mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-09 19:02:01 +00:00
Added P_MobjTouchingTeamBase, P_TeamHasFlagAtBase, sector.teambase
This commit is contained in:
parent
0021fd1680
commit
f6f5dcef1c
9 changed files with 312 additions and 67 deletions
|
@ -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;
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(§ors[i]);
|
||||
|
|
|
@ -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;
|
||||
|
|
212
src/p_spec.c
212
src/p_spec.c
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue