From f6f5dcef1c45c56c5b349d6ccbc3121747f7c319 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 6 Aug 2023 21:13:00 -0300 Subject: [PATCH] Added P_MobjTouchingTeamBase, P_TeamHasFlagAtBase, sector.teambase --- src/g_game.c | 4 +- src/lua_baselib.c | 37 +++++++- src/lua_maplib.c | 8 ++ src/p_inter.c | 69 +++++++++------ src/p_saveg.c | 7 ++ src/p_setup.c | 37 ++++++++ src/p_spec.c | 212 ++++++++++++++++++++++++++++++++++++++-------- src/p_spec.h | 4 +- src/r_defs.h | 1 + 9 files changed, 312 insertions(+), 67 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 0e03c006c..2822e8d62 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -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; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c8b237bf6..2fedd3723 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -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}, diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 3d95cdb75..e4d6f4801 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -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; diff --git a/src/p_inter.c b/src/p_inter.c index 8a0403454..1fd66eaa2 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -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; } diff --git a/src/p_saveg.c b/src/p_saveg.c index 0812f6c3a..33e3aa464 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -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]); diff --git a/src/p_setup.c b/src/p_setup.c index 89b8ff769..92d22097c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -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; diff --git a/src/p_spec.c b/src/p_spec.c index c1703f8fe..ea345b1b9 100644 --- a/src/p_spec.c +++ b/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; diff --git a/src/p_spec.h b/src/p_spec.h index 50ab6410f..ea23d3b0d 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -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); diff --git a/src/r_defs.h b/src/r_defs.h index a9b9a4a08..96b9711d1 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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