From e434ccc3f61f5607064945c86f38fd3a357f5376 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 17 Feb 2013 00:23:58 +0000 Subject: [PATCH] - Add support for user variables on things in UDMF maps. If you include an actor's user variable in its UDMF thing definition, that user variable will be set to the desired value for that actor when the map is loaded. SVN r4140 (trunk) --- src/p_setup.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++--- src/p_setup.h | 10 ++++++++++ src/p_udmf.cpp | 19 +++++++++++++++--- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 261d47ea3..dfabd6420 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -142,6 +142,8 @@ int numgamesubsectors; bool hasglnodes; TArray MapThingsConverted; +TMap MapThingsUserDataIndex; // from mapthing idx -> user data idx +TArray MapThingsUserData; int sidecount; sidei_t *sidetemp; @@ -1637,7 +1639,7 @@ void P_LoadNodes (MapData * map) //=========================================================================== CVAR(Bool, dumpspawnedthings, false, 0) -void SpawnMapThing(int index, FMapThing *mt, int position) +AActor *SpawnMapThing(int index, FMapThing *mt, int position) { AActor *spawned = P_SpawnMapThing(mt, position); if (dumpspawnedthings) @@ -1647,6 +1649,42 @@ void SpawnMapThing(int index, FMapThing *mt, int position) spawned? spawned->GetClass()->TypeName.GetChars() : "(none)"); } T_AddSpawnedThing(spawned); + return spawned; +} + +//=========================================================================== +// +// SetMapThingUserData +// +//=========================================================================== + +static void SetMapThingUserData(AActor *actor, unsigned udi) +{ + if (actor == NULL) + { + return; + } + while (MapThingsUserData[udi].Property != NAME_None) + { + FName varname = MapThingsUserData[udi].Property; + int value = MapThingsUserData[udi].Value; + PSymbol *sym = actor->GetClass()->Symbols.FindSymbol(varname, true); + PSymbolVariable *var; + + udi++; + + if (sym == NULL || sym->SymbolType != SYM_Variable || + !(var = static_cast(sym))->bUserVar || + var->ValueType.Type != VAL_Int) + { + DPrintf("%s is not a user variable in class %s\n", varname.GetChars(), + actor->GetClass()->TypeName.GetChars()); + } + else + { // Set the value of the specified user variable. + *(int *)(reinterpret_cast(actor) + var->offset) = value; + } + } } //=========================================================================== @@ -1685,7 +1723,7 @@ void P_LoadThings (MapData * map) for (int i=0 ; i < numthings; i++, mt++) { // [RH] At this point, monsters unique to Doom II were weeded out - // if the IWAD wasn't for Doom II. R_SpawnMapThing() can now + // if the IWAD wasn't for Doom II. P_SpawnMapThing() can now // handle these and more cases better, so we just pass it // everything and let it decide what to do with them. @@ -1780,7 +1818,12 @@ void P_SpawnThings (int position) for (int i=0; i < numthings; i++) { - SpawnMapThing (i, &MapThingsConverted[i], position); + AActor *actor = SpawnMapThing (i, &MapThingsConverted[i], position); + unsigned *udi = MapThingsUserDataIndex.CheckKey((unsigned)i); + if (udi != NULL) + { + SetMapThingUserData(actor, *udi); + } } for(int i=0; i 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; + + #endif diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index e087834b1..6a38708ea 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -627,9 +627,12 @@ public: break; default: - if (!strnicmp("user_", key.GetChars(), 5)) - { - // Custom user key - handle later + 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); } break; } @@ -1603,8 +1606,18 @@ public: if (sc.Compare("thing")) { FMapThing th; + unsigned userdatastart = MapThingsUserData.Size(); ParseThing(&th); MapThingsConverted.Push(th); + if (userdatastart < MapThingsUserData.Size()) + { // 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); + } } else if (sc.Compare("linedef")) {