From 9d80323a3ad7c5422c190ad6720d5a214d64b390 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 25 May 2023 14:40:55 -0400 Subject: [PATCH] Read-only mapthing_t Map things are writeable in Lua, which I am pretty certain is a mistake because mapthings are not sent over the network at all. I considered making them net-synced (it would be relatively easy), but it also aligns with another, more "philosophical" issue: Doom generally copies over properties from mapthing_t into mobj_t, and then only refers to it again when needing to respawn an object -- mapthing_t is not really intended to be referred to very often at runtime. At best it's slightly annoying since some objects rely on a spawnpoint for behavior changes, at worst it may make ACS more confusing in the future since Thing and Mobj tags are mixed together or less useful since they wouldn't be able to modify behaviors of objects that are based on args. So I decided to solve these two issues at the same time; just treat mapthing_t as something to copy values from, like OG Doom does it. This basically just means that special and args are also part of the mobj now instead of the mapthing, which should fill any desire to edit this stuff from Lua, and reduces the number of instances where objects need to check for their spawnpoint to function properly. --- src/acs/environment.cpp | 2 +- src/deh_tables.c | 5 - src/doomdata.h | 2 +- src/doomstat.h | 4 - src/g_game.c | 7 -- src/lua_mobjlib.c | 124 ++++++++++-------------- src/lua_script.c | 1 - src/objects/loops.c | 6 +- src/p_enemy.c | 137 ++++++++++++-------------- src/p_inter.c | 2 +- src/p_local.h | 2 + src/p_map.c | 2 +- src/p_mobj.c | 76 ++++++++++----- src/p_mobj.h | 4 + src/p_polyobj.c | 4 +- src/p_saveg.c | 208 +++++++++++++++++++++++++++++++--------- src/p_setup.c | 67 ++++--------- src/p_slopes.c | 6 +- src/p_spec.c | 16 +--- src/slope_anchors.c | 2 +- src/taglist.c | 49 ++++++---- src/taglist.h | 1 - 22 files changed, 397 insertions(+), 330 deletions(-) diff --git a/src/acs/environment.cpp b/src/acs/environment.cpp index e90c34cb6..49770dd83 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -271,7 +271,7 @@ bool Environment::checkTag(ACSVM::Word type, ACSVM::Word tag) case ACS_TAGTYPE_CAMERA: { const mobj_t *camera = P_FindObjectTypeFromTag(MT_ALTVIEWMAN, tag); - if (camera == nullptr || camera->spawnpoint == nullptr) + if (camera == nullptr) { return true; } diff --git a/src/deh_tables.c b/src/deh_tables.c index 63458676b..3de0cd12d 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6480,11 +6480,6 @@ struct int_const_s const INT_CONST[] = { {"PA_DRIFT",PA_DRIFT}, {"PA_HURT",PA_HURT}, - // Got Flags, for player->gotflag! - // Used to be MF_ for some stupid reason, now they're GF_ to stop them looking like mobjflags - {"GF_REDFLAG",GF_REDFLAG}, - {"GF_BLUEFLAG",GF_BLUEFLAG}, - // Customisable sounds for Skins, from sounds.h {"SKSSPIN",SKSSPIN}, {"SKSPUTPUT",SKSPUTPUT}, diff --git a/src/doomdata.h b/src/doomdata.h index f5e617a0f..cfed6fbcd 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -261,7 +261,7 @@ struct mapthing_t UINT16 options; INT16 z; UINT8 extrainfo; - taglist_t tags; + mtag_t tid; fixed_t scale; INT16 special; INT32 args[NUMMAPTHINGARGS]; diff --git a/src/doomstat.h b/src/doomstat.h index 77317fd0a..23ae4abfa 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -320,10 +320,6 @@ extern UINT8 skipstats; // Fun extra stuff extern INT16 lastmap; // Last level you were at (returning from special stages). -extern mobj_t *redflag, *blueflag; // Pointers to physical flags -extern mapthing_t *rflagpoint, *bflagpoint; // Pointers to the flag spawn locations -#define GF_REDFLAG 1 -#define GF_BLUEFLAG 2 // A single point in space. struct mappoint_t diff --git a/src/g_game.c b/src/g_game.c index 37399c561..6c9008e6d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -186,13 +186,6 @@ textprompt_t *textprompts[MAX_PROMPTS]; INT16 nextmapoverride; UINT8 skipstats; -// Pointers to each CTF flag -mobj_t *redflag; -mobj_t *blueflag; -// Pointers to CTF spawn location -mapthing_t *rflagpoint; -mapthing_t *bflagpoint; - quake_t *g_quakes = NULL; // Map Header Information diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 835e2bb4d..032dab364 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -101,7 +101,11 @@ enum mobj_e { mobj_sprzoff, mobj_hitlag, mobj_waterskip, - mobj_dispoffset + mobj_dispoffset, + mobj_tid, + mobj_special, + mobj_args, + mobj_stringargs }; static const char *const mobj_opt[] = { @@ -184,6 +188,10 @@ static const char *const mobj_opt[] = { "hitlag", "waterskip", "dispoffset", + "tid", + "special", + "args", + "stringargs", NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) @@ -468,6 +476,18 @@ static int mobj_get(lua_State *L) case mobj_dispoffset: lua_pushinteger(L, mo->dispoffset); break; + case mobj_tid: + lua_pushinteger(L, mo->tid); + break; + case mobj_special: + lua_pushinteger(L, mo->special); + break; + case mobj_args: + LUA_PushUserdata(L, mo->args, META_THINGARGS); + break; + case mobj_stringargs: + LUA_PushUserdata(L, mo->stringargs, META_THINGSTRINGARGS); + break; default: // extra custom variables in Lua memory lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -846,6 +866,16 @@ static int mobj_set(lua_State *L) case mobj_dispoffset: mo->dispoffset = luaL_checkinteger(L, 3); break; + case mobj_tid: + P_SetThingTID(mo, luaL_checkinteger(L, 3)); + break; + case mobj_special: + mo->special = luaL_checkinteger(L, 3); + break; + case mobj_args: + return NOSET; + case mobj_stringargs: + return NOSET; default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -949,13 +979,8 @@ static int mapthing_get(lua_State *L) number = mt->z; else if(fastcmp(field,"extrainfo")) number = mt->extrainfo; - else if(fastcmp(field,"tag")) - number = Tag_FGet(&mt->tags); - else if(fastcmp(field,"taglist")) - { - LUA_PushUserdata(L, &mt->tags, META_TAGLIST); - return 1; - } + else if(fastcmp(field,"tid")) + number = mt->tid; else if(fastcmp(field,"special")) number = mt->special; else if(fastcmp(field,"args")) @@ -980,62 +1005,6 @@ static int mapthing_get(lua_State *L) return 1; } -static int mapthing_set(lua_State *L) -{ - mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)); - const char *field = luaL_checkstring(L, 2); - - if (!mt) - return luaL_error(L, "accessed mapthing_t doesn't exist anymore."); - - if (hud_running) - return luaL_error(L, "Do not alter mapthing_t in HUD rendering code!"); - if (hook_cmd_running) - return luaL_error(L, "Do not alter mapthing_t in CMD building code!"); - - if(fastcmp(field,"x")) - mt->x = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"y")) - mt->y = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"angle")) - mt->angle = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"pitch")) - mt->pitch = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"roll")) - mt->roll = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"type")) - mt->type = (UINT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"options")) - mt->options = (UINT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"scale")) - mt->scale = luaL_checkfixed(L, 3); - else if(fastcmp(field,"z")) - mt->z = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"extrainfo")) - { - INT32 extrainfo = luaL_checkinteger(L, 3); - if (extrainfo & ~15) - return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15); - mt->extrainfo = (UINT8)extrainfo; - } - else if (fastcmp(field,"tag")) - Tag_FSet(&mt->tags, (INT16)luaL_checkinteger(L, 3)); - else if (fastcmp(field,"taglist")) - return LUA_ErrSetDirectly(L, "mapthing_t", "taglist"); - else if (fastcmp(field,"special")) - { - // Can't change mapthing args (yet?), so let's not allow changing special either. - //mt->special = (INT16)luaL_checkinteger(L, 3); - return LUA_ErrSetDirectly(L, "mapthing_t", "special"); - } - else if(fastcmp(field,"mobj")) - mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); - else - return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field); - - return 0; -} - static int mapthing_num(lua_State *L) { mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)); @@ -1065,6 +1034,7 @@ static int lib_iterateMapthings(lua_State *L) static int lib_getMapthing(lua_State *L) { + const char *field; INLEVEL if (lua_isnumber(L, 2)) { @@ -1074,6 +1044,13 @@ static int lib_getMapthing(lua_State *L) LUA_PushUserdata(L, &mapthings[i], META_MAPTHING); return 1; } + + field = luaL_checkstring(L, 2); + if (fastcmp(field,"iterate")) + { + lua_pushcfunction(L, lib_iterateMapthings); + return 1; + } return 0; } @@ -1113,20 +1090,19 @@ int LUA_MobjLib(lua_State *L) lua_pushcfunction(L, mapthing_get); lua_setfield(L, -2, "__index"); - lua_pushcfunction(L, mapthing_set); - lua_setfield(L, -2, "__newindex"); - lua_pushcfunction(L, mapthing_num); lua_setfield(L, -2, "__len"); lua_pop(L,1); - LUA_PushTaggableObjectArray(L, "mapthings", - lib_iterateMapthings, - lib_getMapthing, - lib_nummapthings, - tags_mapthings, - &nummapthings, &mapthings, - sizeof (mapthing_t), META_MAPTHING); + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getMapthing); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_nummapthings); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "mapthings"); return 0; } diff --git a/src/lua_script.c b/src/lua_script.c index 3a12c177b..4da776e55 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -902,7 +902,6 @@ void LUA_InvalidateMapthings(void) for (i = 0; i < nummapthings; i++) { LUA_InvalidateUserdata(&mapthings[i]); - LUA_InvalidateUserdata(&mapthings[i].tags); LUA_InvalidateUserdata(mapthings[i].args); LUA_InvalidateUserdata(mapthings[i].stringargs); } diff --git a/src/objects/loops.c b/src/objects/loops.c index dd9ea7c3b..fab1033e1 100644 --- a/src/objects/loops.c +++ b/src/objects/loops.c @@ -178,10 +178,8 @@ Obj_InitLoopEndpoint void Obj_InitLoopCenter (mobj_t *center) { - const mapthing_t *mt = center->spawnpoint; - - center_max_revolution(center) = mt->args[1] * FRACUNIT / 360; - center_set_flip(center, mt->args[0]); + center_max_revolution(center) = center->args[1] * FRACUNIT / 360; + center_set_flip(center, center->args[0]); } void diff --git a/src/p_enemy.c b/src/p_enemy.c index 4c6ee57cf..17aa6ea71 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3435,8 +3435,7 @@ static void P_DoBossVictory(mobj_t *mo) } // victory! - if (mo->spawnpoint) - P_LinedefExecute(mo->spawnpoint->args[3], mo, NULL); + P_LinedefExecute(mo->args[3], mo, NULL); if (stoppedclock && modeattacking) // if you're just time attacking, skip making the capsule appear since you don't need to step on it anyways. return; @@ -3460,7 +3459,7 @@ static void P_DoBossVictory(mobj_t *mo) static void P_DoBossDefaultDeath(mobj_t *mo) { - INT32 bossid = (mo->spawnpoint ? mo->spawnpoint->args[0] : 0); + INT32 bossid = mo->args[0]; // Stop exploding and prepare to run. P_SetMobjState(mo, mo->info->xdeathstate); @@ -3505,8 +3504,7 @@ void A_BossDeath(mobj_t *mo) if (LUA_CallAction(A_BOSSDEATH, mo)) return; - if (mo->spawnpoint) - P_LinedefExecute(mo->spawnpoint->args[2], mo, NULL); + P_LinedefExecute(mo->args[2], mo, NULL); mo->health = 0; // Boss is dead (but not necessarily fleeing...) @@ -4076,8 +4074,8 @@ void A_FishJump(mobj_t *actor) jumpval = locvar1; else { - if (actor->spawnpoint && actor->spawnpoint->args[0]) - jumpval = actor->spawnpoint->args[0]; + if (actor->args[0]) + jumpval = actor->args[0]; else jumpval = 44; } @@ -5086,29 +5084,26 @@ void A_RockSpawn(mobj_t *actor) if (LUA_CallAction(A_ROCKSPAWN, actor)) return; - if (!actor->spawnpoint) - return; - - type = actor->spawnpoint->stringargs[0] ? get_number(actor->spawnpoint->stringargs[0]) : MT_ROCKCRUMBLE1; + type = actor->stringargs[0] ? get_number(actor->stringargs[0]) : MT_ROCKCRUMBLE1; if (type < MT_NULL || type >= NUMMOBJTYPES) { - CONS_Debug(DBG_GAMELOGIC, "A_RockSpawn: Invalid mobj type %s!\n", actor->spawnpoint->stringargs[0]); + CONS_Debug(DBG_GAMELOGIC, "A_RockSpawn: Invalid mobj type %s!\n", actor->stringargs[0]); return; } - dist = max(actor->spawnpoint->args[0] << (FRACBITS - 4), 1); - if (actor->spawnpoint->args[2]) + dist = max(actor->args[0] << (FRACBITS - 4), 1); + if (actor->args[2]) dist += P_RandomByte(PR_UNDEFINED) * (FRACUNIT/32); // random oomph mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FALLINGROCK); P_SetMobjState(mo, mobjinfo[type].spawnstate); - mo->angle = FixedAngle(actor->spawnpoint->angle << FRACBITS); + mo->angle = actor->angle; P_InstaThrust(mo, mo->angle, dist); mo->momz = dist; - var1 = actor->spawnpoint->args[1]; + var1 = actor->args[1]; A_SetTics(actor); } @@ -5770,8 +5765,7 @@ void A_Boss1Chase(mobj_t *actor) } else { - if (actor->spawnpoint) - P_LinedefExecute(actor->spawnpoint->args[4], actor, NULL); + P_LinedefExecute(actor->args[4], actor, NULL); P_SetMobjState(actor, actor->info->raisestate); } @@ -6468,7 +6462,7 @@ void A_GuardChase(mobj_t *actor) false, NULL) && speed > 0) // can't be the same check as previous so that P_TryMove gets to happen. { - INT32 direction = actor->spawnpoint ? actor->spawnpoint->args[0] : TMGD_BACK; + INT32 direction = actor->args[0]; switch (direction) { @@ -6903,16 +6897,13 @@ void A_LinedefExecuteFromArg(mobj_t *actor) if (LUA_CallAction(A_LINEDEFEXECUTEFROMARG, actor)) return; - if (!actor->spawnpoint) - return; - if (locvar1 < 0 || locvar1 > NUMMAPTHINGARGS) { CONS_Debug(DBG_GAMELOGIC, "A_LinedefExecuteFromArg: Invalid mapthing arg %d\n", locvar1); return; } - tagnum = actor->spawnpoint->args[locvar1]; + tagnum = actor->args[locvar1]; CONS_Debug(DBG_GAMELOGIC, "A_LinedefExecuteFromArg: Running mobjtype %d's sector with tag %d\n", actor->type, tagnum); @@ -7909,15 +7900,32 @@ void A_StateRangeByParameter(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - UINT8 parameter = (actor->spawnpoint ? actor->spawnpoint->extrainfo : 0); + UINT8 parameter = 0; + INT32 range = 0; if (LUA_CallAction(A_STATERANGEBYPARAMETER, actor)) + { return; + } - if (locvar2 - locvar1 < 0) - return; // invalid range + if (udmf) + { + parameter = actor->args[0]; + } + else if (actor->spawnpoint != NULL) + { + // binary format backwards compatibility + parameter = actor->spawnpoint->extrainfo; + } - P_SetMobjState(actor, locvar1 + (parameter % (1 + locvar2 - locvar1))); + range = locvar2 - locvar1; + if (range < 0) + { + CONS_Debug(DBG_GAMELOGIC, "A_StateRangeByParameter: invalid range %d (var1: %d, var2: %d)\n", range, locvar1, locvar2); + return; + } + + P_SetMobjState(actor, locvar1 + (parameter % (range + 1))); } // Function: A_DualAction @@ -10317,17 +10325,13 @@ void P_InternalFlickySetColor(mobj_t *actor, UINT8 color) // // Description: Place flickies in-level. // -// var1: -// Lower 16 bits = if 0, spawns random flicky based on level header. Else, spawns the designated thing type. -// Bits 17-20 = Flicky color, up to 15. Applies to fish. -// Bit 21 = Flag TMFF_AIMLESS (see below) -// Bit 22 = Flag TMFF_STATIONARY (see below) -// Bit 23 = Flag TMFF_HOP (see below) -// -// If actor is placed from a spawnpoint (map Thing), the Thing's properties take precedence. -// +// var1 = if 0, spawns random flicky based on level header. Else, spawns the designated thing type. // var2 = maximum default distance away from spawn the flickies are allowed to travel. If args[0] != 0, then that's the radius. // +// args[0] = Flicky radius +// args[1] = Behavior flags (see the list below) +// args[2] = Flicky color, up to 15. Applies to fish. +// // If TMFF_AIMLESS (MF_SLIDEME): is flagged, Flickies move aimlessly. Else, orbit around the target. // If TMFF_STATIONARY (MF_GRENADEBOUNCE): Flickies stand in-place without gravity (unless they hop, then gravity is applied.) // If TMFF_HOP (MF_NOCLIPTHING): is flagged, Flickies hop. @@ -10336,51 +10340,31 @@ void A_FlickyCenter(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - UINT16 flickytype = (locvar1 & 0xFFFF); - UINT8 flickycolor = ((locvar1 >> 16) & 0xFF); - UINT8 flickyflags = ((locvar1 >> 20) & 0xF); + fixed_t homeRadius = INT32_MAX; if (LUA_CallAction(A_FLICKYCENTER, actor)) return; + homeRadius = locvar2 ? FixedMul(abs(locvar2), actor->scale) : 384*actor->scale; + if (!actor->tracer) { mobj_t *flicky = P_InternalFlickySpawn(actor, locvar1, 1, false, 0); P_SetTarget(&flicky->target, actor); P_SetTarget(&actor->tracer, flicky); - if (actor->spawnpoint) - { - actor->flags &= ~(MF_SLIDEME|MF_GRENADEBOUNCE|MF_NOCLIPTHING); - if (actor->spawnpoint->args[1] & TMFF_AIMLESS) - actor->flags |= MF_SLIDEME; - if (actor->spawnpoint->args[1] & TMFF_STATIONARY) - actor->flags |= MF_GRENADEBOUNCE; - if (actor->spawnpoint->args[1] & TMFF_HOP) - actor->flags |= MF_NOCLIPTHING; - actor->extravalue1 = actor->spawnpoint->args[0] ? abs(actor->spawnpoint->args[0])*FRACUNIT - : locvar2 ? abs(locvar2) : 384*FRACUNIT; - actor->extravalue2 = actor->spawnpoint->args[2]; - actor->friction = actor->spawnpoint->x*FRACUNIT; - actor->movefactor = actor->spawnpoint->y*FRACUNIT; - actor->watertop = actor->spawnpoint->z*FRACUNIT; - } - else - { - actor->flags &= ~(MF_SLIDEME|MF_GRENADEBOUNCE|MF_NOCLIPTHING); - if (flickyflags & TMFF_AIMLESS) - actor->flags |= MF_SLIDEME; - if (flickyflags & TMFF_STATIONARY) - actor->flags |= MF_GRENADEBOUNCE; - if (flickyflags & TMFF_HOP) - actor->flags |= MF_NOCLIPTHING; - actor->extravalue1 = abs(locvar2); - actor->extravalue2 = flickycolor; - actor->friction = actor->x; - actor->movefactor = actor->y; - actor->watertop = actor->z; - locvar1 = flickytype; - } + actor->flags &= ~(MF_SLIDEME|MF_GRENADEBOUNCE|MF_NOCLIPTHING); + if (actor->args[1] & TMFF_AIMLESS) + actor->flags |= MF_SLIDEME; + if (actor->args[1] & TMFF_STATIONARY) + actor->flags |= MF_GRENADEBOUNCE; + if (actor->args[1] & TMFF_HOP) + actor->flags |= MF_NOCLIPTHING; + actor->extravalue1 = actor->args[0] ? abs(actor->args[0])*actor->scale : homeRadius; + actor->extravalue2 = actor->args[2]; + actor->friction = actor->x; + actor->movefactor = actor->y; + actor->watertop = actor->z; if (actor->flags & MF_GRENADEBOUNCE) // in-place actor->tracer->fuse = 0; @@ -10408,7 +10392,7 @@ void A_FlickyCenter(mobj_t *actor) // Impose default home radius if flicky orbits around player if (!actor->extravalue1) - actor->extravalue1 = locvar2 ? abs(locvar2) : 384 * FRACUNIT; + actor->extravalue1 = homeRadius; P_LookForPlayers(actor, true, false, actor->extravalue1); @@ -11298,7 +11282,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) INT32 locvar1 = var1; boolean avoidcenter; INT32 i; - INT32 bossid = (actor->spawnpoint ? actor->spawnpoint->args[0] : 0); + INT32 bossid = actor->args[0]; if (LUA_CallAction(A_BOSS5FINDWAYPOINT, actor)) return; @@ -12681,8 +12665,7 @@ void A_SpawnPterabytes(mobj_t *actor) if (LUA_CallAction(A_SPAWNPTERABYTES, actor)) return; - if (actor->spawnpoint) - amount = min(1, actor->spawnpoint->args[0]); + amount = min(1, actor->args[0]); interval = FixedAngle(FRACUNIT*360/amount); @@ -13370,11 +13353,11 @@ void A_MayonakaArrow(mobj_t *actor) if (LUA_CallAction(A_MAYONAKAARROW, (actor))) return; - iswarning = (actor->spawnpoint->args[0] == TMMA_WARN); // is our object a warning sign? + iswarning = (actor->args[0] == TMMA_WARN); // is our object a warning sign? // "animtimer" is replaced by "extravalue1" here. actor->extravalue1 = ((actor->extravalue1) ? (actor->extravalue1+1) : (P_RandomRange(PR_DECORATION, 0, (iswarning) ? (TICRATE/2) : TICRATE*3))); - flip = ((actor->spawnpoint->args[0] == TMMA_FLIP) ? (3) : (0)); // flip adds 3 frames, which is the flipped version of the sign. + flip = ((actor->args[0] == TMMA_FLIP) ? (3) : (0)); // flip adds 3 frames, which is the flipped version of the sign. // special warning behavior: if (iswarning) flip = 6; diff --git a/src/p_inter.c b/src/p_inter.c index 620076dd3..9737a317b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -547,7 +547,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_STARPOST: - P_TouchStarPost(special, player, special->spawnpoint && special->spawnpoint->args[1]); + P_TouchStarPost(special, player, special->args[1]); return; case MT_BIGTUMBLEWEED: diff --git a/src/p_local.h b/src/p_local.h index 738faffd3..72d00f614 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -608,6 +608,8 @@ void P_SetThingTID(mobj_t *mo, mtag_t tid); void P_RemoveThingTID(mobj_t *mo); mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator); +void P_DeleteMobjStringArgs(mobj_t *mobj); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/p_map.c b/src/p_map.c index 5b539ad28..6d2f9a30c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -528,7 +528,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) if (object->eflags & MFE_SPRUNG) break; - if (spring->spawnpoint && spring->spawnpoint->args[1]) + if (spring->args[1]) { if (object->player) { diff --git a/src/p_mobj.c b/src/p_mobj.c index fbe4d90c2..166bb7ef7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4420,7 +4420,7 @@ static void P_RefreshItemCapsuleParts(mobj_t *mobj) color = SKINCOLOR_GOLD; newRenderFlags |= RF_SEMIBRIGHT; } - else if (mobj->spawnpoint && (mobj->spawnpoint->args[2] & TMICF_INVERTTIMEATTACK)) + else if (mobj->args[2] & TMICF_INVERTTIMEATTACK) color = SKINCOLOR_SAPPHIRE; else if (itemType == KITEM_SPB) color = SKINCOLOR_JET; @@ -6511,7 +6511,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (!(leveltime % 10)) { mobj_t *smok = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PETSMOKE); - if (mobj->spawnpoint && mobj->spawnpoint->args[0]) + if (mobj->args[0]) P_SetMobjStateNF(smok, smok->info->painstate); // same function, diff sprite } break; @@ -9638,7 +9638,7 @@ static boolean P_FuseThink(mobj_t *mobj) case MT_SPIKE: case MT_WALLSPIKE: P_SetMobjState(mobj, mobj->state->nextstate); - mobj->fuse = mobj->spawnpoint ? mobj->spawnpoint->args[0] : mobj->info->speed; + mobj->fuse = mobj->args[0]; break; case MT_LAVAFALL: if (mobj->state - states == S_LAVAFALL_DORMANT) @@ -9764,7 +9764,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags & MF_NOTHINK) return; - if ((mobj->flags & MF_BOSS) && mobj->spawnpoint && (bossdisabled & (1<spawnpoint->args[0]))) + if ((mobj->flags & MF_BOSS) && (bossdisabled & (1 << mobj->args[0]))) return; mobj->flags2 &= ~(MF2_ALREADYHIT); @@ -11123,6 +11123,7 @@ void P_RemoveMobj(mobj_t *mobj) P_SetTarget(&mobj->itnext, NULL); P_RemoveThingTID(mobj); + P_DeleteMobjStringArgs(mobj); R_RemoveMobjInterpolator(mobj); // free block @@ -11209,6 +11210,8 @@ void P_RemoveSavegameMobj(mobj_t *mobj) // stop any playing sound S_StopSound(mobj); + + P_DeleteMobjStringArgs(mobj); R_RemoveMobjInterpolator(mobj); // free block @@ -12175,7 +12178,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) INT32 j; emblem_t* emblem = M_GetLevelEmblems(gamemap); skincolornum_t emcolor; - INT16 tagnum = Tag_FGet(&mthing->tags); + INT16 tagnum = mthing->tid; while (emblem) { @@ -12653,7 +12656,7 @@ static mobj_t *P_MakeSoftwareCorona(mobj_t *mo, INT32 height) void P_InitSkyboxPoint(mobj_t *mobj, mapthing_t *mthing) { - mtag_t tag = Tag_FGet(&mthing->tags); + mtag_t tag = mthing->tid; if (tag < 0 || tag > 15) { CONS_Debug(DBG_GAMELOGIC, "P_InitSkyboxPoint: Skybox ID %d of mapthing %s is not between 0 and 15!\n", tag, sizeu1((size_t)(mthing - mapthings))); @@ -12807,10 +12810,6 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean if (!P_SetupParticleGen(mthing, mobj)) return false; break; - case MT_ROCKSPAWNER: - mobj->threshold = mthing->angle; - mobj->movecount = mthing->extrainfo; - break; case MT_TUBEWAYPOINT: { UINT8 sequence = mthing->args[0]; @@ -12969,20 +12968,12 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj->flags2 |= MF2_AMBUSH; } break; - case MT_REDFLAG: - redflag = mobj; - rflagpoint = mobj->spawnpoint; - break; - case MT_BLUEFLAG: - blueflag = mobj; - bflagpoint = mobj->spawnpoint; - break; // SRB2Kart case MT_WAYPOINT: { const fixed_t mobjscale = mapheaderinfo[gamemap-1]->default_waypoint_radius; - mtag_t tag = Tag_FGet(&mthing->tags); + mtag_t tag = mthing->tid; if (mthing->args[1] > 0) mobj->radius = (mthing->args[1]) * FRACUNIT; @@ -13145,8 +13136,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean { fixed_t top = mobj->z; UINT8 i; - UINT8 locnumsegs = (mthing->extrainfo)+2; - UINT8 numleaves = max(3, (abs(mthing->angle+1) % 6) + 3); + UINT8 locnumsegs = abs(mthing->args[0])+2; + UINT8 numleaves = max(3, (abs(mthing->args[1])+1 % 6) + 3); mobj_t *coconut; // Spawn tree segments @@ -13360,6 +13351,7 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, { mobj_t *mobj = NULL; boolean doangle = true; + size_t arg = SIZE_MAX; mobj = P_SpawnMobj(x, y, z, i); mobj->spawnpoint = mthing; @@ -13393,7 +13385,34 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, mobj->pitch = FixedAngle(mthing->pitch << FRACBITS); mobj->roll = FixedAngle(mthing->roll << FRACBITS); - P_SetThingTID(mobj, Tag_FGet(&mthing->tags)); + P_SetThingTID(mobj, mthing->tid); + + mobj->special = mthing->special; + + for (arg = 0; arg < NUMMAPTHINGARGS; arg++) + { + mobj->args[arg] = mthing->args[arg]; + } + + for (arg = 0; arg < NUMMAPTHINGSTRINGARGS; arg++) + { + size_t len = 0; + + if (mthing->stringargs[arg]) + { + len = strlen(mthing->stringargs[arg]); + } + + if (len == 0) + { + Z_Free(mobj->stringargs[arg]); + mobj->stringargs[arg] = NULL; + continue; + } + + mobj->stringargs[arg] = Z_Realloc(mobj->stringargs[arg], len + 1, PU_LEVEL, NULL); + M_Memcpy(mobj->stringargs[arg], mthing->stringargs[arg], len + 1); + } mthing->mobj = mobj; @@ -13593,7 +13612,7 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numi { const fixed_t length = (numitems - 1) * horizontalspacing / 2; - mobj_t *loopcenter = Obj_FindLoopCenter(Tag_FGet(&mthing->tags)); + mobj_t *loopcenter = Obj_FindLoopCenter(mthing->tid); // Spawn the anchor at the middle point of the line loopanchor = P_SpawnMobjFromMapThing(&dummything, @@ -14425,3 +14444,14 @@ mobj_t *P_FindMobjFromTID(mtag_t tid, mobj_t *i, mobj_t *activator) return i; } + +void P_DeleteMobjStringArgs(mobj_t *mobj) +{ + size_t i = SIZE_MAX; + + for (i = 0; i < NUMMAPTHINGSTRINGARGS; i++) + { + Z_Free(mobj->stringargs[i]); + mobj->stringargs[i] = NULL; + } +} diff --git a/src/p_mobj.h b/src/p_mobj.h index b6eddadea..4cd0b0d9e 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -425,6 +425,10 @@ struct mobj_t INT32 dispoffset; + INT16 special; + INT32 args[NUMMAPTHINGARGS]; + char *stringargs[NUMMAPTHINGSTRINGARGS]; + // WARNING: New fields must be added separately to savegame and Lua. }; diff --git a/src/p_polyobj.c b/src/p_polyobj.c index dc2982236..c6cbe9ee3 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -558,7 +558,7 @@ static void Polyobj_moveToSpawnSpot(mapthing_t *anchor) polyobj_t *po; vertex_t dist, sspot; size_t i; - mtag_t tag = Tag_FGet(&anchor->tags); + mtag_t tag = anchor->tid; if (!(po = Polyobj_GetForNum(tag))) { @@ -1351,7 +1351,7 @@ void Polyobj_InitLevel(void) { qitem = (mobjqitem_t *)M_QueueIterator(&spawnqueue); - Polyobj_spawnPolyObj(i, qitem->mo, Tag_FGet(&qitem->mo->spawnpoint->tags)); + Polyobj_spawnPolyObj(i, qitem->mo, qitem->mo->spawnpoint->tid); } // move polyobjects to spawn points diff --git a/src/p_saveg.c b/src/p_saveg.c index 16073ac06..90664d5cb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2135,6 +2135,31 @@ static void P_NetUnArchiveWorld(savebuffer_t *save) // Thinkers // +static boolean P_ThingArgsEqual(const mobj_t *mobj, const mapthing_t *mapthing) +{ + UINT8 i; + for (i = 0; i < NUMMAPTHINGARGS; i++) + if (mobj->args[i] != mapthing->args[i]) + return false; + + return true; +} + +static boolean P_ThingStringArgsEqual(const mobj_t *mobj, const mapthing_t *mapthing) +{ + UINT8 i; + for (i = 0; i < NUMMAPTHINGSTRINGARGS; i++) + { + if (!mobj->stringargs[i]) + return !mapthing->stringargs[i]; + + if (strcmp(mobj->stringargs[i], mapthing->stringargs[i])) + return false; + } + + return true; +} + typedef enum { MD_SPAWNPOINT = 1, @@ -2166,8 +2191,8 @@ typedef enum MD_WATERBOTTOM = 1<<26, MD_SCALE = 1<<27, MD_DSCALE = 1<<28, - MD_BLUEFLAG = 1<<29, - MD_REDFLAG = 1<<30, + MD_ARGS = 1<<29, + MD_STRINGARGS = 1<<30, MD_MORE = (INT32)(1U<<31) } mobj_diff_t; @@ -2191,10 +2216,10 @@ typedef enum MD2_SHADOWSCALE = 1<<15, MD2_RENDERFLAGS = 1<<16, MD2_TID = 1<<17, - MD2_SPRITEXSCALE = 1<<18, - MD2_SPRITEYSCALE = 1<<19, - MD2_SPRITEXOFFSET = 1<<20, - MD2_SPRITEYOFFSET = 1<<21, + MD2_SPRITESCALE = 1<<18, + MD2_SPRITEOFFSET = 1<<19, + MD2_WORLDOFFSET = 1<<20, + MD2_SPECIAL = 1<<21, MD2_FLOORSPRITESLOPE = 1<<22, MD2_DISPOFFSET = 1<<23, MD2_HITLAG = 1<<24, @@ -2287,6 +2312,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 const mobj_t *mobj = (const mobj_t *)th; UINT32 diff; UINT32 diff2; + size_t j; // Ignore stationary hoops - these will be respawned from mapthings. if (mobj->type == MT_HOOP) @@ -2318,9 +2344,44 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 if (mobj->info->doomednum != mobj->spawnpoint->type) diff |= MD_TYPE; + + if (!P_ThingArgsEqual(mobj, mobj->spawnpoint)) + diff |= MD_ARGS; + + if (!P_ThingStringArgsEqual(mobj, mobj->spawnpoint)) + diff |= MD_STRINGARGS; + + if (mobj->special != mobj->spawnpoint->type) + diff2 |= MD2_SPECIAL; } else - diff = MD_POS | MD_TYPE; // not a map spawned thing so make it from scratch + { + // not a map spawned thing, so make it from scratch + diff = MD_POS | MD_TYPE; + + for (j = 0; j < NUMMAPTHINGARGS; j++) + { + if (mobj->args[j] != 0) + { + diff |= MD_ARGS; + break; + } + } + + for (j = 0; j < NUMMAPTHINGSTRINGARGS; j++) + { + if (mobj->stringargs[j] != NULL) + { + diff |= MD_STRINGARGS; + break; + } + } + + if (mobj->special != 0) + { + diff2 |= MD2_SPECIAL; + } + } diff2 = 0; @@ -2355,7 +2416,6 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 diff |= MD_EFLAGS; if (mobj->player) diff |= MD_PLAYER; - if (mobj->movedir) diff |= MD_MOVEDIR; if (mobj->movecount) @@ -2384,12 +2444,6 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 diff |= MD_DSCALE; if (mobj->scalespeed != mapobjectscale/12) diff2 |= MD2_SCALESPEED; - - if (mobj == redflag) - diff |= MD_REDFLAG; - if (mobj == blueflag) - diff |= MD_BLUEFLAG; - if (mobj->cusval) diff2 |= MD2_CUSVAL; if (mobj->cvmem) @@ -2424,14 +2478,12 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 diff2 |= MD2_RENDERFLAGS; if (mobj->tid != 0) diff2 |= MD2_TID; - if (mobj->spritexscale != FRACUNIT) - diff2 |= MD2_SPRITEXSCALE; - if (mobj->spriteyscale != FRACUNIT) - diff2 |= MD2_SPRITEYSCALE; - if (mobj->spritexoffset) - diff2 |= MD2_SPRITEXOFFSET; - if (mobj->spriteyoffset) - diff2 |= MD2_SPRITEYOFFSET; + if (mobj->spritexscale != FRACUNIT || mobj->spriteyscale != FRACUNIT) + diff2 |= MD2_SPRITESCALE; + if (mobj->spritexoffset || mobj->spriteyoffset) + diff2 |= MD2_SPRITEOFFSET; + if (mobj->sprxoff || mobj->spryoff || mobj->sprzoff) + diff2 |= MD2_WORLDOFFSET; if (mobj->floorspriteslope) { pslope_t *slope = mobj->floorspriteslope; @@ -2577,6 +2629,29 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 WRITEFIXED(save->p, mobj->destscale); if (diff2 & MD2_SCALESPEED) WRITEFIXED(save->p, mobj->scalespeed); + if (diff & MD_ARGS) + { + for (j = 0; j < NUMMAPTHINGARGS; j++) + WRITEINT32(save->p, mobj->args[j]); + } + if (diff & MD_STRINGARGS) + { + for (j = 0; j < NUMMAPTHINGSTRINGARGS; j++) + { + size_t len, k; + + if (!mobj->stringargs[j]) + { + WRITEINT32(save->p, 0); + continue; + } + + len = strlen(mobj->stringargs[j]); + WRITEINT32(save->p, len); + for (k = 0; k < len; k++) + WRITECHAR(save->p, mobj->stringargs[j][k]); + } + } if (diff2 & MD2_CUSVAL) WRITEINT32(save->p, mobj->cusval); if (diff2 & MD2_CVMEM) @@ -2624,14 +2699,24 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 } if (diff2 & MD2_TID) WRITEINT16(save->p, mobj->tid); - if (diff2 & MD2_SPRITEXSCALE) + if (diff2 & MD2_SPRITESCALE) + { WRITEFIXED(save->p, mobj->spritexscale); - if (diff2 & MD2_SPRITEYSCALE) WRITEFIXED(save->p, mobj->spriteyscale); - if (diff2 & MD2_SPRITEXOFFSET) + } + if (diff2 & MD2_SPRITEOFFSET) + { WRITEFIXED(save->p, mobj->spritexoffset); - if (diff2 & MD2_SPRITEYOFFSET) WRITEFIXED(save->p, mobj->spriteyoffset); + } + if (diff2 & MD2_WORLDOFFSET) + { + WRITEFIXED(save->p, mobj->sprxoff); + WRITEFIXED(save->p, mobj->spryoff); + WRITEFIXED(save->p, mobj->sprzoff); + } + if (diff2 & MD2_SPECIAL) + WRITEINT16(save->p, mobj->special); if (diff2 & MD2_FLOORSPRITESLOPE) { pslope_t *slope = mobj->floorspriteslope; @@ -3549,6 +3634,7 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) INT32 i; fixed_t z, floorz, ceilingz; ffloor_t *floorrover = NULL, *ceilingrover = NULL; + size_t j; diff = READUINT32(save->p); if (diff & MD_MORE) @@ -3742,6 +3828,31 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) mobj->scalespeed = READFIXED(save->p); else mobj->scalespeed = mapobjectscale/12; + if (diff & MD_ARGS) + { + for (j = 0; j < NUMMAPTHINGARGS; j++) + mobj->args[j] = READINT32(save->p); + } + if (diff & MD_STRINGARGS) + { + for (j = 0; j < NUMMAPTHINGSTRINGARGS; j++) + { + size_t len = READINT32(save->p); + size_t k; + + if (!len) + { + Z_Free(mobj->stringargs[j]); + mobj->stringargs[j] = NULL; + continue; + } + + mobj->stringargs[j] = Z_Realloc(mobj->stringargs[j], len + 1, PU_LEVEL, NULL); + for (k = 0; k < len; k++) + mobj->stringargs[j][k] = READCHAR(save->p); + mobj->stringargs[j][len] = '\0'; + } + } if (diff2 & MD2_CUSVAL) mobj->cusval = READINT32(save->p); if (diff2 & MD2_CVMEM) @@ -3777,18 +3888,38 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) mobj->renderflags = READUINT32(save->p); if (diff2 & MD2_TID) P_SetThingTID(mobj, READINT16(save->p)); - if (diff2 & MD2_SPRITEXSCALE) + if (diff2 & MD2_SPRITESCALE) + { mobj->spritexscale = READFIXED(save->p); - else - mobj->spritexscale = FRACUNIT; - if (diff2 & MD2_SPRITEYSCALE) mobj->spriteyscale = READFIXED(save->p); + } else - mobj->spriteyscale = FRACUNIT; - if (diff2 & MD2_SPRITEXOFFSET) + { + mobj->spritexscale = mobj->spriteyscale = FRACUNIT; + } + if (diff2 & MD2_SPRITEOFFSET) + { mobj->spritexoffset = READFIXED(save->p); - if (diff2 & MD2_SPRITEYOFFSET) mobj->spriteyoffset = READFIXED(save->p); + } + else + { + mobj->spritexoffset = mobj->spriteyoffset = 0; + } + if (diff2 & MD2_WORLDOFFSET) + { + mobj->sprxoff = READFIXED(save->p); + mobj->spryoff = READFIXED(save->p); + mobj->sprzoff = READFIXED(save->p); + } + else + { + mobj->sprxoff = mobj->spryoff = mobj->sprzoff = 0; + } + if (diff2 & MD2_SPECIAL) + { + mobj->special = READINT16(save->p); + } if (diff2 & MD2_FLOORSPRITESLOPE) { pslope_t *slope = (pslope_t *)P_CreateFloorSpriteSlope(mobj); @@ -3836,17 +3967,6 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) mobj->terrain = NULL; } - if (diff & MD_REDFLAG) - { - redflag = mobj; - rflagpoint = mobj->spawnpoint; - } - if (diff & MD_BLUEFLAG) - { - blueflag = mobj; - bflagpoint = mobj->spawnpoint; - } - // set sprev, snext, bprev, bnext, subsector P_SetThingPosition(mobj); diff --git a/src/p_setup.c b/src/p_setup.c index 4153f889a..1970d5e59 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -714,7 +714,7 @@ static int cmp_loopends(const void *a, const void *b) // weighted sorting; tag takes precedence over type return - intsign(Tag_FGet(&mt1->tags) - Tag_FGet(&mt2->tags)) * 2 + + intsign(mt1->tid - mt2->tid) * 2 + intsign(mt1->args[0] - mt2->args[0]); } @@ -793,7 +793,7 @@ static void P_SpawnMapThings(boolean spawnemblems) *mt1 = loopends[i - 1], *mt2 = loopends[i]; - if (Tag_FGet(&mt1->tags) == Tag_FGet(&mt2->tags) && + if (mt1->tid == mt2->tid && mt1->args[0] == mt2->args[0]) { P_SpawnItemLine(mt1, mt2); @@ -1305,7 +1305,7 @@ static void P_LoadThings(UINT8 *data) mt->type = READUINT16(data); mt->options = READUINT16(data); mt->extrainfo = (UINT8)(mt->type >> 12); - Tag_FSet(&mt->tags, 0); + mt->tid = 0; mt->scale = FRACUNIT; memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args)); memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); @@ -1870,17 +1870,7 @@ static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char static void ParseTextmapThingParameter(UINT32 i, const char *param, const char *val) { if (fastcmp(param, "id")) - Tag_FSet(&mapthings[i].tags, atol(val)); - else if (fastcmp(param, "moreids")) - { - const char* id = val; - while (id) - { - Tag_Add(&mapthings[i].tags, atol(id)); - if ((id = strchr(id, ' '))) - id++; - } - } + mapthings[i].tid = atol(val); else if (fastcmp(param, "x")) mapthings[i].x = atol(val); else if (fastcmp(param, "y")) @@ -2063,9 +2053,6 @@ static void P_WriteTextmap(void) for (i = 0; i < nummapthings; i++) { - if (mapthings[i].tags.count) - wmapthings[i].tags.tags = memcpy(Z_Malloc(mapthings[i].tags.count * sizeof(mtag_t), PU_LEVEL, NULL), mapthings[i].tags.tags, mapthings[i].tags.count * sizeof(mtag_t)); - if (mapthings[i].user.length) { wmapthings[i].user.properties = memcpy( @@ -2232,7 +2219,7 @@ static void P_WriteTextmap(void) CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %s with type 412 cannot be converted.\n"), sizeu1(i)); break; } - Tag_Add(&specialthings[s].teleport->tags, freetag); + specialthings[s].teleport->tid = freetag; wlines[i].args[0] = freetag; freetag = Tag_NextUnused(freetag); break; @@ -2246,7 +2233,7 @@ static void P_WriteTextmap(void) CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %s with type 422 cannot be converted.\n"), sizeu1(i)); break; } - Tag_Add(&specialthings[s].altview->tags, freetag); + specialthings[s].altview->tid = freetag; wlines[i].args[0] = freetag; specialthings[s].altview->pitch = wlines[i].args[2]; freetag = Tag_NextUnused(freetag); @@ -2271,7 +2258,7 @@ static void P_WriteTextmap(void) CONS_Alert(CONS_WARNING, M_GetText("No unused tag found. Linedef %s with type 457 cannot be converted.\n"), sizeu1(i)); break; } - Tag_Add(&specialthings[s].angleanchor->tags, freetag); + specialthings[s].angleanchor->tid = freetag; wlines[i].args[0] = freetag; freetag = Tag_NextUnused(freetag); break; @@ -2370,20 +2357,8 @@ static void P_WriteTextmap(void) { fprintf(f, "thing // %s\n", sizeu1(i)); fprintf(f, "{\n"); - firsttag = Tag_FGet(&wmapthings[i].tags); - if (firsttag != 0) - fprintf(f, "id = %d;\n", firsttag); - if (wmapthings[i].tags.count > 1) - { - fprintf(f, "moreids = \""); - for (j = 1; j < wmapthings[i].tags.count; j++) - { - if (j > 1) - fprintf(f, " "); - fprintf(f, "%d", wmapthings[i].tags.tags[j]); - } - fprintf(f, "\";\n"); - } + if (wmapthings[i].tid != 0) + fprintf(f, "id = %d;\n", wmapthings[i].tid); fprintf(f, "x = %d;\n", wmapthings[i].x); fprintf(f, "y = %d;\n", wmapthings[i].y); if (wmapthings[i].z != 0) @@ -2833,9 +2808,6 @@ static void P_WriteTextmap(void) for (i = 0; i < nummapthings; i++) { - if (wmapthings[i].tags.count) - Z_Free(wmapthings[i].tags.tags); - if (wmapthings[i].user.length) Z_Free(wmapthings[i].user.properties); } @@ -3045,7 +3017,7 @@ static void P_LoadTextmap(void) mt->options = 0; mt->z = 0; mt->extrainfo = 0; - Tag_FSet(&mt->tags, 0); + mt->tid = 0; mt->scale = FRACUNIT; memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args)); memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); @@ -4304,7 +4276,7 @@ static void P_AddBinaryMapTags(void) case 760: case 761: case 762: - Tag_FSet(&mapthings[i].tags, mapthings[i].angle); + mapthings[i].tid = mapthings[i].angle; break; case 290: case 292: @@ -4312,7 +4284,7 @@ static void P_AddBinaryMapTags(void) case 780: case 2020: // MT_LOOPENDPOINT case 2021: // MT_LOOPCENTERPOINT - Tag_FSet(&mapthings[i].tags, mapthings[i].extrainfo); + mapthings[i].tid = mapthings[i].extrainfo; break; default: break; @@ -6837,9 +6809,8 @@ static void P_ConvertBinaryThingTypes(void) { INT32 check = -1; INT32 firstline = -1; - mtag_t tag = Tag_FGet(&mapthings[i].tags); - TAG_ITER_LINES(tag, check) + TAG_ITER_LINES(mapthings[i].tid, check) { if (lines[check].special == 20) { @@ -7058,7 +7029,7 @@ static void P_ConvertBinaryThingTypes(void) { INT32 firstline = Tag_FindLineSpecial(2000, (INT16)mapthings[i].angle); - Tag_FSet(&mapthings[i].tags, mapthings[i].angle); + mapthings[i].tid = mapthings[i].angle; mapthings[i].args[0] = mapthings[i].z; mapthings[i].z = 0; @@ -7135,6 +7106,10 @@ static void P_ConvertBinaryThingTypes(void) case 2050: // MT_DUELBOMB mapthings[i].args[1] = !!(mapthings[i].options & MTF_AMBUSH); break; + case 1950: // MT_AAZTREE_HELPER + mapthings[i].args[0] = mapthings[i].extrainfo; + mapthings[i].args[1] = mapthings[i].angle; + break; case 2333: // MT_BATTLECAPSULE mapthings[i].args[0] = mapthings[i].extrainfo; mapthings[i].args[1] = mapthings[i].angle; @@ -7160,7 +7135,7 @@ static void P_ConvertBinaryThingTypes(void) break; case FLOOR_SLOPE_THING: case CEILING_SLOPE_THING: - Tag_FSet(&mapthings[i].tags, mapthings[i].extrainfo); + mapthings[i].tid = mapthings[i].extrainfo; break; default: break; @@ -7376,10 +7351,6 @@ static void P_InitLevelSettings(void) // emerald hunt hunt1 = hunt2 = hunt3 = NULL; - // clear ctf pointers - redflag = blueflag = NULL; - rflagpoint = bflagpoint = NULL; - // circuit, race and competition stuff numstarposts = 0; timeinmap = 0; diff --git a/src/p_slopes.c b/src/p_slopes.c index d71f80813..38a173baa 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -624,11 +624,11 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag if (mt->type != 750) // Haha, I'm hijacking the old Chaos Spawn thingtype for something! continue; - if (!vertices[0] && Tag_Find(&mt->tags, tag1)) + if (!vertices[0] && mt->tid == tag1) vertices[0] = mt; - else if (!vertices[1] && Tag_Find(&mt->tags, tag2)) + else if (!vertices[1] && mt->tid == tag2) vertices[1] = mt; - else if (!vertices[2] && Tag_Find(&mt->tags, tag3)) + else if (!vertices[2] && mt->tid == tag3) vertices[2] = mt; } diff --git a/src/p_spec.c b/src/p_spec.c index ccc40d337..b987f3d22 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2338,7 +2338,6 @@ void P_PushSpecialLine(line_t *line, mobj_t *thing) // void P_ActivateThingSpecial(mobj_t *mo, mobj_t *source) { - mapthing_t *mt = NULL; player_t *player = NULL; activator_t *activator = NULL; @@ -2348,13 +2347,6 @@ void P_ActivateThingSpecial(mobj_t *mo, mobj_t *source) return; } - mt = mo->spawnpoint; - if (mt == NULL) - { - // No mapthing to activate the special of. - return; - } - // Is this necessary? Probably not, but I hate // spectators so I will manually ensure they // can't impact the gamestate anyway. @@ -2374,7 +2366,7 @@ void P_ActivateThingSpecial(mobj_t *mo, mobj_t *source) } } - if (P_CanActivateSpecial(mt->special) == false) + if (P_CanActivateSpecial(mo->special) == false) { // No special to even activate. return; @@ -2389,7 +2381,7 @@ void P_ActivateThingSpecial(mobj_t *mo, mobj_t *source) activator->sector = source->subsector->sector; } - P_ProcessSpecial(activator, mt->special, mt->args, mt->stringargs); + P_ProcessSpecial(activator, mo->special, mo->args, mo->stringargs); P_SetTarget(&activator->mo, NULL); Z_Free(activator); @@ -3041,7 +3033,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha } newViewMobj = P_FindObjectTypeFromTag(MT_ALTVIEWMAN, args[0]); - if (newViewMobj == NULL || newViewMobj->spawnpoint == NULL) + if (newViewMobj == NULL) { return false; } @@ -6308,7 +6300,7 @@ P_RaiseTaggedThingsToFakeFloor ( if ( (type == 0 || mthing->type == type) && - (tag == 0 || udmf ? Tag_Find(&mthing->tags, tag) : mthing->angle == tag) + (tag == 0 || (udmf ? mthing->tid : mthing->angle) == tag) ){ if (( mo->flags2 & MF2_OBJECTFLIP )) { diff --git a/src/slope_anchors.c b/src/slope_anchors.c index 18a9ac46e..1ee1286dd 100644 --- a/src/slope_anchors.c +++ b/src/slope_anchors.c @@ -199,7 +199,7 @@ get_anchor for (i = 0; i < list->count; ++i) { - if (list->points[i] == v && Tag_FGet(&list->anchors[i]->tags) == tag) + if (list->points[i] == v && list->anchors[i]->tid == tag) { for (k = 0; k < 3; ++k) { diff --git a/src/taglist.c b/src/taglist.c index df4b18a50..e1f60cf11 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -25,7 +25,6 @@ size_t num_tags; // in several taggroups at the same time. These are built on level load. taggroup_t* tags_sectors[MAXTAGS + 1]; taggroup_t* tags_lines[MAXTAGS + 1]; -taggroup_t* tags_mapthings[MAXTAGS + 1]; /// Adds a tag to a given element's taglist. It will not add a duplicate. /// \warning This does not rebuild the global taggroups, which are used for iteration. @@ -247,8 +246,7 @@ static size_t total_elements_with_tag (const mtag_t tag) return ( Taggroup_Count(tags_sectors[tag]) + - Taggroup_Count(tags_lines[tag]) + - Taggroup_Count(tags_mapthings[tag]) + Taggroup_Count(tags_lines[tag]) ); } @@ -309,12 +307,7 @@ static void Taglist_AddToLines (const mtag_t tag, const size_t itemid) Taggroup_Add_Init(tags_lines, tag, itemid); } -static void Taglist_AddToMapthings (const mtag_t tag, const size_t itemid) -{ - Taggroup_Add_Init(tags_mapthings, tag, itemid); -} - -/// After all taglists have been built for each element (sectors, lines, things), +/// After all taglists have been built for each element (sectors, lines), /// the global taggroups, made for iteration, are built here. void Taglist_InitGlobalTables(void) { @@ -327,7 +320,6 @@ void Taglist_InitGlobalTables(void) { tags_sectors[i] = NULL; tags_lines[i] = NULL; - tags_mapthings[i] = NULL; } for (i = 0; i < numsectors; i++) { @@ -339,11 +331,6 @@ void Taglist_InitGlobalTables(void) for (j = 0; j < lines[i].tags.count; j++) Taglist_AddToLines(lines[i].tags.tags[j], i); } - for (i = 0; i < nummapthings; i++) - { - for (j = 0; j < mapthings[i].tags.count; j++) - Taglist_AddToMapthings(mapthings[i].tags.tags[j], i); - } } // Iteration, ingame search. @@ -358,11 +345,6 @@ INT32 Tag_Iterate_Lines (const mtag_t tag, const size_t p) return Taggroup_Iterate(tags_lines, numlines, tag, p); } -INT32 Tag_Iterate_Things (const mtag_t tag, const size_t p) -{ - return Taggroup_Iterate(tags_mapthings, nummapthings, tag, p); -} - INT32 Tag_FindLineSpecial(const INT16 special, const mtag_t tag) { size_t i; @@ -468,3 +450,30 @@ mtag_t Tag_NextUnused(mtag_t start) return (mtag_t)MAXTAGS; } + +// This is no longer a tag list to maintain parity with mobjs, +// but it's convenient to keep it in this file anyway. +INT32 Tag_Iterate_Things (const mtag_t tag, const size_t p) +{ + size_t i = SIZE_MAX; + + if (tag == MTAG_GLOBAL) + { + if (p < nummapthings) + { + return p; + } + + return -1; + } + + for (i = p; i < nummapthings; i++) + { + if (mapthings[i].tid == tag) + { + return i; + } + } + + return -1; +} diff --git a/src/taglist.h b/src/taglist.h index 938e98fa4..14cf586aa 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -59,7 +59,6 @@ extern size_t num_tags; extern taggroup_t* tags_sectors[]; extern taggroup_t* tags_lines[]; -extern taggroup_t* tags_mapthings[]; void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id); void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id);