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")) {