From b6ddcf0d0623b0d3ed950e8b72f672528d945a53 Mon Sep 17 00:00:00 2001 From: Jason Francis Date: Mon, 19 Mar 2018 10:39:50 -0400 Subject: [PATCH 1/2] Enable string & float user_ properties in UDMF things --- src/p_setup.cpp | 27 ++++++++++++------ src/p_setup.h | 9 ++---- src/p_udmf.cpp | 65 +++++++++++++++++-------------------------- src/scripting/types.h | 1 + 4 files changed, 47 insertions(+), 55 deletions(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 022eba064..5a61b0560 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -167,7 +167,7 @@ bool hasglnodes; TArray MapThingsConverted; TMap MapThingsUserDataIndex; // from mapthing idx -> user data idx -TArray MapThingsUserData; +TArray MapThingsUserData; int sidecount; sidei_t *sidetemp; @@ -1645,23 +1645,34 @@ static void SetMapThingUserData(AActor *actor, unsigned udi) { return; } - while (MapThingsUserData[udi].Property != NAME_None) + while (MapThingsUserData[udi].Key != NAME_None) { - FName varname = MapThingsUserData[udi].Property; - int value = MapThingsUserData[udi].Value; + FName varname = MapThingsUserData[udi].Key; PField *var = dyn_cast(actor->GetClass()->FindSymbol(varname, true)); - udi++; - if (var == NULL || (var->Flags & (VARF_Native|VARF_Private|VARF_Protected|VARF_Static)) || !var->Type->isScalar()) { - DPrintf(DMSG_WARNING, "%s is not a user variable in class %s\n", varname.GetChars(), + DPrintf(DMSG_WARNING, "%s is not a writable user variable in class %s\n", varname.GetChars(), actor->GetClass()->TypeName.GetChars()); } else { // Set the value of the specified user variable. - var->Type->SetValue(reinterpret_cast(actor) + var->Offset, value); + void *addr = reinterpret_cast(actor) + var->Offset; + if (var->Type->isString()) + { + var->Type->InitializeValue(addr, &MapThingsUserData[udi].StringVal); + } + else if (var->Type->isFloat()) + { + var->Type->SetValue(addr, MapThingsUserData[udi].FloatVal); + } + else if (var->Type->isIntCompatible()) + { + var->Type->SetValue(addr, MapThingsUserData[udi].IntVal); + } } + + udi++; } } diff --git a/src/p_setup.h b/src/p_setup.h index cd14f17a2..6b961bfa7 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -30,6 +30,7 @@ #include "resourcefiles/resourcefile.h" #include "doomdata.h" +#include "r_defs.h" struct MapData @@ -180,14 +181,8 @@ struct FMissingCount }; typedef TMap FMissingTextureTracker; -// Record of user data for UDMF maps -struct FMapThingUserData -{ - FName Property; - int Value; -}; extern TMap MapThingsUserDataIndex; // from mapthing idx -> user data idx -extern TArray MapThingsUserData; +extern TArray MapThingsUserData; #endif diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 53d2ece9b..bb9055486 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -476,38 +476,7 @@ public: fogMap = normMap = NULL; } - void AddUserKey(FName key, int kind, int index) - { - FUDMFKeys &keyarray = UDMFKeys[kind][index]; - - for(unsigned i=0; i < keyarray.Size(); i++) - { - if (keyarray[i].Key == key) - { - switch (sc.TokenType) - { - case TK_IntConst: - keyarray[i] = sc.Number; - break; - case TK_FloatConst: - keyarray[i] = sc.Float; - break; - default: - case TK_StringConst: - keyarray[i] = parsedString; - break; - case TK_True: - keyarray[i] = 1; - break; - case TK_False: - keyarray[i] = 0; - break; - } - return; - } - } - FUDMFKey ukey; - ukey.Key = key; + void ReadUserKey(FUDMFKey &ukey) { switch (sc.TokenType) { case TK_IntConst: @@ -527,6 +496,22 @@ public: ukey = 0; break; } + } + void AddUserKey(FName key, int kind, int index) + { + FUDMFKeys &keyarray = UDMFKeys[kind][index]; + + for(unsigned i=0; i < keyarray.Size(); i++) + { + if (keyarray[i].Key == key) + { + ReadUserKey(keyarray[i]); + return; + } + } + FUDMFKey ukey; + ukey.Key = key; + ReadUserKey(ukey); keyarray.Push(ukey); } @@ -809,10 +794,10 @@ public: CHECK_N(Zd | Zdt) if (0 == strnicmp("user_", key.GetChars(), 5)) { // Custom user key - Sets an actor's user variable directly - FMapThingUserData ud; - ud.Property = key; - ud.Value = CheckInt(key); - MapThingsUserData.Push(ud); + FUDMFKey ukey; + ukey.Key = key; + ReadUserKey(ukey); + MapThingsUserData.Push(ukey); } break; } @@ -2111,10 +2096,10 @@ public: { // User data added MapThingsUserDataIndex[MapThingsConverted.Size()-1] = userdatastart; // Mark end of the user data for this map thing - FMapThingUserData ud; - ud.Property = NAME_None; - ud.Value = 0; - MapThingsUserData.Push(ud); + FUDMFKey ukey; + ukey.Key = NAME_None; + ukey = 0; + MapThingsUserData.Push(ukey); } } else if (sc.Compare("linedef")) diff --git a/src/scripting/types.h b/src/scripting/types.h index 5c55db6c1..dbfca2039 100644 --- a/src/scripting/types.h +++ b/src/scripting/types.h @@ -200,6 +200,7 @@ public: bool isStruct() const { return TypeTableType == NAME_Struct; } bool isClass() const { return TypeTableType == NAME_Object; } bool isPrototype() const { return TypeTableType == NAME_Prototype; } + bool isString() const { return TypeTableType == NAME_String; } PContainerType *toContainer() { return isContainer() ? (PContainerType*)this : nullptr; } PPointer *toPointer() { return isPointer() ? (PPointer*)this : nullptr; } From d79ca503a2f1d2f6500b7d21bfefaef9650565cd Mon Sep 17 00:00:00 2001 From: Jason Francis Date: Mon, 19 Mar 2018 12:43:26 -0400 Subject: [PATCH 2/2] Allow setting string user variables in ACS --- src/p_acs.cpp | 17 +++++++++++------ src/p_setup.cpp | 4 ++-- src/scripting/types.h | 1 - 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 1b6c472d8..6f1d1635d 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5065,10 +5065,10 @@ bool GetVarAddrType(AActor *self, FName varname, int index, void *&addr, PType * } addr = baddr; // We don't want Int subclasses like Name or Color to be accessible here. - if (!type->isInt() && !type->isFloat() && type != TypeBool) + if (!type->isInt() && !type->isFloat() && type != TypeBool && type != TypeString) { - // For reading, we also support Name and String types. - if (readonly && (type == TypeName || type == TypeString)) + // For reading, we also support Name types. + if (readonly && (type == TypeName)) { return true; } @@ -5084,13 +5084,18 @@ static void SetUserVariable(AActor *self, FName varname, int index, int value) if (GetVarAddrType(self, varname, index, addr, type, false)) { - if (!type->isFloat()) + if (type == TypeString) { - type->SetValue(addr, value); + FString str = FBehavior::StaticLookupString(value); + type->InitializeValue(addr, &str); + } + else if (type->isFloat()) + { + type->SetValue(addr, ACSToDouble(value)); } else { - type->SetValue(addr, ACSToDouble(value)); + type->SetValue(addr, value); } } } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 5a61b0560..dbc3d31d2 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1658,7 +1658,7 @@ static void SetMapThingUserData(AActor *actor, unsigned udi) else { // Set the value of the specified user variable. void *addr = reinterpret_cast(actor) + var->Offset; - if (var->Type->isString()) + if (var->Type == TypeString) { var->Type->InitializeValue(addr, &MapThingsUserData[udi].StringVal); } @@ -1666,7 +1666,7 @@ static void SetMapThingUserData(AActor *actor, unsigned udi) { var->Type->SetValue(addr, MapThingsUserData[udi].FloatVal); } - else if (var->Type->isIntCompatible()) + else if (var->Type->isInt() || var->Type == TypeBool) { var->Type->SetValue(addr, MapThingsUserData[udi].IntVal); } diff --git a/src/scripting/types.h b/src/scripting/types.h index dbfca2039..5c55db6c1 100644 --- a/src/scripting/types.h +++ b/src/scripting/types.h @@ -200,7 +200,6 @@ public: bool isStruct() const { return TypeTableType == NAME_Struct; } bool isClass() const { return TypeTableType == NAME_Object; } bool isPrototype() const { return TypeTableType == NAME_Prototype; } - bool isString() const { return TypeTableType == NAME_String; } PContainerType *toContainer() { return isContainer() ? (PContainerType*)this : nullptr; } PPointer *toPointer() { return isPointer() ? (PPointer*)this : nullptr; }