From 66695ac6a0003ead5fe21d2616a779e147d50cc5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 28 Jan 2019 02:44:05 +0100 Subject: [PATCH] - made most of the player spawn spot handliing functions members of FLevelLocals. --- src/b_game.cpp | 2 +- src/fragglescript/t_script.cpp | 2 +- src/g_game.cpp | 99 ++++++++++--------- src/g_game.h | 4 - src/g_level.cpp | 4 +- src/g_levellocals.h | 11 +++ src/p_mobj.cpp | 4 +- src/p_setup.cpp | 6 +- wadsrc/static/zscript/base.txt | 12 ++- wadsrc/static/zscript/hexen/teleportother.txt | 6 +- wadsrc/static/zscript/raven/artitele.txt | 4 +- 11 files changed, 84 insertions(+), 70 deletions(-) diff --git a/src/b_game.cpp b/src/b_game.cpp index f8eca50a5e..69f273174f 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -417,7 +417,7 @@ bool FCajunMaster::DoAddBot (uint8_t *info, botskill_t skill) else Printf ("%s joined the game\n", players[bnum].userinfo.GetName()); - G_DoReborn (bnum, true); + level.DoReborn (bnum, true); return true; } diff --git a/src/fragglescript/t_script.cpp b/src/fragglescript/t_script.cpp index 534eb5fa4b..2eb6df9d6b 100644 --- a/src/fragglescript/t_script.cpp +++ b/src/fragglescript/t_script.cpp @@ -667,6 +667,6 @@ CCMD(fpuke) } else { - T_RunScript(currentUILevel, atoi(argv[1]), players[consoleplayer].mo); + T_RunScript(players[consoleplayer].mo->Level, atoi(argv[1]), players[consoleplayer].mo); } } diff --git a/src/g_game.cpp b/src/g_game.cpp index c22c5b4adc..9cf44bf9ce 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1014,7 +1014,7 @@ void G_Ticker () } if (players[i].playerstate == PST_REBORN || players[i].playerstate == PST_ENTER) { - G_DoReborn(i, false); + level.DoReborn(i, false); } } } @@ -1241,7 +1241,7 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags) // Called after a player dies // almost everything is cleared and initialized // -void G_PlayerReborn (int player) +void FLevelLocals::PlayerReborn (int player) { player_t* p; int frags[MAXPLAYERS]; @@ -1325,7 +1325,7 @@ void G_PlayerReborn (int player) // because something is occupying it // -bool G_CheckSpot (int playernum, FPlayerStart *mthing) +bool FLevelLocals::CheckSpot (int playernum, FPlayerStart *mthing) { DVector3 spot; double oldz; @@ -1335,7 +1335,7 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing) spot = mthing->pos; - if (!(level.flags & LEVEL_USEPLAYERSTARTZ)) + if (!(flags & LEVEL_USEPLAYERSTARTZ)) { spot.Z = 0; } @@ -1377,7 +1377,7 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing) // // [RH] Returns the distance of the closest player to the given mapthing -static double PlayersRangeFromSpot (FPlayerStart *spot) +double FLevelLocals::PlayersRangeFromSpot (FPlayerStart *spot) { double closest = INT_MAX; double distance; @@ -1398,7 +1398,7 @@ static double PlayersRangeFromSpot (FPlayerStart *spot) } // [RH] Select the deathmatch spawn spot farthest from everyone. -static FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections) +FPlayerStart *FLevelLocals::SelectFarthestDeathmatchSpot (size_t selections) { double bestdistance = 0; FPlayerStart *bestspot = NULL; @@ -1406,7 +1406,7 @@ static FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections) for (i = 0; i < selections; i++) { - double distance = PlayersRangeFromSpot (&level.deathmatchstarts[i]); + double distance = PlayersRangeFromSpot (&deathmatchstarts[i]); if (distance > bestdistance) { @@ -1419,27 +1419,27 @@ static FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections) } // [RH] Select a deathmatch spawn spot at random (original mechanism) -static FPlayerStart *SelectRandomDeathmatchSpot (int playernum, unsigned int selections) +FPlayerStart *FLevelLocals::SelectRandomDeathmatchSpot (int playernum, unsigned int selections) { unsigned int i, j; for (j = 0; j < 20; j++) { i = pr_dmspawn() % selections; - if (G_CheckSpot (playernum, &level.deathmatchstarts[i]) ) + if (CheckSpot (playernum, &level.deathmatchstarts[i]) ) { - return &level.deathmatchstarts[i]; + return &deathmatchstarts[i]; } } // [RH] return a spot anyway, since we allow telefragging when a player spawns - return &level.deathmatchstarts[i]; + return &deathmatchstarts[i]; } -DEFINE_ACTION_FUNCTION(DObject, G_PickDeathmatchStart) +DEFINE_ACTION_FUNCTION(FLevelLocals, PickDeathmatchStart) { - PARAM_PROLOGUE; - unsigned int selections = level.deathmatchstarts.Size(); + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); + unsigned int selections = self->deathmatchstarts.Size(); DVector3 pos; int angle; if (selections == 0) @@ -1450,8 +1450,8 @@ DEFINE_ACTION_FUNCTION(DObject, G_PickDeathmatchStart) else { unsigned int i = pr_dmspawn() % selections; - angle = level.deathmatchstarts[i].angle; - pos = level.deathmatchstarts[i].pos; + angle = self->deathmatchstarts[i].angle; + pos = self->deathmatchstarts[i].pos; } if (numret > 1) @@ -1466,12 +1466,12 @@ DEFINE_ACTION_FUNCTION(DObject, G_PickDeathmatchStart) return numret; } -void G_DeathMatchSpawnPlayer (int playernum) +void FLevelLocals::DeathMatchSpawnPlayer (int playernum) { unsigned int selections; FPlayerStart *spot; - selections = level.deathmatchstarts.Size (); + selections = deathmatchstarts.Size (); // [RH] We can get by with just 1 deathmatch start if (selections < 1) I_Error ("No deathmatch starts"); @@ -1488,17 +1488,17 @@ void G_DeathMatchSpawnPlayer (int playernum) { // No good spot, so the player will probably get stuck. // We were probably using select farthest above, and all // the spots were taken. - spot = G_PickPlayerStart(playernum, PPS_FORCERANDOM); - if (!G_CheckSpot(playernum, spot)) + spot = PickPlayerStart(playernum, PPS_FORCERANDOM); + if (!CheckSpot(playernum, spot)) { // This map doesn't have enough coop spots for this player // to use one. spot = SelectRandomDeathmatchSpot(playernum, selections); if (spot == NULL) { // We have a player 1 start, right? - spot = &level.playerstarts[0]; + spot = &playerstarts[0]; if (spot->type == 0) { // Fine, whatever. - spot = &level.deathmatchstarts[0]; + spot = &deathmatchstarts[0]; } } } @@ -1511,15 +1511,15 @@ void G_DeathMatchSpawnPlayer (int playernum) // // G_PickPlayerStart // -FPlayerStart *G_PickPlayerStart(int playernum, int flags) +FPlayerStart *FLevelLocals::PickPlayerStart(int playernum, int flags) { - if (level.AllPlayerStarts.Size() == 0) // No starts to pick + if (AllPlayerStarts.Size() == 0) // No starts to pick { return NULL; } - if ((level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM) || - level.playerstarts[playernum].type == 0) + if ((flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM) || + playerstarts[playernum].type == 0) { if (!(flags & PPS_NOBLOCKINGCHECK)) { @@ -1529,9 +1529,9 @@ FPlayerStart *G_PickPlayerStart(int playernum, int flags) // Find all unblocked player starts. for (i = 0; i < level.AllPlayerStarts.Size(); ++i) { - if (G_CheckSpot(playernum, &level.AllPlayerStarts[i])) + if (CheckSpot(playernum, &AllPlayerStarts[i])) { - good_starts.Push(&level.AllPlayerStarts[i]); + good_starts.Push(&AllPlayerStarts[i]); } } if (good_starts.Size() > 0) @@ -1540,17 +1540,17 @@ FPlayerStart *G_PickPlayerStart(int playernum, int flags) } } // Pick a spot at random, whether it's open or not. - return &level.AllPlayerStarts[pr_pspawn(level.AllPlayerStarts.Size())]; + return &level.AllPlayerStarts[pr_pspawn(AllPlayerStarts.Size())]; } - return &level.playerstarts[playernum]; + return &playerstarts[playernum]; } -DEFINE_ACTION_FUNCTION(DObject, G_PickPlayerStart) +DEFINE_ACTION_FUNCTION(FLevelLocals, PickPlayerStart) { - PARAM_PROLOGUE; + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); PARAM_INT(playernum); PARAM_INT(flags); - auto ps = G_PickPlayerStart(playernum, flags); + auto ps = self->PickPlayerStart(playernum, flags); if (numret > 1) { ret[1].SetInt(ps? ps->angle : 0); @@ -1566,23 +1566,24 @@ DEFINE_ACTION_FUNCTION(DObject, G_PickPlayerStart) // // G_QueueBody // -static void G_QueueBody (AActor *body) +void FLevelLocals::QueueBody (AActor *body) { // flush an old corpse if needed - int modslot = level.bodyqueslot%level.BODYQUESIZE; - level.bodyqueslot = modslot + 1; + int modslot = bodyqueslot%level.BODYQUESIZE; + bodyqueslot = modslot + 1; - if (level.bodyqueslot >= level.BODYQUESIZE && level.bodyque[modslot] != NULL) + if (bodyqueslot >= BODYQUESIZE && bodyque[modslot] != NULL) { - level.bodyque[modslot]->Destroy (); + bodyque[modslot]->Destroy (); } - level.bodyque[modslot] = body; + bodyque[modslot] = body; // Copy the player's translation, so that if they change their color later, only // their current body will change and not all their old corpses. if (GetTranslationType(body->Translation) == TRANSLATION_Players || GetTranslationType(body->Translation) == TRANSLATION_PlayersExtra) { + // This needs to be able to handle multiple levels, in case a level with dead players is used as a secondary one later. *translationtables[TRANSLATION_PlayerCorpses][modslot] = *TranslationToTable(body->Translation); body->Translation = TRANSLATION(TRANSLATION_PlayerCorpses,modslot); translationtables[TRANSLATION_PlayerCorpses][modslot]->UpdateNative(); @@ -1606,9 +1607,9 @@ static void G_QueueBody (AActor *body) // G_DoReborn // EXTERN_CVAR(Bool, sv_singleplayerrespawn) -void G_DoReborn (int playernum, bool freshbot) +void FLevelLocals::DoReborn (int playernum, bool freshbot) { - if (!multiplayer && !(level.flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn && + if (!multiplayer && !(flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn && !G_SkillProperty(SKILLP_PlayerRespawn)) { if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars())) @@ -1633,27 +1634,27 @@ void G_DoReborn (int playernum, bool freshbot) // first disassociate the corpse if (players[playernum].mo) { - G_QueueBody (players[playernum].mo); + QueueBody (players[playernum].mo); players[playernum].mo->player = NULL; } // spawn at random spot if in deathmatch - if ((deathmatch || isUnfriendly) && (level.deathmatchstarts.Size () > 0)) + if ((deathmatch || isUnfriendly) && (deathmatchstarts.Size () > 0)) { - G_DeathMatchSpawnPlayer (playernum); + DeathMatchSpawnPlayer (playernum); return; } - if (!(level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) && - level.playerstarts[playernum].type != 0 && - G_CheckSpot (playernum, &level.playerstarts[playernum])) + if (!(flags2 & LEVEL2_RANDOMPLAYERSTARTS) && + playerstarts[playernum].type != 0 && + CheckSpot (playernum, &playerstarts[playernum])) { - AActor *mo = P_SpawnPlayer(&level.playerstarts[playernum], playernum); + AActor *mo = P_SpawnPlayer(&playerstarts[playernum], playernum); if (mo != NULL) P_PlayerStartStomp(mo, true); } else { // try to spawn at any random player's spot - FPlayerStart *start = G_PickPlayerStart(playernum, PPS_FORCERANDOM); + FPlayerStart *start = PickPlayerStart(playernum, PPS_FORCERANDOM); AActor *mo = P_SpawnPlayer(start, playernum); if (mo != NULL) P_PlayerStartStomp(mo, true); } diff --git a/src/g_game.h b/src/g_game.h index 35b8f479c7..03658c106d 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -38,9 +38,6 @@ class AActor; // // GAME // -void G_DeathMatchSpawnPlayer (int playernum); - -struct FPlayerStart *G_PickPlayerStart (int playernum, int flags = 0); enum { PPS_FORCERANDOM = 1, @@ -89,7 +86,6 @@ enum EFinishLevelType void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags); -void G_DoReborn (int playernum, bool freshbot); void G_DoPlayerPop(int playernum); // Adds pitch to consoleplayer's viewpitch and clamps it diff --git a/src/g_level.cpp b/src/g_level.cpp index 4b4b176032..37c1bbc227 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -693,7 +693,7 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill player->mo->special1 = 0; } // ]] - G_DoReborn(i, false); + level.DoReborn(i, false); } } } @@ -1360,7 +1360,7 @@ int G_FinishTravel () pawndup = pawn->player->mo; assert (pawn != pawndup); - start = G_PickPlayerStart(pnum, 0); + start = level.PickPlayerStart(pnum, 0); if (start == NULL) { if (pawndup != nullptr) diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 41e5e28517..d28728986f 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -262,6 +262,17 @@ public: void SpawnExtraPlayers(); void Serialize(FSerializer &arc, bool hubload); + // g_Game + void PlayerReborn (int player); + bool CheckSpot (int playernum, FPlayerStart *mthing); + void DoReborn (int playernum, bool freshbot); + void QueueBody (AActor *body); + double PlayersRangeFromSpot (FPlayerStart *spot); + FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections); + FPlayerStart *SelectRandomDeathmatchSpot (int playernum, unsigned int selections); + void DeathMatchSpawnPlayer (int playernum); + FPlayerStart *PickPlayerStart(int playernum, int flags = 0); + private: // Work data for CollectConnectedGroups. diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 02abc3be08..52d371f3d6 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -109,8 +109,6 @@ // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- -void G_PlayerReborn (int player); - // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- static void PlayerLandedOnThing (AActor *mo, AActor *onmobj); @@ -4999,7 +4997,7 @@ AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flag state = p->playerstate; if (state == PST_REBORN || state == PST_ENTER) { - G_PlayerReborn (playernum); + PlayerReborn (playernum); } else if (oldactor != NULL && oldactor->player == p && !(flags & SPF_TEMPPLAYER)) { diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 8b1d591602..d557236ac6 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -445,7 +445,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame) if (playeringame[i]) { players[i].mo = nullptr; - G_DeathMatchSpawnPlayer(i); + Level->DeathMatchSpawnPlayer(i); } } } @@ -457,7 +457,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame) if (playeringame[i]) { players[i].mo = nullptr; - FPlayerStart *mthing = G_PickPlayerStart(i); + FPlayerStart *mthing = Level->PickPlayerStart(i); P_SpawnPlayer(mthing, i, (Level->flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0); } } @@ -474,7 +474,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame) if (!(players[i].mo->flags & MF_FRIENDLY)) { AActor * oldSpawn = players[i].mo; - G_DeathMatchSpawnPlayer(i); + Level->DeathMatchSpawnPlayer(i); oldSpawn->Destroy(); } } diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 5e52f3e5aa..de621398c9 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -400,8 +400,14 @@ class Object native native static String G_SkillName(); native static int G_SkillPropertyInt(int p); native static double G_SkillPropertyFloat(int p); - native static vector3, int G_PickDeathmatchStart(); - native static vector3, int G_PickPlayerStart(int pnum, int flags = 0); + deprecated("3.8") static vector3, int G_PickDeathmatchStart() + { + return level.PickDeathmatchStart(); + } + deprecated("3.8") static vector3, int G_PickPlayerStart(int pnum, int flags = 0) + { + return level.PickPlayerStart(pnum, flags); + } native static void S_Sound (Sound sound_id, int channel, float volume = 1, float attenuation = ATTN_NORM); native static void S_PauseSound (bool notmusic, bool notsfx); native static void S_ResumeSound (bool notsfx); @@ -703,6 +709,8 @@ struct LevelLocals native native int FindUniqueTid(int start = 0, int limit = 0); native uint GetSkyboxPortal(Actor actor); native void ReplaceTextures(String from, String to, int flags); + native vector3, int PickDeathmatchStart(); + native vector3, int PickPlayerStart(int pnum, int flags = 0); native static clearscope bool IsPointInMap(vector3 p); diff --git a/wadsrc/static/zscript/hexen/teleportother.txt b/wadsrc/static/zscript/hexen/teleportother.txt index f7be0ebff7..93608470ed 100644 --- a/wadsrc/static/zscript/hexen/teleportother.txt +++ b/wadsrc/static/zscript/hexen/teleportother.txt @@ -157,12 +157,12 @@ class TelOtherFX1 : Actor // //=========================================================================== - private static void P_TeleportToPlayerStarts (Actor victim) + private void P_TeleportToPlayerStarts (Actor victim) { Vector3 dest; double destAngle; - [dest, destAngle] = G_PickPlayerStart(0, PPS_FORCERANDOM | PPS_NOBLOCKINGCHECK); + [dest, destAngle] = level.PickPlayerStart(0, PPS_FORCERANDOM | PPS_NOBLOCKINGCHECK); dest.Z = ONFLOORZ; victim.Teleport ((dest.xy, ONFLOORZ), destangle, TELF_SOURCEFOG | TELF_DESTFOG); } @@ -178,7 +178,7 @@ class TelOtherFX1 : Actor Vector3 dest; double destAngle; - [dest, destAngle] = G_PickDeathmatchStart(); + [dest, destAngle] = level.PickDeathmatchStart(); if (destAngle < 65536) victim.Teleport((dest.xy, ONFLOORZ), destangle, TELF_SOURCEFOG | TELF_DESTFOG); else P_TeleportToPlayerStarts(victim); } diff --git a/wadsrc/static/zscript/raven/artitele.txt b/wadsrc/static/zscript/raven/artitele.txt index 0e65fe051f..0400193fe7 100644 --- a/wadsrc/static/zscript/raven/artitele.txt +++ b/wadsrc/static/zscript/raven/artitele.txt @@ -30,11 +30,11 @@ class ArtiTeleport : Inventory if (deathmatch) { - [dest, destAngle] = G_PickDeathmatchStart(); + [dest, destAngle] = level.PickDeathmatchStart(); } else { - [dest, destAngle] = G_PickPlayerStart(Owner.PlayerNumber()); + [dest, destAngle] = level.PickPlayerStart(Owner.PlayerNumber()); } dest.Z = ONFLOORZ; Owner.Teleport (dest, destAngle, TELF_SOURCEFOG | TELF_DESTFOG);