Replace most sector specials with sector special flags

This commit is contained in:
MascaraSnake 2021-12-31 00:03:24 +01:00
parent e1393954c7
commit feaa4f1273
15 changed files with 446 additions and 171 deletions

View file

@ -82,6 +82,25 @@ sectorflags
gravityflip = "Flip Objects in Reverse Gravity";
heatwave = "Heat Wave";
noclipcamera = "Intangible to the Camera";
outerspace = "Space Countdown";
doublestepup = "Ramp Sector (double step-up/down)";
nostepdown = "Non-Ramp Sector (No step-down)";
windcurrent = "Wind/Current";
conveyor = "Conveyor Belt";
speedpad = "Speed Pad";
starpostactivator = "Star Post Activator";
exit = "Exit";
specialstagepit = "Special Stage Pit";
returnflag = "Return Flag";
redteambase = "Red Team Base";
blueteambase = "Blue Team Base";
fan = "Fan Sector";
supertransform = "Super Sonic Transform";
forcespin = "Force Spin";
zoomtubestart = "Zoom Tube Start";
zoomtubeend = "Zoom Tube End";
finishline = "Circuit Finish Line";
ropehang = "Rope Hang";
}
thingflags

View file

@ -353,6 +353,16 @@ static inline int lib_getenum(lua_State *L)
if (mathlib) return luaL_error(L, "sector flag '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("SSF_", word, 3)) {
p = word + 4;
for (i = 0; i < 19; i++)
if (SSF_LIST[i] && fastcmp(p, SSF_LIST[i])) {
lua_pushinteger(L, ((lua_Integer)1 << i));
return 1;
}
if (mathlib) return luaL_error(L, "sector special flag '%s' could not be found.\n", word);
return 0;
}
else if (fastncmp("S_",word,2)) {
p = word+2;
for (i = 0; i < NUMSTATEFREESLOTS; i++) {

View file

@ -4482,6 +4482,28 @@ const char *const MSF_LIST[7] = {
"NOCLIPCAMERA",
};
// Sector special flags
const char* const SSF_LIST[19] = {
"OUTERSPACE",
"DOUBLESTEPUP",
"WINDCURRENT",
"CONVEYOR",
"SPEEDPAD",
"STARPOSTACTIVATOR",
"EXIT",
"SPECIALSTAGEPIT",
"RETURNFLAG",
"REDTEAMBASE",
"BLUETEAMBASE",
"FAN",
"SUPERTRANSFORM",
"FORCESPIN",
"ZOOMTUBESTART",
"ZOOMTUBEEND",
"FINISHLINE",
"ROPEHANG",
};
const char *COLOR_ENUMS[] = {
"NONE", // SKINCOLOR_NONE,

View file

@ -66,6 +66,7 @@ extern const char *const PLAYERFLAG_LIST[];
extern const char *const GAMETYPERULE_LIST[];
extern const char *const ML_LIST[16]; // Linedef flags
extern const char* const MSF_LIST[7]; // Sector flags
extern const char* const SSF_LIST[19]; // Sector special flags
extern const char *COLOR_ENUMS[];
extern const char *const POWERS_LIST[];
extern const char *const HUDITEMS_LIST[];

View file

@ -2215,6 +2215,18 @@ static int lib_pMobjTouchingSectorSpecial(lua_State *L)
return 1;
}
static int lib_pMobjTouchingSectorSpecialFlag(lua_State *L)
{
mobj_t *mo = *((mobj_t**)luaL_checkudata(L, 1, META_MOBJ));
sectorspecialflags_t flag = (INT32)luaL_checkinteger(L, 2);
//HUDSAFE
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
LUA_PushUserdata(L, P_MobjTouchingSectorSpecialFlag(mo, flag), META_SECTOR);
return 1;
}
static int lib_pPlayerTouchingSectorSpecial(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2228,6 +2240,18 @@ static int lib_pPlayerTouchingSectorSpecial(lua_State *L)
return 1;
}
static int lib_pPlayerTouchingSectorSpecialFlag(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
sectorspecialflags_t flag = (INT32)luaL_checkinteger(L, 2);
//HUDSAFE
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
LUA_PushUserdata(L, P_PlayerTouchingSectorSpecialFlag(player, flag), META_SECTOR);
return 1;
}
static int lib_pFindLowestFloorSurrounding(lua_State *L)
{
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
@ -4059,7 +4083,9 @@ static luaL_Reg lib[] = {
{"P_DoSuperTransformation",lib_pDoSuperTransformation},
{"P_ExplodeMissile",lib_pExplodeMissile},
{"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial},
{"P_MobjTouchingSectorSpecialFlag",lib_pMobjTouchingSectorSpecialFlag},
{"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial},
{"P_PlayerTouchingSectorSpecialFlag",lib_pPlayerTouchingSectorSpecialFlag},
{"P_FindLowestFloorSurrounding",lib_pFindLowestFloorSurrounding},
{"P_FindHighestFloorSurrounding",lib_pFindHighestFloorSurrounding},
{"P_FindNextHighestFloor",lib_pFindNextHighestFloor},

View file

@ -50,6 +50,7 @@ enum sector_e {
sector_fslope,
sector_cslope,
sector_flags,
sector_specialflags,
sector_friction,
sector_gravity,
};
@ -76,6 +77,7 @@ static const char *const sector_opt[] = {
"f_slope",
"c_slope",
"flags",
"specialflags",
"friction",
"gravity",
NULL};
@ -658,6 +660,9 @@ static int sector_get(lua_State *L)
case sector_flags: // flags
lua_pushinteger(L, sector->flags);
return 1;
case sector_specialflags: // specialflags
lua_pushinteger(L, sector->specialflags);
return 1;
case sector_friction: // friction
lua_pushinteger(L, sector->friction);
return 1;
@ -755,6 +760,9 @@ static int sector_set(lua_State *L)
sector->flags = luaL_checkinteger(L, 3);
CheckForReverseGravity |= (sector->flags & MSF_GRAVITYFLIP);
break;
case sector_specialflags:
sector->specialflags = luaL_checkinteger(L, 3);
break;
case sector_gravity:
sector->gravity = luaL_checkfixed(L, 3);
break;

View file

@ -763,6 +763,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// return;
{
UINT8 flagteam = (special->type == MT_REDFLAG) ? 1 : 2;
sectorspecialflags_t specialflag = (special->type == MT_REDFLAG) ? SSF_REDTEAMBASE : SSF_BLUETEAMBASE;
const char *flagtext;
char flagcolor;
char plname[MAXPLAYERNAME+4];
@ -792,7 +793,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->fuse = 1;
special->flags2 |= MF2_JUSTATTACKED;
if (!P_PlayerTouchingSectorSpecial(player, 4, 2 + flagteam))
if (!P_PlayerTouchingSectorSpecialFlag(player, specialflag))
{
CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80);

View file

@ -2699,14 +2699,14 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thing->player)
{
// If using type Section1:13, double the maxstep.
if (P_PlayerTouchingSectorSpecial(thing->player, 1, 13)
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 13)
// If using SSF_DOUBLESTEPUP, double the maxstep.
if (P_PlayerTouchingSectorSpecialFlag(thing->player, SSF_DOUBLESTEPUP)
|| (R_PointInSubsector(x, y)->sector->specialflags & SSF_DOUBLESTEPUP))
maxstep <<= 1;
// If using type Section1:14, no maxstep.
if (P_PlayerTouchingSectorSpecial(thing->player, 1, 14)
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)
// If using SSF_NOSTEPDOWN, no maxstep.
if (P_PlayerTouchingSectorSpecialFlag(thing->player, SSF_NOSTEPDOWN)
|| (R_PointInSubsector(x, y)->sector->specialflags & SSF_NOSTEPDOWN))
maxstep = 0;
// Don't 'step up' while springing,
@ -2717,12 +2717,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
}
else if (thing->flags & MF_PUSHABLE)
{
// If using type Section1:13, double the maxstep.
if (GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 13)
// If using SSF_DOUBLESTEPUP, double the maxstep.
if (R_PointInSubsector(x, y)->sector->specialflags & SSF_DOUBLESTEPUP)
maxstep <<= 1;
// If using type Section1:14, no maxstep.
if (GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)
// If using SSF_NOSTEPDOWN, no maxstep.
if (R_PointInSubsector(x, y)->sector->specialflags & SSF_NOSTEPDOWN)
maxstep = 0;
}

View file

@ -9738,7 +9738,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
break;
case MT_BLUEFLAG:
case MT_REDFLAG:
if (P_MobjTouchingSectorSpecial(mobj, 4, 2))
if (P_MobjTouchingSectorSpecialFlag(mobj, SSF_RETURNFLAG))
mobj->fuse = 1; // Return to base.
break;
case MT_SPINDUST: // Spindash dust

View file

@ -853,7 +853,8 @@ static void P_NetUnArchiveWaypoints(void)
#define SD_FLOORLIGHT 0x08
#define SD_CEILLIGHT 0x10
#define SD_FLAG 0x20
#define SD_GRAVITY 0x40
#define SD_SPECIALFLAG 0x40
#define SD_GRAVITY 0x80
#define LD_FLAG 0x01
#define LD_SPECIAL 0x02
@ -1041,6 +1042,8 @@ static void ArchiveSectors(void)
diff3 |= SD_CEILLIGHT;
if (ss->flags != spawnss->flags)
diff3 |= SD_FLAG;
if (ss->specialflags != spawnss->specialflags)
diff3 |= SD_SPECIALFLAG;
if (ss->gravity != spawnss->gravity)
diff3 |= SD_GRAVITY;
@ -1109,6 +1112,8 @@ static void ArchiveSectors(void)
}
if (diff3 & SD_FLAG)
WRITEUINT32(save_p, ss->flags);
if (diff3 & SD_SPECIALFLAG)
WRITEUINT32(save_p, ss->specialflags);
if (diff3 & SD_GRAVITY)
WRITEFIXED(save_p, ss->gravity);
if (diff & SD_FFLOORS)
@ -1217,6 +1222,8 @@ static void UnArchiveSectors(void)
sectors[i].flags = READUINT32(save_p);
CheckForReverseGravity |= (sectors[i].flags & MSF_GRAVITYFLIP);
}
if (diff3 & SD_SPECIALFLAG)
sectors[i].specialflags = READUINT32(save_p);
if (diff3 & SD_GRAVITY)
sectors[i].gravity = READFIXED(save_p);

View file

@ -1679,6 +1679,44 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val)
sectors[i].flags |= MSF_HEATWAVE;
else if (fastcmp(param, "noclipcamera") && fastcmp("true", val))
sectors[i].flags |= MSF_NOCLIPCAMERA;
else if (fastcmp(param, "outerspace") && fastcmp("true", val))
sectors[i].specialflags |= SSF_OUTERSPACE;
else if (fastcmp(param, "doublestepup") && fastcmp("true", val))
sectors[i].specialflags |= SSF_DOUBLESTEPUP;
else if (fastcmp(param, "nostepdown") && fastcmp("true", val))
sectors[i].specialflags |= SSF_NOSTEPDOWN;
else if (fastcmp(param, "windcurrent") && fastcmp("true", val))
sectors[i].specialflags |= SSF_WINDCURRENT;
else if (fastcmp(param, "conveyor") && fastcmp("true", val))
sectors[i].specialflags |= SSF_CONVEYOR;
else if (fastcmp(param, "speedpad") && fastcmp("true", val))
sectors[i].specialflags |= SSF_SPEEDPAD;
else if (fastcmp(param, "starpostactivator") && fastcmp("true", val))
sectors[i].specialflags |= SSF_STARPOSTACTIVATOR;
else if (fastcmp(param, "exit") && fastcmp("true", val))
sectors[i].specialflags |= SSF_EXIT;
else if (fastcmp(param, "specialstagepit") && fastcmp("true", val))
sectors[i].specialflags |= SSF_SPECIALSTAGEPIT;
else if (fastcmp(param, "returnflag") && fastcmp("true", val))
sectors[i].specialflags |= SSF_RETURNFLAG;
else if (fastcmp(param, "redteambase") && fastcmp("true", val))
sectors[i].specialflags |= SSF_REDTEAMBASE;
else if (fastcmp(param, "blueteambase") && fastcmp("true", val))
sectors[i].specialflags |= SSF_BLUETEAMBASE;
else if (fastcmp(param, "fan") && fastcmp("true", val))
sectors[i].specialflags |= SSF_FAN;
else if (fastcmp(param, "supertransform") && fastcmp("true", val))
sectors[i].specialflags |= SSF_SUPERTRANSFORM;
else if (fastcmp(param, "forcespin") && fastcmp("true", val))
sectors[i].specialflags |= SSF_FORCESPIN;
else if (fastcmp(param, "zoomtubestart") && fastcmp("true", val))
sectors[i].specialflags |= SSF_ZOOMTUBESTART;
else if (fastcmp(param, "zoomtubeend") && fastcmp("true", val))
sectors[i].specialflags |= SSF_ZOOMTUBEEND;
else if (fastcmp(param, "finishline") && fastcmp("true", val))
sectors[i].specialflags |= SSF_FINISHLINE;
else if (fastcmp(param, "ropehang") && fastcmp("true", val))
sectors[i].specialflags |= SSF_ROPEHANG;
else if (fastcmp(param, "friction"))
sectors[i].friction = atol(val);
else if (fastcmp(param, "gravity"))
@ -5021,8 +5059,72 @@ static void P_ConvertBinaryMap(void)
for (i = 0; i < numsectors; i++)
{
switch(GETSECSPECIAL(sectors[i].special, 1))
{
case 12: //Space countdown
sectors[i].specialflags |= SSF_OUTERSPACE;
break;
case 13: //Ramp sector
sectors[i].specialflags |= SSF_DOUBLESTEPUP;
break;
case 14: //Non-ramp sector
sectors[i].specialflags |= SSF_NOSTEPDOWN;
break;
default:
break;
}
switch(GETSECSPECIAL(sectors[i].special, 3))
{
case 2: //Wind/Current
sectors[i].specialflags |= SSF_WINDCURRENT;
break;
case 4: //Conveyor belt
sectors[i].specialflags |= SSF_CONVEYOR;
break;
case 5: //Speed pad
sectors[i].specialflags |= SSF_SPEEDPAD;
break;
default:
break;
}
switch(GETSECSPECIAL(sectors[i].special, 4))
{
case 1: //Star post activator
sectors[i].specialflags |= SSF_STARPOSTACTIVATOR;
break;
case 2: //Exit/Special Stage pit/Return flag
sectors[i].specialflags |= SSF_EXIT|SSF_SPECIALSTAGEPIT|SSF_RETURNFLAG;
break;
case 3: //Red team base
sectors[i].specialflags |= SSF_REDTEAMBASE;
break;
case 4: //Blue team base
sectors[i].specialflags |= SSF_BLUETEAMBASE;
break;
case 5: //Fan sector
sectors[i].specialflags |= SSF_FAN;
break;
case 6: //Super Sonic transform
sectors[i].specialflags |= SSF_SUPERTRANSFORM;
break;
case 7: //Force spin
sectors[i].specialflags |= SSF_FORCESPIN;
break;
case 8: //Zoom tube start
sectors[i].specialflags |= SSF_ZOOMTUBESTART;
break;
case 9: //Zoom tube end
sectors[i].specialflags |= SSF_ZOOMTUBEEND;
break;
case 10: //Circuit finish line
sectors[i].specialflags |= SSF_FINISHLINE;
break;
case 11: //Rope hang
sectors[i].specialflags |= SSF_ROPEHANG;
break;
case 12: //Intangible to the camera
sectors[i].flags |= MSF_NOCLIPCAMERA;
break;

View file

@ -3933,7 +3933,7 @@ boolean P_IsFlagAtBase(mobjtype_t flag)
{
thinker_t *think;
mobj_t *mo;
INT32 specialnum = (flag == MT_REDFLAG) ? 3 : 4;
sectorspecialflags_t specialflag = (flag == MT_REDFLAG) ? SSF_REDTEAMBASE : SSF_BLUETEAMBASE;
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
{
@ -3945,7 +3945,7 @@ boolean P_IsFlagAtBase(mobjtype_t flag)
if (mo->type != flag)
continue;
if (GETSECSPECIAL(mo->subsector->sector->special, 4) == specialnum)
if (mo->subsector->sector->specialflags & specialflag)
return true;
else if (mo->subsector->sector->ffloors) // Check the 3D floors
{
@ -3956,7 +3956,7 @@ boolean P_IsFlagAtBase(mobjtype_t flag)
if (!(rover->flags & FF_EXISTS))
continue;
if (GETSECSPECIAL(rover->master->frontsector->special, 4) != specialnum)
if (!(rover->master->frontsector->specialflags & specialflag))
continue;
if (!(mo->z <= P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector)
@ -4041,6 +4041,30 @@ static sector_t *P_MobjTouching3DFloorSpecial(mobj_t *mo, sector_t *sector, INT3
return NULL;
}
static sector_t *P_MobjTouching3DFloorSpecialFlag(mobj_t *mo, sector_t *sector, sectorspecialflags_t flag)
{
ffloor_t *rover;
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->master->frontsector->specialflags & flag))
continue;
if (!(rover->flags & FF_EXISTS))
continue;
if (!P_IsMobjTouching3DFloor(mo, rover, sector))
continue;
// This FOF has the special we're looking for, but are we allowed to touch it?
if (sector == mo->subsector->sector
|| (rover->master->frontsector->flags & MSF_TRIGGERSPECIAL_TOUCH))
return rover->master->frontsector;
}
return NULL;
}
static sector_t *P_MobjTouchingPolyobjSpecial(mobj_t *mo, INT32 section, INT32 number)
{
polyobj_t *po;
@ -4073,6 +4097,38 @@ static sector_t *P_MobjTouchingPolyobjSpecial(mobj_t *mo, INT32 section, INT32 n
return NULL;
}
static sector_t *P_MobjTouchingPolyobjSpecialFlag(mobj_t *mo, sectorspecialflags_t flag)
{
polyobj_t *po;
sector_t *polysec;
boolean touching = false;
boolean inside = false;
for (po = mo->subsector->polyList; po; po = (polyobj_t *)(po->link.next))
{
if (po->flags & POF_NOSPECIALS)
continue;
polysec = po->lines[0]->backsector;
if (!(polysec->specialflags & flag))
continue;
touching = (polysec->flags & MSF_TRIGGERSPECIAL_TOUCH) && P_MobjTouchingPolyobj(po, mo);
inside = P_MobjInsidePolyobj(po, mo);
if (!(inside || touching))
continue;
if (!P_IsMobjTouchingPolyobj(mo, po, polysec))
continue;
return polysec;
}
return NULL;
}
sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number)
{
msecnode_t *node;
@ -4101,7 +4157,42 @@ sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number)
if (!(node->m_sector->flags & MSF_TRIGGERSPECIAL_TOUCH))
continue;
if (GETSECSPECIAL(mo->subsector->sector->special, section) == number)
if (GETSECSPECIAL(node->m_sector->special, section) == number)
return node->m_sector;
}
return NULL;
}
sector_t *P_MobjTouchingSectorSpecialFlag(mobj_t *mo, sectorspecialflags_t flag)
{
msecnode_t *node;
sector_t *result;
result = P_MobjTouching3DFloorSpecialFlag(mo, mo->subsector->sector, flag);
if (result)
return result;
result = P_MobjTouchingPolyobjSpecialFlag(mo, flag);
if (result)
return result;
if (mo->subsector->sector->specialflags & flag)
return mo->subsector->sector;
for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (node->m_sector == mo->subsector->sector) // Don't duplicate
continue;
result = P_MobjTouching3DFloorSpecialFlag(mo, node->m_sector, flag);
if (result)
return result;
if (!(node->m_sector->flags & MSF_TRIGGERSPECIAL_TOUCH))
continue;
if (node->m_sector->specialflags & flag)
return node->m_sector;
}
@ -4127,6 +4218,14 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
return P_MobjTouchingSectorSpecial(player->mo, section, number);
}
sector_t *P_PlayerTouchingSectorSpecialFlag(player_t *player, sectorspecialflags_t flag)
{
if (!player->mo)
return NULL;
return P_MobjTouchingSectorSpecialFlag(player->mo, flag);
}
static sector_t *P_Check3DFloorTriggers(player_t *player, sector_t *sector, line_t *sourceline)
{
ffloor_t *rover;
@ -4371,7 +4470,7 @@ static void P_ProcessSpeedPad(player_t *player, sector_t *sector, sector_t *rove
if (lineindex == -1)
{
CONS_Debug(DBG_GAMELOGIC, "ERROR: Sector special %d missing line special #4.\n", sector->special);
CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad missing line special #4.\n");
return;
}
@ -4425,7 +4524,27 @@ static void P_ProcessSpeedPad(player_t *player, sector_t *sector, sector_t *rove
S_StartSound(player->mo, sfxnum);
}
static void P_ProcessExitSector(player_t *player, boolean isTouching, mtag_t sectag)
static void P_ProcessSpecialStagePit(player_t* player)
{
if (!(gametyperules & GTR_ALLOWEXIT))
return;
if (player->bot)
return;
if (!G_IsSpecialStage(gamemap))
return;
if (maptol & TOL_NIGHTS)
return;
if (player->nightstime <= 6)
return;
player->nightstime = 6; // Just let P_Ticker take care of the rest.
}
static void P_ProcessExitSector(player_t *player, mtag_t sectag)
{
INT32 lineindex;
@ -4435,13 +4554,6 @@ static void P_ProcessExitSector(player_t *player, boolean isTouching, mtag_t sec
if (player->bot)
return;
if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))
{
if (player->nightstime > 6 && isTouching)
player->nightstime = 6; // Just let P_Ticker take care of the rest.
return;
}
// Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c)
P_DoPlayerFinish(player);
@ -4515,7 +4627,7 @@ static void P_ProcessTeamBase(player_t *player, boolean redteam)
P_AddPlayerScore(player, 250);
}
static void P_ProcessZoomTube(player_t *player, sector_t *sector, mtag_t sectag, boolean end)
static void P_ProcessZoomTube(player_t *player, mtag_t sectag, boolean end)
{
INT32 sequence;
fixed_t speed;
@ -4534,7 +4646,7 @@ static void P_ProcessZoomTube(player_t *player, sector_t *sector, mtag_t sectag,
if (lineindex == -1)
{
CONS_Debug(DBG_GAMELOGIC, "ERROR: Sector special %d missing line special #3.\n", sector->special);
CONS_Debug(DBG_GAMELOGIC, "ERROR: Zoom tube missing line special #3.\n");
return;
}
@ -4630,7 +4742,7 @@ static void P_ProcessFinishLine(player_t *player)
}
}
static void P_ProcessRopeHang(player_t *player, sector_t *sector, mtag_t sectag)
static void P_ProcessRopeHang(player_t *player, mtag_t sectag)
{
INT32 sequence;
fixed_t speed;
@ -4668,7 +4780,7 @@ static void P_ProcessRopeHang(player_t *player, sector_t *sector, mtag_t sectag)
if (lineindex == -1)
{
CONS_Debug(DBG_GAMELOGIC, "ERROR: Sector special %d missing line special #11.\n", sector->special);
CONS_Debug(DBG_GAMELOGIC, "ERROR: Rope hang missing line special #11.\n");
return;
}
@ -4801,18 +4913,13 @@ static void P_ProcessRopeHang(player_t *player, sector_t *sector, mtag_t sectag)
*/
void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector)
{
INT32 section1, section2, section3, section4;
INT32 section1, section2;
mtag_t sectag = Tag_FGet(&sector->tags);
boolean isTouching;
if (!sector->special)
if (!sector->special && sector->specialflags == 0)
return;
section1 = GETSECSPECIAL(sector->special, 1);
section2 = GETSECSPECIAL(sector->special, 2);
section3 = GETSECSPECIAL(sector->special, 3);
section4 = GETSECSPECIAL(sector->special, 4);
// Ignore spectators
if (player->spectator)
return;
@ -4823,12 +4930,74 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
if (player->playerstate != PST_LIVE)
return;
// Conveyor stuff
if (section3 == 2 || section3 == 4)
player->onconveyor = section3;
isTouching = roversector || P_IsMobjTouchingSectorPlane(player->mo, sector);
if (sector->specialflags & SSF_OUTERSPACE)
{
if (!(player->powers[pw_shield] & SH_PROTECTWATER) && !player->powers[pw_spacetime])
player->powers[pw_spacetime] = spacetimetics + 1;
}
if (sector->specialflags & SSF_WINDCURRENT)
player->onconveyor = 2;
if (sector->specialflags & SSF_CONVEYOR)
player->onconveyor = 4;
if ((sector->specialflags & SSF_SPEEDPAD) && isTouching)
P_ProcessSpeedPad(player, sector, roversector, sectag);
if (sector->specialflags & SSF_STARPOSTACTIVATOR)
{
mobj_t *post = P_GetObjectTypeInSectorNum(MT_STARPOST, sector - sectors);
if (post)
P_TouchStarPost(post, player, false);
}
if (sector->specialflags & SSF_EXIT)
P_ProcessExitSector(player, sectag);
if ((sector->specialflags & SSF_SPECIALSTAGEPIT) && isTouching)
P_ProcessSpecialStagePit(player);
if ((sector->specialflags & SSF_REDTEAMBASE) && isTouching)
P_ProcessTeamBase(player, true);
if ((sector->specialflags & SSF_BLUETEAMBASE) && isTouching)
P_ProcessTeamBase(player, false);
if (sector->specialflags & SSF_FAN)
{
player->mo->momz += mobjinfo[MT_FAN].mass/4;
if (player->mo->momz > mobjinfo[MT_FAN].mass)
player->mo->momz = mobjinfo[MT_FAN].mass;
P_ResetPlayer(player);
if (player->panim != PA_FALL)
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
}
if (sector->specialflags & SSF_SUPERTRANSFORM)
{
if (player->mo->health > 0 && !player->bot && (player->charflags & SF_SUPER) && !player->powers[pw_super] && ALL7EMERALDS(emeralds))
P_DoSuperTransformation(player, true);
}
if ((sector->specialflags & SSF_FORCESPIN) && isTouching)
{
if (!(player->pflags & PF_SPINNING))
{
player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartAttackSound(player->mo, sfx_spin);
if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale)
&& abs(player->rmomy) < FixedMul(5*FRACUNIT, player->mo->scale))
P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale));
}
}
if (sector->specialflags & SSF_ZOOMTUBESTART)
P_ProcessZoomTube(player, sectag, false);
if (sector->specialflags & SSF_ZOOMTUBEEND)
P_ProcessZoomTube(player, sectag, true);
if (sector->specialflags & SSF_FINISHLINE)
P_ProcessFinishLine(player);
if ((sector->specialflags & SSF_ROPEHANG) && isTouching)
P_ProcessRopeHang(player, sectag);
section1 = GETSECSPECIAL(sector->special, 1);
section2 = GETSECSPECIAL(sector->special, 2);
switch (section1)
{
case 1: // Damage (Generic)
@ -4891,20 +5060,10 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
P_SpecialStageDamage(player, NULL, NULL);
break;
case 12: // Space Countdown
if (!(player->powers[pw_shield] & SH_PROTECTWATER) && !player->powers[pw_spacetime])
player->powers[pw_spacetime] = spacetimetics + 1;
break;
case 13: // Ramp Sector (Increase step-up/down)
case 14: // Non-Ramp Sector (Don't step-down)
case 15: // Bouncy FOF (deprecated)
break;
}
switch (section2)
{
case 1: // Trigger Linedef Exec (Pushable Objects)
break;
case 2: // Linedef executor requires all players present+doesn't require touching floor
case 3: // Linedef executor requires all players present
if (!P_DoAllPlayersTrigger(sectag))
@ -4919,111 +5078,10 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
if (!player->bot)
P_LinedefExecute(sectag, player->mo, sector);
break;
case 8: // Tells pushable things to check FOFs
break;
case 9: // Egg trap capsule
if (!udmf && roversector)
P_ProcessEggCapsule(player, sector);
break;
case 10: // Special Stage Time/Rings
case 11: // Custom Gravity
case 12: // Lua sector special
break;
}
switch (section3)
{
case 1: // Unused
case 2: // Wind/Current
case 3: // Unused
case 4: // Conveyor Belt
break;
case 5: // Speed pad
if (isTouching)
P_ProcessSpeedPad(player, sector, roversector, sectag);
break;
case 6: // Unused
case 7: // Unused
case 8: // Unused
case 9: // Unused
case 10: // Unused
case 11: // Unused
case 12: // Unused
case 13: // Unused
case 14: // Unused
case 15: // Unused
break;
}
switch (section4)
{
case 1: // Starpost Activator
{
mobj_t *post = P_GetObjectTypeInSectorNum(MT_STARPOST, sector - sectors);
if (!post)
break;
P_TouchStarPost(post, player, false);
break;
}
case 2: // Special stage GOAL sector / Exit Sector / CTF Flag Return
P_ProcessExitSector(player, isTouching, sectag);
break;
case 3: // Red Team's Base
if (isTouching)
P_ProcessTeamBase(player, true);
break;
case 4: // Blue Team's Base
if (isTouching)
P_ProcessTeamBase(player, false);
break;
case 5: // Fan sector
player->mo->momz += mobjinfo[MT_FAN].mass/4;
if (player->mo->momz > mobjinfo[MT_FAN].mass)
player->mo->momz = mobjinfo[MT_FAN].mass;
P_ResetPlayer(player);
if (player->panim != PA_FALL)
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
break;
case 6: // Super Sonic transformer
if (player->mo->health > 0 && !player->bot && (player->charflags & SF_SUPER) && !player->powers[pw_super] && ALL7EMERALDS(emeralds))
P_DoSuperTransformation(player, true);
break;
case 7: // Make player spin
if (!isTouching)
break;
if (!(player->pflags & PF_SPINNING))
{
player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartAttackSound(player->mo, sfx_spin);
if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale)
&& abs(player->rmomy) < FixedMul(5*FRACUNIT, player->mo->scale))
P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale));
}
break;
case 8: // Zoom Tube Start
P_ProcessZoomTube(player, sector, sectag, false);
break;
case 9: // Zoom Tube End
P_ProcessZoomTube(player, sector, sectag, true);
break;
case 10: // Finish Line
P_ProcessFinishLine(player);
break;
case 11: // Rope hang
if (isTouching)
P_ProcessRopeHang(player, sector, sectag);
break;
case 12: // Unused
case 13: // Unused
case 14: // Unused
case 15: // Unused
break;
}
}
@ -5042,7 +5100,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!rover->master->frontsector->special)
if (!rover->master->frontsector->special && rover->master->frontsector->specialflags == 0)
continue;
if (!(rover->flags & FF_EXISTS))
@ -5076,7 +5134,7 @@ static void P_PlayerOnSpecialPolyobj(player_t *player)
polysec = po->lines[0]->backsector;
if (!polysec->special)
if (!polysec->special && polysec->specialflags == 0)
continue;
touching = (polysec->flags & MSF_TRIGGERSPECIAL_TOUCH) && P_MobjTouchingPolyobj(po, player->mo);
@ -6025,6 +6083,12 @@ void P_SpawnSpecials(boolean fromnetsave)
{
CheckForReverseGravity |= (sector->flags & MSF_GRAVITYFLIP);
if (sector->specialflags & SSF_FINISHLINE)
{
if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE)
circuitmap = true;
}
if (!sector->special)
continue;
@ -6063,15 +6127,6 @@ void P_SpawnSpecials(boolean fromnetsave)
gravity = sector->floorheight/1000;
break;
}
// Process Section 4
switch(GETSECSPECIAL(sector->special, 4))
{
case 10: // Circuit finish line
if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE)
circuitmap = true;
break;
}
}
P_SpawnScrollers(); // Add generalized scrollers
@ -8332,17 +8387,17 @@ void T_Pusher(pusher_t *p)
sec = sectors + p->affectee;
// Be sure the special sector type is still turned on. If so, proceed.
// Else, bail out; the sector type has been changed on us.
// Be sure the sector special flag is still turned on. If so, proceed.
// Else, bail out; the flag has been changed on us.
if (p->roverpusher)
{
referrer = &sectors[p->referrer];
if (GETSECSPECIAL(referrer->special, 3) != 2)
if (!(referrer->specialflags & SSF_WINDCURRENT))
return;
}
else if (GETSECSPECIAL(sec->special, 3) != 2)
else if (!(sec->specialflags & SSF_WINDCURRENT))
return;
// For constant pushers (wind/current) there are 3 situations:

View file

@ -480,7 +480,9 @@ void P_SpawnSpecials(boolean fromnetsave);
// every tic
void P_UpdateSpecials(void);
sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number);
sector_t *P_MobjTouchingSectorSpecialFlag(mobj_t *mo, sectorspecialflags_t flag);
sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number);
sector_t *P_PlayerTouchingSectorSpecialFlag(player_t *player, sectorspecialflags_t flag);
void P_PlayerInSpecialSector(player_t *player);
void P_CheckPushableTrigger(mobj_t *mobj, sector_t *sec);
void P_CheckMobjTrigger(mobj_t *mobj);

View file

@ -2166,13 +2166,12 @@ void P_DoPlayerExit(player_t *player)
P_RestoreMusic(player);
}
#define SPACESPECIAL 12
boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
{
sector_t *sector = mo->subsector->sector;
fixed_t topheight, bottomheight;
if (GETSECSPECIAL(sector->special, 1) == SPACESPECIAL)
if (sector->specialflags & SSF_OUTERSPACE)
return true;
if (sector->ffloors)
@ -2184,7 +2183,7 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
if (!(rover->flags & FF_EXISTS))
continue;
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
if (!(rover->master->frontsector->specialflags & SSF_OUTERSPACE))
continue;
topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y);
bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y);
@ -4678,7 +4677,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH)
&& player->speed < 5*player->mo->scale && canstand)
{
if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player)))
if ((player->mo->subsector->sector->specialflags & SSF_FORCESPIN) || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player)))
P_InstaThrust(player->mo, player->mo->angle, 10*player->mo->scale);
else
{

View file

@ -289,6 +289,28 @@ typedef enum
MSF_NOCLIPCAMERA = 1<<7,
} sectorflags_t;
typedef enum
{
SSF_OUTERSPACE = 1,
SSF_DOUBLESTEPUP = 1<<1,
SSF_NOSTEPDOWN = 1<<2,
SSF_WINDCURRENT = 1<<3,
SSF_CONVEYOR = 1<<4,
SSF_SPEEDPAD = 1<<5,
SSF_STARPOSTACTIVATOR = 1<<6,
SSF_EXIT = 1<<7,
SSF_SPECIALSTAGEPIT = 1<<8,
SSF_RETURNFLAG = 1<<9,
SSF_REDTEAMBASE = 1<<10,
SSF_BLUETEAMBASE = 1<<11,
SSF_FAN = 1<<12,
SSF_SUPERTRANSFORM = 1<<13,
SSF_FORCESPIN = 1<<14,
SSF_ZOOMTUBESTART = 1<<15,
SSF_ZOOMTUBEEND = 1<<16,
SSF_FINISHLINE = 1<<17,
SSF_ROPEHANG = 1<<18,
} sectorspecialflags_t;
typedef enum
{
@ -371,6 +393,7 @@ typedef struct sector_s
fixed_t gravity; // per-sector gravity factor
fixed_t *gravityptr; // For binary format: Read gravity from floor height of master sector
sectorflags_t flags;
sectorspecialflags_t specialflags;
INT32 friction;