Commit 50e15840 by James R.

Merge branch 'udmf-multitag' into 'next'

UDMF: Multitag support See merge request STJr/SRB2!1097
parents 2a35e0d5 d3199ac7
......@@ -169,6 +169,7 @@ set(SRB2_CORE_GAME_SOURCES
p_telept.c
p_tick.c
p_user.c
taglist.c
p_local.h
p_maputl.h
......@@ -180,6 +181,7 @@ set(SRB2_CORE_GAME_SOURCES
p_slopes.h
p_spec.h
p_tick.h
taglist.h
)
if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
......
......@@ -522,6 +522,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/r_picformats.o \
$(OBJDIR)/r_portal.o \
$(OBJDIR)/screen.o \
$(OBJDIR)/taglist.o \
$(OBJDIR)/v_video.o \
$(OBJDIR)/s_sound.o \
$(OBJDIR)/sounds.o \
......
......@@ -23,6 +23,7 @@
// Some global defines, that configure the game.
#include "doomdef.h"
#include "taglist.h"
#include "m_fixed.h" // See the mapthing_t scale.
//
......@@ -208,11 +209,10 @@ typedef struct
UINT16 options;
INT16 z;
UINT8 extrainfo;
taglist_t tags;
fixed_t scale;
INT16 tag;
INT32 args[NUMMAPTHINGARGS];
char *stringargs[NUMMAPTHINGSTRINGARGS];
struct mobj_s *mobj;
} mapthing_t;
......
......@@ -1608,7 +1608,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
//Hurdler: 3d-floors test
if (gl_frontsector && gl_backsector && gl_frontsector->tag != gl_backsector->tag && (gl_backsector->ffloors || gl_frontsector->ffloors))
if (gl_frontsector && gl_backsector && !Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags) && (gl_backsector->ffloors || gl_frontsector->ffloors))
{
ffloor_t * rover;
fixed_t highcut = 0, lowcut = 0;
......@@ -1625,6 +1625,18 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
for (rover = gl_backsector->ffloors; rover; rover = rover->next)
{
boolean bothsides = false;
// Skip if it exists on both sectors.
ffloor_t * r2;
for (r2 = gl_frontsector->ffloors; r2; r2 = r2->next)
if (rover->master == r2->master)
{
bothsides = true;
break;
}
if (bothsides) continue;
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES))
continue;
if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES)
......@@ -1759,6 +1771,18 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{
for (rover = gl_frontsector->ffloors; rover; rover = rover->next)
{
boolean bothsides = false;
// Skip if it exists on both sectors.
ffloor_t * r2;
for (r2 = gl_backsector->ffloors; r2; r2 = r2->next)
if (rover->master == r2->master)
{
bothsides = true;
break;
}
if (bothsides) continue;
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES))
continue;
if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES))
......@@ -2384,7 +2408,7 @@ static void HWR_AddLine(seg_t * line)
if (!line->polyseg &&
!line->sidedef->midtexture
&& ((!gl_frontsector->ffloors && !gl_backsector->ffloors)
|| (gl_frontsector->tag == gl_backsector->tag)))
|| Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags)))
return; // line is empty, don't even bother
// treat like wide open window instead
HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D
......@@ -2423,7 +2447,7 @@ static void HWR_AddLine(seg_t * line)
if (!line->polyseg &&
!line->sidedef->midtexture
&& ((!gl_frontsector->ffloors && !gl_backsector->ffloors)
|| (gl_frontsector->tag == gl_backsector->tag)))
|| Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags)))
return; // line is empty, don't even bother
goto clippass; // treat like wide open window instead
......
......@@ -32,6 +32,7 @@
#include "lua_script.h"
#include "lua_libs.h"
#include "lua_hud.h" // hud_running errors
#include "taglist.h" // P_FindSpecialLineFromTag
#include "lua_hook.h" // hook_cmd_running errors
#define NOHUD if (hud_running)\
......
......@@ -99,8 +99,6 @@ enum line_e {
line_slopetype,
line_frontsector,
line_backsector,
line_firsttag,
line_nexttag,
line_polyobj,
line_text,
line_callcount
......@@ -125,8 +123,6 @@ static const char *const line_opt[] = {
"slopetype",
"frontsector",
"backsector",
"firsttag",
"nexttag",
"polyobj",
"text",
"callcount",
......@@ -583,7 +579,7 @@ static int sector_get(lua_State *L)
lua_pushinteger(L, sector->special);
return 1;
case sector_tag:
lua_pushinteger(L, sector->tag);
lua_pushinteger(L, Tag_FGet(&sector->tags));
return 1;
case sector_thinglist: // thinglist
lua_pushcfunction(L, lib_iterateSectorThinglist);
......@@ -684,7 +680,7 @@ static int sector_set(lua_State *L)
sector->special = (INT16)luaL_checkinteger(L, 3);
break;
case sector_tag:
P_ChangeSectorTag((UINT32)(sector - sectors), (INT16)luaL_checkinteger(L, 3));
Tag_SectorFSet((UINT32)(sector - sectors), (INT16)luaL_checkinteger(L, 3));
break;
}
return 0;
......@@ -823,7 +819,7 @@ static int line_get(lua_State *L)
lua_pushinteger(L, line->special);
return 1;
case line_tag:
lua_pushinteger(L, line->tag);
lua_pushinteger(L, Tag_FGet(&line->tags));
return 1;
case line_args:
LUA_PushUserdata(L, line->args, META_LINEARGS);
......@@ -871,12 +867,6 @@ static int line_get(lua_State *L)
case line_backsector:
LUA_PushUserdata(L, line->backsector, META_SECTOR);
return 1;
case line_firsttag:
lua_pushinteger(L, line->firsttag);
return 1;
case line_nexttag:
lua_pushinteger(L, line->nexttag);
return 1;
case line_polyobj:
LUA_PushUserdata(L, line->polyobj, META_POLYOBJ);
return 1;
......
......@@ -848,7 +848,7 @@ static int mapthing_get(lua_State *L)
else if(fastcmp(field,"extrainfo"))
number = mt->extrainfo;
else if(fastcmp(field,"tag"))
number = mt->tag;
number = Tag_FGet(&mt->tags);
else if(fastcmp(field,"args"))
{
LUA_PushUserdata(L, mt->args, META_THINGARGS);
......@@ -910,7 +910,7 @@ static int mapthing_set(lua_State *L)
mt->extrainfo = (UINT8)extrainfo;
}
else if (fastcmp(field,"tag"))
mt->tag = (INT16)luaL_checkinteger(L, 3);
Tag_FSet(&mt->tags, (INT16)luaL_checkinteger(L, 3));
else if(fastcmp(field,"mobj"))
mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
else
......
......@@ -1108,7 +1108,6 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value;
mt->scale = player->mo->scale;
mt->tag = 0;
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
mt->pitch = mt->roll = 0;
......
......@@ -394,8 +394,10 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
INT32 secnum = -1;
sector_t *sec;
ceiling_t *ceiling;
mtag_t tag = Tag_FGet(&line->tags);
TAG_ITER_DECLARECOUNTER(0);
while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0)
TAG_ITER_SECTORS(0, tag, secnum)
{
sec = &sectors[secnum];
......@@ -593,7 +595,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
}
ceiling->tag = sec->tag;
ceiling->tag = tag;
ceiling->type = type;
firstone = 0;
}
......@@ -614,8 +616,10 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type)
INT32 secnum = -1;
sector_t *sec;
ceiling_t *ceiling;
mtag_t tag = Tag_FGet(&line->tags);
TAG_ITER_DECLARECOUNTER(0);
while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0)
TAG_ITER_SECTORS(0, tag, secnum)
{
sec = &sectors[secnum];
......@@ -670,7 +674,7 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type)
break;
}
ceiling->tag = sec->tag;
ceiling->tag = tag;
ceiling->type = type;
}
return rtn;
......
......@@ -3925,11 +3925,12 @@ void A_BossDeath(mobj_t *mo)
else
{
// Bring the egg trap up to the surface
junk.tag = LE_CAPSULE0;
// Incredibly shitty code ahead
Tag_FSet(&junk.tags, LE_CAPSULE0);
EV_DoElevator(&junk, elevateHighest, false);
junk.tag = LE_CAPSULE1;
Tag_FSet(&junk.tags, LE_CAPSULE1);
EV_DoElevator(&junk, elevateUp, false);
junk.tag = LE_CAPSULE2;
Tag_FSet(&junk.tags, LE_CAPSULE2);
EV_DoElevator(&junk, elevateHighest, false);
if (mapheaderinfo[gamemap-1]->muspostbossname[0] &&
......@@ -4052,7 +4053,7 @@ bossjustdie:
}
case MT_KOOPA:
{
junk.tag = LE_KOOPA;
Tag_FSet(&junk.tags, LE_KOOPA);
EV_DoCeiling(&junk, raiseToHighest);
return;
}
......@@ -6157,7 +6158,7 @@ void A_RockSpawn(mobj_t *actor)
{
mobj_t *mo;
mobjtype_t type;
INT32 i = P_FindSpecialLineFromTag(12, (INT16)actor->threshold, -1);
INT32 i = Tag_FindLineSpecial(12, (INT16)actor->threshold);
line_t *line;
fixed_t dist;
fixed_t randomoomph;
......
......@@ -632,8 +632,10 @@ void T_BounceCheese(bouncecheese_t *bouncer)
fixed_t waterheight;
fixed_t floorheight;
sector_t *actionsector;
INT32 i;
boolean remove;
INT32 i;
mtag_t tag = Tag_FGet(&bouncer->sourceline->tags);
TAG_ITER_DECLARECOUNTER(0);
if (bouncer->sector->crumblestate == CRUMBLE_RESTORE || bouncer->sector->crumblestate == CRUMBLE_WAIT
|| bouncer->sector->crumblestate == CRUMBLE_ACTIVATED) // Oops! Crumbler says to remove yourself!
......@@ -648,7 +650,7 @@ void T_BounceCheese(bouncecheese_t *bouncer)
}
// You can use multiple target sectors, but at your own risk!!!
for (i = -1; (i = P_FindSectorFromTag(bouncer->sourceline->tag, i)) >= 0 ;)
TAG_ITER_SECTORS(0, tag, i)
{
actionsector = &sectors[i];
actionsector->moved = true;
......@@ -772,6 +774,8 @@ void T_StartCrumble(crumble_t *crumble)
ffloor_t *rover;
sector_t *sector;
INT32 i;
mtag_t tag = Tag_FGet(&crumble->sourceline->tags);
TAG_ITER_DECLARECOUNTER(0);
// Once done, the no-return thinker just sits there,
// constantly 'returning'... kind of an oxymoron, isn't it?
......@@ -800,7 +804,7 @@ void T_StartCrumble(crumble_t *crumble)
}
else if (++crumble->timer == 0) // Reposition back to original spot
{
for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;)
TAG_ITER_SECTORS(0, tag, i)
{
sector = &sectors[i];
......@@ -836,7 +840,7 @@ void T_StartCrumble(crumble_t *crumble)
// Flash to indicate that the platform is about to return.
if (crumble->timer > -224 && (leveltime % ((abs(crumble->timer)/8) + 1) == 0))
{
for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;)
TAG_ITER_SECTORS(0, tag, i)
{
sector = &sectors[i];
......@@ -928,7 +932,7 @@ void T_StartCrumble(crumble_t *crumble)
P_RemoveThinker(&crumble->thinker);
}
for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;)
TAG_ITER_SECTORS(0, tag, i)
{
sector = &sectors[i];
sector->moved = true;
......@@ -944,6 +948,7 @@ void T_StartCrumble(crumble_t *crumble)
void T_MarioBlock(mariothink_t *block)
{
INT32 i;
TAG_ITER_DECLARECOUNTER(0);
T_MovePlane
(
......@@ -978,8 +983,7 @@ void T_MarioBlock(mariothink_t *block)
block->sector->ceilspeed = 0;
block->direction = 0;
}
for (i = -1; (i = P_FindSectorFromTag(block->tag, i)) >= 0 ;)
TAG_ITER_SECTORS(0, (INT16)block->tag, i)
P_RecalcPrecipInSector(&sectors[i]);
}
......@@ -992,8 +996,7 @@ void T_FloatSector(floatthink_t *floater)
// Just find the first sector with the tag.
// Doesn't work with multiple sectors that have different floor/ceiling heights.
secnum = P_FindSectorFromTag(floater->tag, -1);
if (secnum <= 0)
if ((secnum = Tag_Iterate_Sectors((INT16)floater->tag, 0)) < 0)
return;
actionsector = &sectors[secnum];
......@@ -1131,10 +1134,8 @@ void T_ThwompSector(thwomp_t *thwomp)
// Just find the first sector with the tag.
// Doesn't work with multiple sectors that have different floor/ceiling heights.
secnum = P_FindSectorFromTag(thwomp->tag, -1);
if (secnum <= 0)
return; // Bad bad bad!
if ((secnum = Tag_Iterate_Sectors((INT16)thwomp->tag, 0)) < 0)
return;
actionsector = &sectors[secnum];
......@@ -1293,8 +1294,10 @@ void T_NoEnemiesSector(noenemies_t *nobaddies)
sector_t *sec = NULL;
INT32 secnum = -1;
boolean FOFsector = false;
mtag_t tag = Tag_FGet(&nobaddies->sourceline->tags);
TAG_ITER_DECLARECOUNTER(0);
while ((secnum = P_FindSectorFromTag(nobaddies->sourceline->tag, secnum)) >= 0)
TAG_ITER_SECTORS(0, tag, secnum)
{
sec = &sectors[secnum];
......@@ -1304,13 +1307,15 @@ void T_NoEnemiesSector(noenemies_t *nobaddies)
for (i = 0; i < sec->linecount; i++)
{
INT32 targetsecnum = -1;
mtag_t tag2 = Tag_FGet(&sec->lines[i]->tags);
TAG_ITER_DECLARECOUNTER(1);
if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300)
continue;
FOFsector = true;
while ((targetsecnum = P_FindSectorFromTag(sec->lines[i]->tag, targetsecnum)) >= 0)
TAG_ITER_SECTORS(1, tag2, targetsecnum)
{
if (T_SectorHasEnemies(&sectors[targetsecnum]))
return;
......@@ -1321,7 +1326,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies)
return;
}
CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", nobaddies->sourceline->tag);
CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", tag);
// No enemies found, run the linedef exec and terminate this thinker
P_RunTriggerLinedef(nobaddies->sourceline, NULL, NULL);
......@@ -1396,6 +1401,8 @@ void T_EachTimeThinker(eachtime_t *eachtime)
boolean floortouch = false;
fixed_t bottomheight, topheight;
ffloor_t *rover;
mtag_t tag = Tag_FGet(&eachtime->sourceline->tags);
TAG_ITER_DECLARECOUNTER(0);
for (i = 0; i < MAXPLAYERS; i++)
{
......@@ -1405,7 +1412,7 @@ void T_EachTimeThinker(eachtime_t *eachtime)
eachtime->playersOnArea[i] = false;
}
while ((secnum = P_FindSectorFromTag(eachtime->sourceline->tag, secnum)) >= 0)
TAG_ITER_SECTORS(0, tag, secnum)
{
sec = &sectors[secnum];
......@@ -1422,13 +1429,15 @@ void T_EachTimeThinker(eachtime_t *eachtime)
for (i = 0; i < sec->linecount; i++)
{
INT32 targetsecnum = -1;
mtag_t tag2 = Tag_FGet(&sec->lines[i]->tags);
TAG_ITER_DECLARECOUNTER(1);
if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300)
continue;
FOFsector = true;
while ((targetsecnum = P_FindSectorFromTag(sec->lines[i]->tag, targetsecnum)) >= 0)
TAG_ITER_SECTORS(1, tag2, targetsecnum)
{
targetsec = &sectors[targetsecnum];
......@@ -1530,7 +1539,7 @@ void T_EachTimeThinker(eachtime_t *eachtime)
if (!playersArea[i] && (!eachtime->triggerOnExit || !P_IsPlayerValid(i)))
continue;
CONS_Debug(DBG_GAMELOGIC, "Trying to activate each time executor with tag %d\n", eachtime->sourceline->tag);
CONS_Debug(DBG_GAMELOGIC, "Trying to activate each time executor with tag %d\n", tag);
// 03/08/14 -Monster Iestyn
// No more stupid hacks involving changing eachtime->sourceline's tag or special or whatever!
......@@ -1562,11 +1571,13 @@ void T_RaiseSector(raise_t *raise)
fixed_t distToNearestEndpoint;
INT32 direction;
result_e res = 0;
mtag_t tag = raise->tag;
TAG_ITER_DECLARECOUNTER(0);
if (raise->sector->crumblestate >= CRUMBLE_FALL || raise->sector->ceilingdata)
return;
for (i = -1; (i = P_FindSectorFromTag(raise->tag, i)) >= 0 ;)
TAG_ITER_SECTORS(0, tag, i)
{
sector = &sectors[i];
......@@ -1693,7 +1704,7 @@ void T_RaiseSector(raise_t *raise)
raise->sector->ceilspeed = 42;
raise->sector->floorspeed = speed*direction;
for (i = -1; (i = P_FindSectorFromTag(raise->tag, i)) >= 0 ;)
TAG_ITER_SECTORS(0, tag, i)
P_RecalcPrecipInSector(&sectors[i]);
}
......@@ -1810,8 +1821,10 @@ void EV_DoFloor(line_t *line, floor_e floortype)
INT32 secnum = -1;
sector_t *sec;
floormove_t *dofloor;
mtag_t tag = Tag_FGet(&line->tags);
TAG_ITER_DECLARECOUNTER(0);
while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0)
TAG_ITER_SECTORS(0, tag, secnum)
{
sec = &sectors[secnum];
......@@ -2025,9 +2038,11 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed)
INT32 secnum = -1;
sector_t *sec;
elevator_t *elevator;
mtag_t tag = Tag_FGet(&line->tags);
TAG_ITER_DECLARECOUNTER(0);
// act on all sectors with the same tag as the triggering linedef
while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0)
TAG_ITER_SECTORS(0, tag, secnum)
{
sec = &sectors[secnum];
......@@ -2148,6 +2163,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
INT16 flags;
sector_t *controlsec = rover->master->frontsector;
mtag_t tag = Tag_FGet(&controlsec->tags);
if (sec == NULL)
{
......@@ -2176,9 +2192,9 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
lifetime = 3*TICRATE;
flags = 0;
if (controlsec->tag != 0)
if (tag != 0)
{
INT32 tagline = P_FindSpecialLineFromTag(14, controlsec->tag, -1);
INT32 tagline = Tag_FindLineSpecial(14, tag);
if (tagline != -1)
{
if (sides[lines[tagline].sidenum[0]].toptexture)
......@@ -2322,6 +2338,8 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
crumble_t *crumble;
sector_t *foundsec;
INT32 i;
mtag_t tag = Tag_FGet(&rover->master->tags);
TAG_ITER_DECLARECOUNTER(0);
// If floor is already activated, skip it
if (sec->floordata)
......@@ -2364,7 +2382,7 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
crumble->sector->crumblestate = CRUMBLE_ACTIVATED;
for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;)
TAG_ITER_SECTORS(0, tag, i)
{
foundsec = &sectors[i];
......@@ -2413,7 +2431,7 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
block->direction = 1;
block->floorstartheight = block->sector->floorheight;
block->ceilingstartheight = block->sector->ceilingheight;
block->tag = (INT16)sector->tag;
block->tag = (INT16)Tag_FGet(&sector->tags);
if (itsamonitor)
{
......
......@@ -1388,7 +1388,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (player->bot)
return;
junk.tag = LE_AXE;
Tag_FSet(&junk.tags, LE_AXE);
EV_DoElevator(&junk, bridgeFall, false);
// scan the remaining thinkers to find koopa
......
......@@ -374,8 +374,10 @@ void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force)
{
INT32 i;
TAG_ITER_DECLARECOUNTER(0);
// search all sectors for ones with tag
for (i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0 ;)
TAG_ITER_SECTORS(0, tag, i)
{
if (!force && ticbased // always let speed fader execute
&& sectors[i].lightingdata
......
......@@ -3536,16 +3536,19 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
{
sector_t *sector;
fixed_t halfheight = thiscam->z + (thiscam->height >> 1);
size_t i;
// see if we are in water
sector = thiscam->subsector->sector;
if (P_FindSpecialLineFromTag(13, sector->tag, -1) != -1)
return true;
for (i = 0; i < sector->tags.count; i++)
if (Tag_FindLineSpecial(13, sector->tags.tags[i]) != -1)
return true;
if (sector->ffloors)
{
ffloor_t *rover;
size_t j;
for (rover = sector->ffloors; rover; rover = rover->next)
{
......@@ -3557,7 +3560,8 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
if (halfheight <= P_GetFFloorBottomZAt(rover, thiscam->x, thiscam->y))
continue;
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
for (j = 0; j < rover->master->frontsector->tags.count; j++)
if (Tag_FindLineSpecial(13, rover->master->frontsector->tags.tags[j]) != -1)
return true;
}
}
......@@ -4626,16 +4630,18 @@ static boolean P_Boss4MoveCage(mobj_t *mobj, fixed_t delta)
const UINT16 tag = 65534 + (mobj->spawnpoint ? mobj->spawnpoint->extrainfo*LE_PARAMWIDTH : 0);
INT32 snum;
sector_t *sector;
for (snum = sectors[tag%numsectors].firsttag; snum != -1; snum = sector->nexttag)
boolean gotcage = false;
TAG_ITER_DECLARECOUNTER(0);
TAG_ITER_SECTORS(0, tag, snum)
{
sector = &sectors[snum];
if (sector->tag != tag)
continue;
sector->floorheight += delta;
sector->ceilingheight += delta;
P_CheckSector(sector, true);
gotcage = true;
}
return sectors[tag%numsectors].firsttag != -1;
return gotcage;
}
// Move Boss4's arms to angle
......@@ -4707,26 +4713,16 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz)
static void P_Boss4DestroyCage(mobj_t *mobj)
{
const UINT16 tag = 65534 + (mobj->spawnpoint ? mobj->spawnpoint->extrainfo*LE_PARAMWIDTH : 0);
INT32 snum, next;
INT32 snum;
size_t a;
sector_t *sector, *rsec;
ffloor_t *rover;
TAG_ITER_DECLARECOUNTER(0);
// This will be the final iteration of sector tag.
// We'll destroy the tag list as we go.
next = sectors[tag%numsectors].firsttag;
sectors[tag%numsectors].firsttag = -1;
for (snum = next; snum != -1; snum = next)
TAG_ITER_SECTORS(0, tag, snum)
{
sector = &sectors[snum];
next = sector->nexttag;
sector->nexttag = -1;
if (sector->tag != tag)
continue;
sector->tag = 0;
// Destroy the FOFs.
for (a = 0; a < sector->numattached; a++)
{
......@@ -10046,11 +10042,12 @@ void P_MobjThinker(mobj_t *mobj)
// Sector special (2,8) allows ANY mobj to trigger a linedef exec
if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8)
{
sector_t *sec2;
sec2 = P_ThingOnSpecial3DFloor(mobj);
sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj);
if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1)
P_LinedefExecute(sec2->tag, mobj, sec2);
{
mtag_t tag = Tag_FGet(&sec2->tags);
P_LinedefExecute(tag, mobj, sec2);
}
}
if (mobj->scale != mobj->destscale)
......@@ -10274,14 +10271,19 @@ void P_PushableThinker(mobj_t *mobj)
sec = mobj->subsector->sector;
if (GETSECSPECIAL(sec->special, 2) == 1 && mobj->z == sec->floorheight)
P_LinedefExecute(sec->tag, mobj, sec);
// else if (GETSECSPECIAL(sec->special, 2) == 8)
{
sector_t *sec2;
mtag_t tag = Tag_FGet(&sec->tags);
P_LinedefExecute(tag, mobj, sec);
}
sec2 = P_ThingOnSpecial3DFloor(mobj);
// else if (GETSECSPECIAL(sec->special, 2) == 8)
{
sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj);
if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1)
P_LinedefExecute(sec2->tag, mobj, sec2);
{
mtag_t tag = Tag_FGet(&sec2->tags);
P_LinedefExecute(tag, mobj, sec2);
}
}
// it has to be pushable RIGHT NOW for this part to happen
......@@ -12030,8 +12032,7 @@ static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle)
const size_t mthingi = (size_t)(mthing - mapthings);
// Find the corresponding linedef special, using angle as tag
// P_FindSpecialLineFromTag works here now =D
line = P_FindSpecialLineFromTag(9, mthing->angle, -1);
line = Tag_FindLineSpecial(9, mthing->angle);
if (line == -1)
{
......@@ -12341,7 +12342,7 @@ static boolean P_SetupParticleGen(mapthing_t *mthing, mobj_t *mobj)
const size_t mthingi = (size_t)(mthing - mapthings);
// Find the corresponding linedef special, using angle as tag
line = P_FindSpecialLineFromTag(15, mthing->angle, -1);
line = Tag_FindLineSpecial(15, mthing->angle);
if (line == -1)
{
......@@ -12580,17 +12581,20 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
break;
}
case MT_SKYBOX:
if (mthing->tag < 0 || mthing->tag > 15)