Added P_MobjTouchingTeamBase, P_TeamHasFlagAtBase, sector.teambase

This commit is contained in:
Lactozilla 2023-08-06 21:13:00 -03:00
parent 0021fd1680
commit f6f5dcef1c
9 changed files with 312 additions and 67 deletions

View file

@ -3947,7 +3947,7 @@ UINT8 G_GetTeamFromTeamFlag(UINT32 flag)
{
for (UINT16 i = 1; i < teamsingame; i++)
{
UINT32 otherflag = 1 << (i - 1);
UINT32 otherflag = teams[G_GetTeam(i)].flag;
if (flag == otherflag)
return i;
}
@ -3961,7 +3961,7 @@ UINT8 G_GetTeamListFromTeamFlags(UINT8 *teamlist, UINT32 flags)
for (UINT16 i = 1; i < teamsingame; i++)
{
UINT32 otherflag = 1 << (i - 1);
UINT32 otherflag = teams[G_GetTeam(i)].flag;
if ((flags & otherflag) != 0)
{
teamlist[count++] = i;

View file

@ -2340,6 +2340,19 @@ static int lib_pPlayerTouchingSectorSpecialFlag(lua_State *L)
return 1;
}
static int lib_pMobjTouchingTeamBase(lua_State *L)
{
mobj_t *mo = *((mobj_t**)luaL_checkudata(L, 1, META_MOBJ));
INT32 team = (INT32)luaL_checkinteger(L, 2);
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
if (team <= 0 || team >= teamsingame)
luaL_error(L, "team index %d out of range (1 - %d)", team, teamsingame-1);
LUA_PushUserdata(L, P_MobjTouchingTeamBase(mo, team), META_SECTOR);
return 1;
}
static int lib_pFindLowestFloorSurrounding(lua_State *L)
{
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
@ -2481,11 +2494,29 @@ static int lib_pFadeLight(lua_State *L)
static int lib_pIsFlagAtBase(lua_State *L)
{
mobjtype_t flag = luaL_checkinteger(L, 1);
//HUDSAFE
INLEVEL
if (flag >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", flag, NUMMOBJTYPES-1);
lua_pushboolean(L, P_IsFlagAtBase(flag));
for (UINT8 i = 1; i < teamsingame; i++)
{
UINT8 team = G_GetTeam(i);
if (teams[team].flag_mobj_type == flag)
{
lua_pushboolean(L, P_TeamHasFlagAtBase(team));
return 1;
}
}
lua_pushboolean(L, false);
return 1;
}
static int lib_pTeamHasFlagAtBase(lua_State *L)
{
INT32 team = luaL_checkinteger(L, 1);
INLEVEL
if (team <= 0 || team >= teamsingame)
luaL_error(L, "team index %d out of range (1 - %d)", team, teamsingame-1);
lua_pushboolean(L, P_TeamHasFlagAtBase(team));
return 1;
}
@ -4281,6 +4312,7 @@ static luaL_Reg lib[] = {
{"P_MobjTouchingSectorSpecialFlag",lib_pMobjTouchingSectorSpecialFlag},
{"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial},
{"P_PlayerTouchingSectorSpecialFlag",lib_pPlayerTouchingSectorSpecialFlag},
{"P_MobjTouchingTeamBase",lib_pMobjTouchingTeamBase},
{"P_FindLowestFloorSurrounding",lib_pFindLowestFloorSurrounding},
{"P_FindHighestFloorSurrounding",lib_pFindHighestFloorSurrounding},
{"P_FindNextHighestFloor",lib_pFindNextHighestFloor},
@ -4293,6 +4325,7 @@ static luaL_Reg lib[] = {
{"P_SpawnLightningFlash",lib_pSpawnLightningFlash},
{"P_FadeLight",lib_pFadeLight},
{"P_IsFlagAtBase",lib_pIsFlagAtBase},
{"P_TeamHasFlagAtBase",lib_pTeamHasFlagAtBase},
{"P_SetupLevelSky",lib_pSetupLevelSky},
{"P_SetSkyboxMobj",lib_pSetSkyboxMobj},
{"P_StartQuake",lib_pStartQuake},

View file

@ -60,6 +60,7 @@ enum sector_e {
sector_flags,
sector_specialflags,
sector_damagetype,
sector_teambase,
sector_triggertag,
sector_triggerer,
sector_friction,
@ -98,6 +99,7 @@ static const char *const sector_opt[] = {
"flags",
"specialflags",
"damagetype",
"teambase",
"triggertag",
"triggerer",
"friction",
@ -760,6 +762,9 @@ static int sector_get(lua_State *L)
case sector_damagetype: // damagetype
lua_pushinteger(L, (UINT8)sector->damagetype);
return 1;
case sector_teambase: // teambase
lua_pushinteger(L, (UINT8)sector->teambase);
return 1;
case sector_triggertag: // triggertag
lua_pushinteger(L, (INT16)sector->triggertag);
return 1;
@ -893,6 +898,9 @@ static int sector_set(lua_State *L)
case sector_damagetype:
sector->damagetype = (UINT8)luaL_checkinteger(L, 3);
break;
case sector_teambase:
sector->teambase = (UINT8)luaL_checkinteger(L, 3);
break;
case sector_triggertag:
sector->triggertag = (INT16)luaL_checkinteger(L, 3);
break;

View file

@ -566,7 +566,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->extravalue1 > TEAM_NONE && special->extravalue1 < numteams)
{
UINT8 flagteam = special->extravalue1;
sectorspecialflags_t specialflag = flagteam == TEAM_RED ? SSF_REDTEAMBASE : SSF_BLUETEAMBASE;
const char *flagtext;
const char *flagcolor;
char plname[MAXPLAYERNAME+4];
@ -588,7 +587,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->fuse = 1;
special->flags2 |= MF2_JUSTATTACKED;
if (!P_PlayerTouchingSectorSpecialFlag(player, specialflag))
if (!P_PlayerTouchingTeamBase(player, flagteam))
CONS_Printf(M_GetText("%s returned the %s%s%c to base.\n"), plname, flagcolor, flagtext, 0x80);
}
return;
@ -4381,14 +4380,28 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
if (!player->gotflag)
return;
for (UINT8 i = 1; i < numteams; i++)
UINT8 totalcaptured = 0;
UINT8 teamscaptured[MAXTEAMS];
memset(teamscaptured, 0, sizeof(teamscaptured));
for (UINT8 i = 1; i < teamsingame; i++)
{
UINT8 team = G_GetTeam(i);
UINT32 flagflag = 1 << (team - 1);
if (!(player->gotflag & flagflag))
UINT8 otherteam = G_GetTeam(i);
UINT32 flagflag = teams[otherteam].flag;
if (!(player->gotflag & flagflag) || otherteam == player->ctfteam)
continue;
if (teams[otherteam].flag_mobj_type == 0)
continue;
mobj_t *flag = P_SpawnTeamFlag(team, player->mo->x, player->mo->y, player->mo->z);
teamscaptured[totalcaptured++] = otherteam;
}
for (UINT8 i = 0; i < totalcaptured; i++)
{
UINT8 otherteam = teamscaptured[i];
mobj_t *flag = P_SpawnTeamFlag(otherteam, player->mo->x, player->mo->y, player->mo->z);
if (flag == NULL)
continue;
@ -4402,7 +4415,12 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
P_InstaThrust(flag, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale));
else
{
angle_t fa = P_RandomByte()*FINEANGLES/256;
angle_t fa;
if (totalcaptured == 1)
fa = P_RandomByte()*FINEANGLES/256;
else
fa = ((255 / totalcaptured) * i) * FINEANGLES/256;
flag->momx = FixedMul(FINECOSINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
@ -4412,37 +4430,34 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
if (player->mo->eflags & MFE_VERTICALFLIP)
flag->momz = -flag->momz;
flag->spawnpoint = flagpoints[team];
flag->spawnpoint = flagpoints[otherteam];
flag->fuse = cv_flagtime.value * TICRATE;
P_SetTarget(&flag->target, player->mo);
// Take out the flag from the player
player->gotflag &= ~teams[otherteam].flag;
// Flag text
{
char plname[MAXPLAYERNAME+4];
const char *flagtext;
const char *flagcolor;
char plname[MAXPLAYERNAME+4];
snprintf(plname, sizeof(plname), "%s%s%s",
CTFTEAMCODE(player),
player_names[player - players],
CTFTEAMENDCODE(player));
snprintf(plname, sizeof(plname), "%s%s%s",
CTFTEAMCODE(player),
player_names[player - players],
CTFTEAMENDCODE(player));
flagtext = G_GetTeamFlagName(team);
flagcolor = GetChatColorForSkincolor(G_GetTeamColor(team));
const char *flagtext = G_GetTeamFlagName(otherteam);
const char *flagcolor = GetChatColorForSkincolor(G_GetTeamColor(otherteam));
if (toss)
CONS_Printf(M_GetText("%s tossed the %s%s%c.\n"), plname, flagcolor, flagtext, 0x80);
else
CONS_Printf(M_GetText("%s dropped the %s%s%c.\n"), plname, flagcolor, flagtext, 0x80);
}
if (toss)
CONS_Printf(M_GetText("%s tossed the %s%s%c.\n"), plname, flagcolor, flagtext, 0x80);
else
CONS_Printf(M_GetText("%s dropped the %s%s%c.\n"), plname, flagcolor, flagtext, 0x80);
// Pointers set for displaying time value and for consistency restoration.
P_SetTarget(&flagmobjs[team], flag);
P_SetTarget(&flagmobjs[otherteam], flag);
}
player->gotflag = 0;
if (toss)
player->tossdelay = 2*TICRATE;
}

View file

@ -867,6 +867,7 @@ static void P_NetUnArchiveWaypoints(void)
#define SD_TRIGGERTAG 0x02
#define SD_TRIGGERER 0x04
#define SD_GRAVITY 0x08
#define SD_TEAMBASE 0x10
#define LD_FLAG 0x01
#define LD_SPECIAL 0x02
@ -1064,6 +1065,8 @@ static void ArchiveSectors(void)
diff4 |= SD_TRIGGERER;
if (ss->gravity != spawnss->gravity)
diff4 |= SD_GRAVITY;
if (ss->teambase != spawnss->teambase)
diff4 |= SD_TEAMBASE;
if (ss->ffloors && CheckFFloorDiff(ss))
diff |= SD_FFLOORS;
@ -1145,6 +1148,8 @@ static void ArchiveSectors(void)
WRITEUINT8(save_p, ss->triggerer);
if (diff4 & SD_GRAVITY)
WRITEFIXED(save_p, ss->gravity);
if (diff4 & SD_TEAMBASE)
WRITEUINT8(save_p, ss->teambase);
if (diff & SD_FFLOORS)
ArchiveFFloors(ss);
}
@ -1265,6 +1270,8 @@ static void UnArchiveSectors(void)
sectors[i].triggerer = READUINT8(save_p);
if (diff4 & SD_GRAVITY)
sectors[i].gravity = READFIXED(save_p);
if (diff4 & SD_TEAMBASE)
sectors[i].teambase = READUINT8(save_p);
if (diff & SD_FFLOORS)
UnArchiveFFloors(&sectors[i]);

View file

@ -1801,9 +1801,28 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char
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;
sectors[i].teambase = G_GetTeam(TEAM_RED);
}
else if (fastcmp(param, "blueteambase") && fastcmp("true", val))
{
sectors[i].specialflags |= SSF_BLUETEAMBASE;
sectors[i].teambase = G_GetTeam(TEAM_BLUE);
}
else if (fastcmp(param, "teambase"))
{
sectors[i].teambase = TEAM_NONE;
for (UINT8 j = 0; j < numteams; j++)
{
if (fastcmp(val, teamnames[j]))
{
sectors[j].teambase = j;
break;
}
}
}
else if (fastcmp(param, "fan") && fastcmp("true", val))
sectors[i].specialflags |= SSF_FAN;
else if (fastcmp(param, "supertransform") && fastcmp("true", val))
@ -2711,6 +2730,22 @@ static void P_WriteTextmap(void)
fprintf(f, "redteambase = true;\n");
if (wsectors[i].specialflags & SSF_BLUETEAMBASE)
fprintf(f, "blueteambase = true;\n");
if (wsectors[i].teambase != TEAM_NONE && (wsectors[i].specialflags & (SSF_REDTEAMBASE | SSF_BLUETEAMBASE)) == 0)
{
// We DON'T write the teambase if the sector has (SSF_REDTEAMBASE | SSF_BLUETEAMBASE) because
// these flags get the team bases for the current gametype's team 1 and team 2, rather than the
// actual teams TEAM_RED and TEAM_BLUE.
UINT8 team = wsectors[i].teambase;
if (team != TEAM_NONE && team < numteams)
{
char *teambase = Z_StrDup(teamnames[team]);
strlwr(teambase);
fprintf(f, "teambase = \"%s\";\n", teambase);
Z_Free(teambase);
}
else
fprintf(f, "teambase = \"%s\";\n", "unknown");
}
if (wsectors[i].specialflags & SSF_FAN)
fprintf(f, "fan = true;\n");
if (wsectors[i].specialflags & SSF_SUPERTRANSFORM)
@ -6201,9 +6236,11 @@ static void P_ConvertBinarySectorTypes(void)
break;
case 3: //Red team base
sectors[i].specialflags |= SSF_REDTEAMBASE;
sectors[i].teambase = G_GetTeam(TEAM_RED);
break;
case 4: //Blue team base
sectors[i].specialflags |= SSF_BLUETEAMBASE;
sectors[i].teambase = G_GetTeam(TEAM_BLUE);
break;
case 5: //Fan sector
sectors[i].specialflags |= SSF_FAN;

View file

@ -3941,15 +3941,18 @@ void P_SetupSignExit(player_t *player)
}
//
// P_IsFlagAtBase
// P_TeamHasFlagAtBase
//
// Checks to see if a flag is at its base.
// Checks to see if a team has its flag at its base.
//
boolean P_IsFlagAtBase(mobjtype_t flag)
boolean P_TeamHasFlagAtBase(UINT8 team)
{
if (team == TEAM_NONE || team >= teamsingame)
return false;
thinker_t *think;
mobj_t *mo;
sectorspecialflags_t specialflag = (flag == teams[TEAM_RED].flag_mobj_type) ? SSF_REDTEAMBASE : SSF_BLUETEAMBASE;
mobjtype_t flag = teams[team].flag_mobj_type;
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
{
@ -3961,7 +3964,7 @@ boolean P_IsFlagAtBase(mobjtype_t flag)
if (mo->type != flag)
continue;
if (mo->subsector->sector->specialflags & specialflag)
if (mo->subsector->sector->teambase == team)
return true;
else if (mo->subsector->sector->ffloors) // Check the 3D floors
{
@ -3972,7 +3975,7 @@ boolean P_IsFlagAtBase(mobjtype_t flag)
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->master->frontsector->specialflags & specialflag))
if (rover->master->frontsector->teambase != team)
continue;
if (!(mo->z <= P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector)
@ -4238,6 +4241,97 @@ sector_t *P_MobjTouchingSectorSpecialFlag(mobj_t *mo, sectorspecialflags_t flag)
return NULL;
}
static sector_t *P_MobjTouching3DFloorTeamBase(mobj_t *mo, sector_t *sector, UINT8 team)
{
ffloor_t *rover;
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (rover->master->frontsector->teambase != team)
continue;
if (!(rover->fofflags & FOF_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_MobjTouchingPolyobjTeamBase(mobj_t *mo, UINT8 team)
{
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->teambase != team)
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_MobjTouchingTeamBase(mobj_t *mo, UINT8 team)
{
msecnode_t *node;
sector_t *result;
result = P_MobjTouching3DFloorTeamBase(mo, mo->subsector->sector, team);
if (result)
return result;
result = P_MobjTouchingPolyobjTeamBase(mo, team);
if (result)
return result;
if (mo->subsector->sector->teambase == team)
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_MobjTouching3DFloorTeamBase(mo, node->m_sector, team);
if (result)
return result;
if (!(node->m_sector->flags & MSF_TRIGGERSPECIAL_TOUCH))
continue;
if (node->m_sector->teambase == team)
return node->m_sector;
}
return NULL;
}
//
// P_PlayerTouchingSectorSpecial
//
@ -4265,6 +4359,14 @@ sector_t *P_PlayerTouchingSectorSpecialFlag(player_t *player, sectorspecialflags
return P_MobjTouchingSectorSpecialFlag(player->mo, flag);
}
sector_t *P_PlayerTouchingTeamBase(player_t *player, UINT8 base)
{
if (!player->mo)
return NULL;
return P_MobjTouchingTeamBase(player->mo, base);
}
static sector_t *P_CheckPlayer3DFloorTrigger(player_t *player, sector_t *sector, line_t *sourceline)
{
ffloor_t *rover;
@ -4637,48 +4739,90 @@ static void P_ProcessExitSector(player_t *player, mtag_t sectag)
static void P_ProcessTeamBase(player_t *player, UINT8 team)
{
mobj_t *mo;
if (team == TEAM_NONE || team >= teamsingame)
return;
if (!(gametyperules & GTR_TEAMFLAGS))
return;
// Make sure the team still has their own flag at their base so they can score.
if (!P_TeamHasFlagAtBase(team))
return;
if (!P_IsObjectOnGround(player->mo))
return;
if (player->ctfteam != team)
if (!player->gotflag || player->ctfteam != team)
return;
UINT8 otherteam = team == TEAM_RED ? TEAM_BLUE : TEAM_RED;
UINT32 teamflag = teams[otherteam].flag;
UINT8 totalcaptured = 0;
UINT8 teamscaptured[MAXTEAMS];
if (!(player->gotflag & teamflag))
return;
memset(teamscaptured, 0, sizeof(teamscaptured));
// Make sure the team still has their own
// flag at their base so they can score.
if (!P_IsFlagAtBase(teams[team].flag_mobj_type))
return;
for (UINT8 i = 1; i < teamsingame; i++)
{
UINT8 otherteam = G_GetTeam(i);
UINT32 flagflag = teams[otherteam].flag;
if (!(player->gotflag & flagflag) || otherteam == player->ctfteam)
continue;
teamscaptured[totalcaptured++] = otherteam;
teamscores[team]++;
player->gotflag &= ~flagflag;
P_AddPlayerScore(player, 250);
if (splitscreen || players[consoleplayer].ctfteam == team)
S_StartSound(NULL, sfx_flgcap);
else if (players[consoleplayer].ctfteam != team)
S_StartSound(NULL, sfx_lose);
mobj_t *mo = P_SpawnTeamFlag(otherteam, player->mo->x, player->mo->y, player->mo->z);
if (mo)
{
mo->flags &= ~MF_SPECIAL;
mo->fuse = TICRATE;
mo->spawnpoint = flagpoints[otherteam];
mo->flags2 |= MF2_JUSTATTACKED;
}
}
HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE);
HU_SetCEchoDuration(5);
HU_DoCEcho(va(M_GetText("%s%s\200\\captured the %s%s\200.\\\\\\\\"), GetChatColorForSkincolor(G_GetTeamColor(team)), player_names[player-players], GetChatColorForSkincolor(G_GetTeamColor(otherteam)), G_GetTeamFlagName(otherteam)));
if (splitscreen || players[consoleplayer].ctfteam == team)
S_StartSound(NULL, sfx_flgcap);
else if (players[consoleplayer].ctfteam != team)
S_StartSound(NULL, sfx_lose);
mo = P_SpawnTeamFlag(otherteam, player->mo->x, player->mo->y, player->mo->z);
if (mo)
if (totalcaptured == 1)
{
mo->flags &= ~MF_SPECIAL;
mo->fuse = TICRATE;
mo->spawnpoint = flagpoints[otherteam];
mo->flags2 |= MF2_JUSTATTACKED;
UINT8 otherteam = teamscaptured[0];
HU_DoCEcho(va(M_GetText("%s%s\200\\captured the %s%s\200.\\\\\\\\"), GetChatColorForSkincolor(G_GetTeamColor(team)), player_names[player-players], GetChatColorForSkincolor(G_GetTeamColor(otherteam)), G_GetTeamFlagName(otherteam)));
}
else
{
char *buffer = NULL;
size_t buffer_size = 0;
const char *text = va(M_GetText("%s%s\200 captured the:\\"), GetChatColorForSkincolor(G_GetTeamColor(team)), player_names[player-players]);
buffer_size += strlen(text) + 1;
buffer = Z_Realloc(buffer, buffer_size, PU_STATIC, NULL);
strcpy(buffer, text);
for (UINT8 i = 0; i < totalcaptured; i++)
{
UINT8 otherteam = teamscaptured[i];
text = va(M_GetText("%s%s\200\\"), GetChatColorForSkincolor(G_GetTeamColor(otherteam)), G_GetTeamFlagName(otherteam));
buffer_size += strlen(text) + 1;
buffer = Z_Realloc(buffer, buffer_size, PU_STATIC, NULL);
strcat(buffer, text);
}
HU_DoCEcho(buffer);
Z_Free(buffer);
}
player->gotflag &= ~teamflag;
teamscores[team]++;
P_AddPlayerScore(player, 250);
}
static void P_ProcessZoomTube(player_t *player, mtag_t sectag, boolean end)
@ -4999,10 +5143,8 @@ static void P_EvaluateSpecialFlags(player_t *player, sector_t *sector, sector_t
P_ProcessExitSector(player, sectag);
if ((sector->specialflags & SSF_SPECIALSTAGEPIT) && isTouching)
P_ProcessSpecialStagePit(player);
if ((sector->specialflags & SSF_REDTEAMBASE) && isTouching)
P_ProcessTeamBase(player, TEAM_RED);
if ((sector->specialflags & SSF_BLUETEAMBASE) && isTouching)
P_ProcessTeamBase(player, TEAM_BLUE);
if ((sector->teambase != TEAM_NONE) && isTouching)
P_ProcessTeamBase(player, sector->teambase);
if (sector->specialflags & SSF_FAN)
{
player->mo->momz += mobjinfo[MT_FAN].mass/4;

View file

@ -506,6 +506,8 @@ sector_t *P_FindPlayerTrigger(player_t *player, line_t *sourceline);
boolean P_IsPlayerValid(size_t playernum);
boolean P_CanPlayerTrigger(size_t playernum);
void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector);
sector_t *P_MobjTouchingTeamBase(mobj_t *mo, UINT8 team);
sector_t *P_PlayerTouchingTeamBase(player_t *player, UINT8 team);
fixed_t P_FindLowestFloorSurrounding(sector_t *sec);
fixed_t P_FindHighestFloorSurrounding(sector_t *sec);
@ -519,7 +521,7 @@ fixed_t P_FindHighestCeilingSurrounding(sector_t *sec);
INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max);
void P_SetupSignExit(player_t *player);
boolean P_IsFlagAtBase(mobjtype_t flag);
boolean P_TeamHasFlagAtBase(UINT8 team);
boolean P_IsMobjTouchingSectorPlane(mobj_t *mo, sector_t *sec);
boolean P_IsMobjTouching3DFloor(mobj_t *mo, ffloor_t *ffloor, sector_t *sec);

View file

@ -467,6 +467,7 @@ typedef struct sector_s
sectorflags_t flags;
sectorspecialflags_t specialflags;
UINT8 damagetype;
UINT8 teambase;
// Linedef executor triggering
mtag_t triggertag; // tag to call upon triggering