sektor2111 wrote: ↑Fri Jan 29, 2021 8:03 am
1337GameDev wrote: ↑Fri Jan 29, 2021 7:20 am
I absolutely hate that simple enums don't just work easily....Irks me something fierce....
Okay, let's see another sample of accessing enum vars of movers:
Code: Select all
class Mover extends Brush
native
nativereplication;
// How the mover should react when it encroaches an actor.
var() enum EMoverEncroachType
{
ME_StopWhenEncroach, // Stop when we hit an actor.
ME_ReturnWhenEncroach, // Return to previous position when we hit an actor.
ME_CrushWhenEncroach, // Crush the poor helpless actor.
ME_IgnoreWhenEncroach, // Ignore encroached actors.
} MoverEncroachType;
And an ancient mutator like UTJMH is addressing movers exactly into these enum types for preventing game-break in broken maps.
Code: Select all
if(M.bTriggerOnceOnly && M.MoverEncroachType == ME_ReturnWhenEncroach)
{
M.MoverEncroachType = ME_IgnoreWhenEncroach;
}
I don't get what exactly is the problem with enum vars.
This essentially is doing what I want...
But i cannot get my example to compile....
Sigh... Here's a direct example I tried to compile.
----------------- ClassA ----------------------
Code: Select all
class TestEnumClassA extends Object;
enum Enum1 {
VALUE1, VALUE2, VALUE3
};
function LogEnum(){
Log("Enum1 1st value:"$Enum1.VALUE1);
}
----------------- ClassB ----------------------
Code: Select all
class TestEnumClassB extends Object;
var byte Enum2;
function LogEnum2(){
Enum2 = TestEnumClassA.Enum1.VALUE2;
Log("Enum2 value:"$Enum2);
}
The results after trying to build with ucc is:
Code: Select all
TestEnumClassB.uc(6) : Error, Bad or missing expression in '='
Critical error while compiling
Refers to the first line in the LogEnum2 function where I set the variable....
Basically, because it's outside of the scope of class A, it can't find the enum...
I tried this then too:
Code: Select all
function LogEnum2(){
Enum2 = class'TestEnumClassA'.Enum1.VALUE2;
Log("Enum2 value:"$Enum2);
}
for the function in class B, and tried compiling, and got this:
Code: Select all
TestEnumClassB.uc(6) : Error, Unrecognized member 'Enum1' in class 'Class'
Critical error while compiling
PS: I couldn't find the code you mentioned in MH.... I tried looking for the latest "utjmh" but couldnt extract the uc files using wotgreal....
PPS: I got the decompile to work. Found the code in "UTJMHBase" on line 256 using grepwin.
Hmm. I don't think this code should even compile. It shouldn't. I try the exact same thing, and my code complains.... Maybe it's because it's setting the enum to one declared inside the same class?
I tested exactly that....
And it worked.... but ONLY for setting an enum variable inside ClassA.... but not ClassB....
Here are the classes I tested:
------------ New ClassA ------------
Code: Select all
class TestEnumClassA extends Object;
var enum Enum1 {
VALUE1, VALUE2, VALUE3
} Enum1Var;
function LogEnum(){
Log("Enum1 1st value:"$Enum1.VALUE1);
}
------------ New ClassB ------------
Code: Select all
class TestEnumClassB extends Object;
var byte Enum2;
function LogEnum2(){
local TestEnumClassA ca;
ca = new class'TestEnumClassA';
ca.Enum1Var = VALUE2;
Enum2 = VALUE2;
Log("Enum2 value:"$Enum2);
}
And the resulting compile error:
Code: Select all
TestEnumClassB.uc(10) : Error, Bad or missing expression in '='
Critical error while compiling
I decided to try and change the ClassB "byte" value... to Enum1 type... and it cannot find the type....
Code: Select all
TestEnumClassB.uc(3) : Error, Unrecognized type 'Enum1'
Critical error while compiling
The ONLY way it compiles... is when I try to set the ClassB.Enum2 type to be ClassA.Enum1.... Then it can set it...
Hmm.... I believe the error was that I was trying to have it implicitly cast types....
THIS situation seems to work:
Code: Select all
class TestEnumClassA extends Object;
enum Enum1 {
VALUE1, VALUE2, VALUE3
};
var Enum1 Enum1Var;
function LogEnum(){
Log("Enum1 1st value:"$Enum1.VALUE1);
}
static function LogPassed(byte e1) {
Log("Enum1 passed:"$e1);
}
Code: Select all
class TestEnumClassB extends Object;
var TestEnumClassA.Enum1 Enum2;
function LogEnum2(){
local TestEnumClassA ca;
local TestEnumClassA.Enum1 e1;
e1 = VALUE3;
ca = new class'TestEnumClassA';
ca.Enum1Var = VALUE2;
Enum2 = VALUE2;
Log("Enum2 value:"$Enum2);
class'TestEnumClassA'.static.LogPassed(e1);
}
So, the rules seem to be this:
If you want to declare an enum type from another class / package - FULL QUALIFY the type. EG:
If you want to pass enums around, and cast to a byte... You must do so implicitly, but ONLY after you store the wanted value in a type of the fully qualified enum. EG:
Code: Select all
local TestEnumClassA.Enum1 e1;
local byte EnumByte;
e1 = VALUE3; // any valid value of that enum
EnumByte = e1;
You CANNOT directly reference an enum value, EXCEPT if youre storing it into a fully qualified (or in-scope) variable of that enum type. You CANNOT pass it directly to a function, unless that function has a FULL QUALIFIED argument for that enum.
Otherwise it acts as if it cannot find the type / the enum is an invalid expression.
Really frustrating... but seems to work now.
Thanks secktor2111... Your example lead me to the proper limitations of enums, and NEEDING to store the value i intend to pass, in a temp variable of the FULLY QUALIFIED enum type. I'm over the moon that I figured this out (with your help). Was so perplexing...
NEVERMIND - I found out WHY it worked.
It's based on COMPILATION order. In later UnrealEngines, there is a
keyword to build a dependency order for compilation....
If TestEnumClassB compiles BEFORE TestEnumClassA, then it fails in ALL cases, even if I full qualify the enum. Dammit. This is why they try to use BYTE.....
The only reason why they can get away with that in the MH mutator... is because MOVER is already in the compilation context as it's a base class in the game files, already built.
Dammit. I cannot do what I want with UnrealEngine1.... Unless I force a compilation order, via relying on names or something with ucc.
I'll have to find a way to get an enum value via SetPropertyText, or just pass an integer blindly, and rely on the caller to lookup the index of that value.... as we also cannot declare values for enums.... (eg: if i add a new enum value to the beginning all enum values are now off by 1).
Sigh... I'll have to settle for an integer if i also care about performance as name/string lookups are expensive in any language (even if they use a hashtable and string hashing).
Sigh....