diff --git a/src/actorptrselect.cpp b/src/actorptrselect.cpp index 8c9057ca7..5cf326480 100644 --- a/src/actorptrselect.cpp +++ b/src/actorptrselect.cpp @@ -35,6 +35,7 @@ #include "actor.h" #include "d_player.h" #include "p_local.h" +#include "g_levellocals.h" //========================================================================== // @@ -61,14 +62,18 @@ Only one selector of each type can be used. */ -#define AAPTR_RESOLVE_PLAYERNUM(playernum) (playeringame[playernum] ? players[playernum].mo : NULL) - AActor *COPY_AAPTR(AActor *origin, int selector) { if (selector == AAPTR_DEFAULT) return origin; FTranslatedLineTarget t; + auto Level = origin->Level; + auto AAPTR_RESOLVE_PLAYERNUM = [=](int playernum) -> AActor* + { + return (Level->PlayerInGame(playernum) ? Level->Players[playernum]->mo : nullptr); + }; + if (origin) { if (origin->player) @@ -97,7 +102,7 @@ AActor *COPY_AAPTR(AActor *origin, int selector) return t.linetarget; } } - + switch (selector & AAPTR_STATIC_SELECTORS) { case AAPTR_PLAYER1: return AAPTR_RESOLVE_PLAYERNUM(0); diff --git a/src/fragglescript/t_cmd.cpp b/src/fragglescript/t_cmd.cpp index 593b72e03..905c47c99 100644 --- a/src/fragglescript/t_cmd.cpp +++ b/src/fragglescript/t_cmd.cpp @@ -154,12 +154,12 @@ void FS_EmulateCmd(FLevelLocals *Level, char * string) { sc.MustGetFloat(); double playerviewheight = sc.Float; - for(int i=0;iPlayers) { // No, this is not correct. But this is the way Legacy WADs expect it to be handled! - if (players[i].mo != NULL) players[i].mo->FloatVar(NAME_ViewHeight) = playerviewheight; - players[i].viewheight = playerviewheight; - players[i].Uncrouch(); + if (p->mo != nullptr) p->mo->FloatVar(NAME_ViewHeight) = playerviewheight; + p->viewheight = playerviewheight; + p->Uncrouch(); } while (sc.GetString()) { diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 1dccf3f35..4ebd0b1e9 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -278,7 +278,7 @@ int FParser::T_GetPlayerNum(const svalue_t &arg) { return -1; } - if(!playeringame[playernum]) // no error, just return -1 + if(!Level->PlayerInGame(playernum)) // no error, just return -1 { return -1; } @@ -288,7 +288,7 @@ int FParser::T_GetPlayerNum(const svalue_t &arg) AActor *FParser::T_GetPlayerActor(const svalue_t &arg) { int num = T_GetPlayerNum(arg); - return num == -1 ? nullptr : players[num].mo; + return num == -1 ? nullptr : Level->Players[num]->mo; } PClassActor *T_ClassType(const svalue_t &arg) @@ -659,7 +659,7 @@ void FParser::SF_PlayerTip(void) if (CheckArgs(1)) { int plnum = T_GetPlayerNum(t_argv[0]); - if (plnum!=-1 && players[plnum].mo->CheckLocalView(consoleplayer)) + if (plnum!=-1 && Level->Players[plnum]->mo->CheckLocalView(consoleplayer)) { C_MidPrint(SmallFont, GetFormatString(1).GetChars()); } @@ -692,7 +692,7 @@ void FParser::SF_PlayerMsg(void) if (CheckArgs(1)) { int plnum = T_GetPlayerNum(t_argv[0]); - if (plnum!=-1 && players[plnum].mo->CheckLocalView(consoleplayer)) + if (plnum!=-1 && Level->Players[plnum]->mo->CheckLocalView(consoleplayer)) { Printf(PRINT_HIGH, "%s\n", GetFormatString(1).GetChars()); } @@ -714,7 +714,7 @@ void FParser::SF_PlayerInGame(void) if (plnum!=-1) { t_return.type = svt_int; - t_return.value.i = playeringame[plnum]; + t_return.value.i = Level->PlayerInGame(plnum); } } } @@ -742,7 +742,7 @@ void FParser::SF_PlayerName(void) if(plnum !=-1) { t_return.type = svt_string; - t_return.string = players[plnum].userinfo.GetName(); + t_return.string = Level->Players[plnum]->userinfo.GetName(); } else { @@ -773,7 +773,7 @@ void FParser::SF_PlayerObj(void) if(plnum !=-1) { t_return.type = svt_mobj; - t_return.value.mobj = players[plnum].mo; + t_return.value.mobj = Level->Players[plnum]->mo; } else { @@ -1402,8 +1402,8 @@ void FParser::SF_SetCamera(void) if (CheckArgs(1)) { - player=Script->trigger->player; - if (!player) player=&players[0]; + player = Script->trigger->player; + if (!player) player = Level->Players[0]; newcamera = actorvalue(t_argv[0]); if(!newcamera) @@ -1435,8 +1435,8 @@ void FParser::SF_SetCamera(void) void FParser::SF_ClearCamera(void) { player_t * player; - player=Script->trigger->player; - if (!player) player=&players[0]; + player = Script->trigger->player; + if (!player) player = Level->Players[0]; AActor * cam=player->camera; if (cam) @@ -2419,13 +2419,13 @@ void FParser::SF_PlayerKeys(void) if(t_argc == 2) { t_return.type = svt_int; - t_return.value.i = CheckInventory(players[playernum].mo, keyname); + t_return.value.i = CheckInventory(Level->Players[playernum]->mo, keyname); return; } else { givetake = intvalue(t_argv[2]); - ScriptUtil::Exec(givetake?NAME_GiveInventory : NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, keyname.GetIndex(), ScriptUtil::Int, 1, ScriptUtil::End); + ScriptUtil::Exec(givetake?NAME_GiveInventory : NAME_TakeInventory, ScriptUtil::Pointer, Level->Players[playernum]->mo, ScriptUtil::Int, keyname.GetIndex(), ScriptUtil::Int, 1, ScriptUtil::End); t_return.type = svt_int; t_return.value.i = 0; } @@ -2504,14 +2504,14 @@ void FParser::SF_PlayerWeapon() if (t_argc == 2) { - AActor * wp = players[playernum].mo->FindInventory(ti); + AActor * wp = Level->Players[playernum]->mo->FindInventory(ti); t_return.type = svt_int; t_return.value.i = wp!=NULL; return; } else { - AActor * wp = players[playernum].mo->FindInventory(ti); + AActor * wp = Level->Players[playernum]->mo->FindInventory(ti); newweapon = !!intvalue(t_argv[2]); if (!newweapon) @@ -2520,14 +2520,14 @@ void FParser::SF_PlayerWeapon() { wp->Destroy(); // If the weapon is active pick a replacement. Legacy didn't do this! - if (players[playernum].PendingWeapon==wp) players[playernum].PendingWeapon=WP_NOCHANGE; - if (players[playernum].ReadyWeapon==wp) + if (Level->Players[playernum]->PendingWeapon==wp) Level->Players[playernum]->PendingWeapon=WP_NOCHANGE; + if (Level->Players[playernum]->ReadyWeapon==wp) { - players[playernum].ReadyWeapon=nullptr; + Level->Players[playernum]->ReadyWeapon=nullptr; IFVM(PlayerPawn, PickNewWeapon) { - VMValue param[] = { players[playernum].mo, (void*)nullptr }; + VMValue param[] = { Level->Players[playernum]->mo, (void*)nullptr }; VMCall(func, param, 2, nullptr, 0); } } @@ -2537,9 +2537,9 @@ void FParser::SF_PlayerWeapon() { if (!wp) { - auto pw=players[playernum].PendingWeapon; - players[playernum].mo->GiveInventoryType(ti); - players[playernum].PendingWeapon=pw; + auto pw=Level->Players[playernum]->PendingWeapon; + Level->Players[playernum]->mo->GiveInventoryType(ti); + Level->Players[playernum]->PendingWeapon=pw; } } @@ -2588,13 +2588,13 @@ void FParser::SF_PlayerSelectedWeapon() return; } - players[playernum].PendingWeapon = players[playernum].mo->FindInventory(ti); + Level->Players[playernum]->PendingWeapon = Level->Players[playernum]->mo->FindInventory(ti); } t_return.type = svt_int; for(int i=0;i<9;i++) { - if (players[playernum].ReadyWeapon->GetClass ()->TypeName == FName(WeaponNames[i])) + if (Level->Players[playernum]->ReadyWeapon->GetClass ()->TypeName == FName(WeaponNames[i])) { t_return.value.i=i; break; @@ -2620,7 +2620,7 @@ void FParser::SF_GiveInventory(void) if(t_argc == 2) count=1; else count=intvalue(t_argv[2]); - ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, FName(stringvalue(t_argv[1])).GetIndex(), ScriptUtil::Int, count, ScriptUtil::End); + ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, Level->Players[playernum]->mo, ScriptUtil::Int, FName(stringvalue(t_argv[1])).GetIndex(), ScriptUtil::Int, count, ScriptUtil::End); t_return.type = svt_int; t_return.value.i = 0; } @@ -2643,7 +2643,7 @@ void FParser::SF_TakeInventory(void) if(t_argc == 2) count=32767; else count=intvalue(t_argv[2]); - ScriptUtil::Exec(NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, FName(stringvalue(t_argv[1])).GetIndex(), ScriptUtil::Int, count, ScriptUtil::End); + ScriptUtil::Exec(NAME_TakeInventory, ScriptUtil::Pointer, Level->Players[playernum]->mo, ScriptUtil::Int, FName(stringvalue(t_argv[1])).GetIndex(), ScriptUtil::Int, count, ScriptUtil::End); t_return.type = svt_int; t_return.value.i = 0; } @@ -2668,7 +2668,7 @@ void FParser::SF_CheckInventory(void) return; } t_return.type = svt_int; - t_return.value.i = CheckInventory(players[playernum].mo, stringvalue(t_argv[1])); + t_return.value.i = CheckInventory(Level->Players[playernum]->mo, stringvalue(t_argv[1])); } } @@ -3221,10 +3221,10 @@ void FParser::SF_PlayerAddFrag() { playernum1 = T_GetPlayerNum(t_argv[0]); - players[playernum1].fragcount++; + Level->Players[playernum1]->fragcount++; t_return.type = svt_int; - t_return.value.f = players[playernum1].fragcount; + t_return.value.f = Level->Players[playernum1]->fragcount; } else @@ -3232,10 +3232,10 @@ void FParser::SF_PlayerAddFrag() playernum1 = T_GetPlayerNum(t_argv[0]); playernum2 = T_GetPlayerNum(t_argv[1]); - players[playernum1].frags[playernum2]++; + Level->Players[playernum1]->frags[playernum2]++; t_return.type = svt_int; - t_return.value.f = players[playernum1].frags[playernum2]; + t_return.value.f = Level->Players[playernum1]->frags[playernum2]; } } } diff --git a/src/fragglescript/t_script.cpp b/src/fragglescript/t_script.cpp index 2eb6df9d6..fd2cbcefc 100644 --- a/src/fragglescript/t_script.cpp +++ b/src/fragglescript/t_script.cpp @@ -616,7 +616,7 @@ void T_PreprocessScripts(FLevelLocals *Level) // get the other scripts // levelscript started by player 0 'superplayer' - th->LevelScript->trigger = players[0].mo; + th->LevelScript->trigger = Level->Players[0]->mo; th->LevelScript->Preprocess(Level); th->LevelScript->ParseScript(nullptr, th); diff --git a/src/g_inventory/a_keys.cpp b/src/g_inventory/a_keys.cpp index 817340579..ad0e85404 100644 --- a/src/g_inventory/a_keys.cpp +++ b/src/g_inventory/a_keys.cpp @@ -494,7 +494,7 @@ int P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet) // If we get here, that means the actor isn't holding an appropriate key. - if (owner == players[consoleplayer].camera) + if (owner->CheckLocalView(consoleplayer)) { PrintMessage(failtext); diff --git a/src/g_level.cpp b/src/g_level.cpp index 94a985066..60f38ea5e 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -835,12 +835,12 @@ bool FLevelLocals::DoCompleted (FString nextlevel, wbstartstruct_t &wminfo) for (i=0 ; ikillcount; + wminfo.plyr[i].sitems = Players[i]->itemcount; + wminfo.plyr[i].ssecret = Players[i]->secretcount; wminfo.plyr[i].stime = time; - memcpy (wminfo.plyr[i].frags, players[i].frags, sizeof(wminfo.plyr[i].frags)); - wminfo.plyr[i].fragcount = players[i].fragcount; + memcpy (wminfo.plyr[i].frags, Players[i]->frags, sizeof(wminfo.plyr[i].frags)); + wminfo.plyr[i].fragcount = Players[i]->fragcount; } // [RH] If we're in a hub and staying within that hub, take a snapshot. @@ -1035,11 +1035,11 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && (deathmatch || players[i].playerstate == PST_DEAD)) - players[i].playerstate = PST_ENTER; // [BC] - memset (players[i].frags,0,sizeof(players[i].frags)); + if (PlayerInGame(i) && (deathmatch || Players[i]->playerstate == PST_DEAD)) + Players[i]->playerstate = PST_ENTER; // [BC] + memset (Players[i]->frags,0,sizeof(Players[i]->frags)); if (!(dmflags2 & DF2_YES_KEEPFRAGS) && (alwaysapplydmflags || deathmatch)) - players[i].fragcount = 0; + Players[i]->fragcount = 0; } if (changeflags & CHANGELEVEL_NOMONSTERS) @@ -1093,19 +1093,19 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au { for (int i = 0; imo != nullptr) + P_PlayerStartStomp(Players[i]->mo); } } // For each player, if they are viewing through a player, make sure it is themselves. for (int ii = 0; ii < MAXPLAYERS; ++ii) { - if (playeringame[ii]) + if (PlayerInGame(ii)) { - if (players[ii].camera == NULL || players[ii].camera->player != NULL) + if (Players[ii]->camera == nullptr || Players[ii]->camera->player != nullptr) { - players[ii].camera = players[ii].mo; + Players[ii]->camera = Players[ii]->mo; } if (savegamerestore) @@ -1119,7 +1119,7 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au if (fromSnapshot) { // ENTER scripts are being handled when the player gets spawned, this cannot be changed due to its effect on voodoo dolls. - Behaviors.StartTypedScripts(SCRIPT_Return, players[ii].mo, true); + Behaviors.StartTypedScripts(SCRIPT_Return, Players[ii]->mo, true); } } } @@ -1181,8 +1181,8 @@ void FLevelLocals::WorldDone (void) // Strife needs a special case here to choose between good and sad ending. Bad is handled elsewhere. if (endsequence == NAME_Inter_Strife) { - if (players[0].mo->FindInventory (NAME_QuestItem25) || - players[0].mo->FindInventory (NAME_QuestItem28)) + if (Players[0]->mo->FindInventory (NAME_QuestItem25) || + Players[0]->mo->FindInventory (NAME_QuestItem28)) { endsequence = NAME_Inter_Strife_Good; } @@ -1317,12 +1317,12 @@ void FLevelLocals::StartTravel () { if (playeringame[i]) { - AActor *pawn = players[i].mo; + AActor *pawn = Players[i]->mo; AActor *inv; - players[i].camera = nullptr; + Players[i]->camera = nullptr; // Only living players travel. Dead ones get a new body on the new level. - if (players[i].health > 0) + if (Players[i]->health > 0) { pawn->UnlinkFromWorld (nullptr); int tid = pawn->tid; // Save TID @@ -1721,14 +1721,14 @@ void FLevelLocals::UnSnapshotLevel (bool hubLoad) while ((pawn = next) != 0) { next = it.Next(); - if (pawn->player == NULL || pawn->player->mo == NULL || !playeringame[pawn->player - players]) + if (pawn->player == nullptr || pawn->player->mo == nullptr || !PlayerInGame(pawn->player)) { int i; // If this isn't the unmorphed original copy of a player, destroy it, because it's extra. for (i = 0; i < MAXPLAYERS; ++i) { - if (playeringame[i] && players[i].morphTics && players[i].mo->alternative == pawn) + if (PlayerInGame(i) && Players[i]->morphTics && Players[i]->mo->alternative == pawn) { break; } diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 79f72c23f..471d7b655 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -48,6 +48,7 @@ #include "p_spec.h" #include "actor.h" #include "p_effect.h" +#include "d_player.h" #include "p_destructible.h" #include "r_data/r_sections.h" #include "r_data/r_canvastexture.h" @@ -102,7 +103,15 @@ struct FLevelLocals { void *level; void *Level; // bug catchers. - FLevelLocals() : Behaviors(this), tagManager(this) {} + FLevelLocals() : Behaviors(this), tagManager(this) + { + // Make sure that these point to the right data all the time. + // This will be needed for as long as it takes to completely separate global UI state from per-level play state. + for (int i = 0; i < MAXPLAYERS; i++) + { + Players[i] = &players[i]; + } + } friend class MapLoader; @@ -493,6 +502,42 @@ public: TObjPtr bodyque[BODYQUESIZE]; TObjPtr automap = nullptr; int bodyqueslot; + + // For now this merely points to the global player array, but with this in place, access to this array can be moved over to the level. + // As things progress each level needs to be able to point to different players, + // but even then the level will not own the player - the player merely links to the level. + // This should also be made a real object eventually. + player_t *Players[MAXPLAYERS]; + + // This is to allow refactoring without refactoring the data right away. + bool PlayerInGame(int pnum) + { + return playeringame[pnum]; + } + + // This needs to be done better, but for now it should be good enough. + bool PlayerInGame(player_t *player) + { + for (int i = 0; i < MAXPLAYERS; i++) + { + if (player == Players[i]) return PlayerInGame(i); + } + return false; + } + + int PlayerNum(player_t *player) + { + for (int i = 0; i < MAXPLAYERS; i++) + { + if (player == Players[i]) return i; + } + return -1; + } + + bool isPrimaryLevel() const + { + return true; + } int NumMapSections; diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index a00307f7e..4eff8a437 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -122,9 +122,9 @@ void DEarthquake::Tick () { for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && !(players[i].cheats & CF_NOCLIP)) + if (Level->PlayerInGame(i) && !(Level->Players[i]->cheats & CF_NOCLIP)) { - AActor *victim = players[i].mo; + AActor *victim = Level->Players[i]->mo; double dist; dist = m_Spot->Distance2D(victim, true); diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index a22491009..ca141bb01 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -3247,8 +3247,8 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position) for (int i = 0; i < MAXPLAYERS; ++i) { - if (playeringame[i] && players[i].mo != nullptr) - players[i].health = players[i].mo->health; + if (Level->PlayerInGame(i) && Level->Players[i]->mo != nullptr) + Level->Players[i]->health = Level->Players[i]->mo->health; } if (!map->HasBehavior && !map->isText) TranslateTeleportThings(); // [RH] Assign teleport destination TIDs diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 6a45adb38..8b54e9798 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1725,7 +1725,7 @@ static bool DoUseInv (AActor *actor, PClassActor *info) // //============================================================================ -static int UseInventory (AActor *activator, const char *type) +static int UseInventory (FLevelLocals *Level, AActor *activator, const char *type) { PClassActor *info; int ret = 0; @@ -1743,8 +1743,8 @@ static int UseInventory (AActor *activator, const char *type) { for (int i = 0; i < MAXPLAYERS; ++i) { - if (playeringame[i]) - ret += DoUseInv (players[i].mo, info); + if (Level->PlayerInGame(i)) + ret += DoUseInv (Level->Players[i]->mo, info); } } else @@ -1759,6 +1759,7 @@ static int UseInventory (AActor *activator, const char *type) // CheckInventory // // Returns how much of a particular item an actor has. +// This also gets called from FraggleScript. // //============================================================================ @@ -3672,7 +3673,7 @@ int DLevelScript::CountPlayers () int count = 0, i; for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) + if (Level->PlayerInGame(i)) count++; return count; @@ -3850,9 +3851,9 @@ void DLevelScript::DoFadeRange (int r1, int g1, int b1, int a1, { for (i = 0; i < MAXPLAYERS; ++i) { - if (playeringame[i]) + if (Level->PlayerInGame(i)) { - viewer = &players[i]; + viewer = Level->Players[i]; showme: if (ftime <= 0.f) { @@ -3965,7 +3966,7 @@ int DoGetMasterTID (AActor *self) if (self->master) return self->master->tid; else if (self->FriendPlayer) { - player_t *player = &players[(self->FriendPlayer)-1]; + player_t *player = self->Level->Players[(self->FriendPlayer)-1]; return player->mo->tid; } else return 0; @@ -4504,13 +4505,13 @@ int DLevelScript::GetPlayerInput(int playernum, int inputnum) } p = activator->player; } - else if (playernum >= MAXPLAYERS || !playeringame[playernum]) + else if (playernum >= MAXPLAYERS || !Level->PlayerInGame(playernum)) { return 0; } else { - p = &players[playernum]; + p = Level->Players[playernum]; } if (p == NULL) { @@ -4961,11 +4962,11 @@ static int DoGetCVar(FBaseCVar *cvar, bool is_string) int DLevelScript::SetUserCVar(int playernum, const char *cvarname, int value, bool is_string) { - if ((unsigned)playernum >= MAXPLAYERS || !playeringame[playernum]) + if ((unsigned)playernum >= MAXPLAYERS || !Level->PlayerInGame(playernum)) { return 0; } - FBaseCVar **cvar_p = players[playernum].userinfo.CheckKey(FName(cvarname, true)); + FBaseCVar **cvar_p = Level->Players[playernum]->userinfo.CheckKey(FName(cvarname, true)); FBaseCVar *cvar; // Only mod-created cvars may be set. if (cvar_p == NULL || (cvar = *cvar_p) == NULL || (cvar->GetFlags() & CVAR_IGNORE) || !(cvar->GetFlags() & CVAR_MOD)) @@ -4975,7 +4976,7 @@ int DLevelScript::SetUserCVar(int playernum, const char *cvarname, int value, bo DoSetCVar(cvar, value, is_string); // If we are this player, then also reflect this change in the local version of this cvar. - if (playernum == consoleplayer) + if (playernum == consoleplayer && Level->isPrimaryLevel()) { FBaseCVar *cvar = FindCVar(cvarname, NULL); // If we can find it in the userinfo, then we should also be able to find it in the normal cvar list, @@ -5004,7 +5005,9 @@ int DLevelScript::SetCVar(AActor *activator, const char *cvarname, int value, bo { return 0; } - return SetUserCVar(int(activator->player - players), cvarname, value, is_string); + auto pnum = Level->PlayerNum(activator->player); + if (pnum < 0) return 0; + return SetUserCVar(pnum, cvarname, value, is_string); } DoSetCVar(cvar, value, is_string); return 1; @@ -5388,25 +5391,25 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args) case ACSF_GetAirSupply: { - if (args[0] < 0 || args[0] >= MAXPLAYERS || !playeringame[args[0]]) + if (args[0] < 0 || args[0] >= MAXPLAYERS || !Level->PlayerInGame(args[0])) { return 0; } else { - return players[args[0]].air_finished - Level->time; + return Level->Players[args[0]]->air_finished - Level->time; } } case ACSF_SetAirSupply: { - if (args[0] < 0 || args[0] >= MAXPLAYERS || !playeringame[args[0]]) + if (args[0] < 0 || args[0] >= MAXPLAYERS || !Level->PlayerInGame(args[0])) { return 0; } else { - players[args[0]].air_finished = args[1] + Level->time; + Level->Players[args[0]]->air_finished = args[1] + Level->time; return 1; } } @@ -5420,14 +5423,14 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args) case ACSF_GetArmorType: { - if (args[1] < 0 || args[1] >= MAXPLAYERS || !playeringame[args[1]]) + if (args[1] < 0 || args[1] >= MAXPLAYERS || !Level->PlayerInGame(args[1])) { return 0; } else { FName p(Level->Behaviors.LookupString(args[0])); - auto armor = players[args[1]].mo->FindInventory(NAME_BasicArmor); + auto armor = Level->Players[args[1]]->mo->FindInventory(NAME_BasicArmor); if (armor && armor->NameVar(NAME_ArmorType) == p) return armor->IntVar(NAME_Amount); } return 0; @@ -8454,9 +8457,9 @@ scriptwait: player = activator->player; } } - else if (playeringame[STACK(1)-1]) + else if (Level->PlayerInGame(STACK(1)-1)) { - player = &players[STACK(1)-1]; + player = Level->Players[STACK(1)-1]; } else { @@ -8610,6 +8613,7 @@ scriptwait: { optstart = sp; } + if (Level->isPrimaryLevel()) { AActor *screen = activator; if (screen != NULL && @@ -9198,7 +9202,7 @@ scriptwait: break; case PCD_USEINVENTORY: - STACK(1) = UseInventory (activator, Level->Behaviors.LookupString (STACK(1))); + STACK(1) = UseInventory (Level, activator, Level->Behaviors.LookupString (STACK(1))); break; case PCD_USEACTORINVENTORY: @@ -9207,7 +9211,7 @@ scriptwait: const char *type = Level->Behaviors.LookupString(STACK(1)); if (STACK(2) == 0) { - ret = UseInventory(NULL, type); + ret = UseInventory(Level, NULL, type); } else { @@ -9215,7 +9219,7 @@ scriptwait: AActor *actor; for (actor = it.Next(); actor != NULL; actor = it.Next()) { - ret += UseInventory(actor, type); + ret += UseInventory(Level, actor, type); } } STACK(2) = ret; @@ -9655,18 +9659,18 @@ scriptwait: } else { - STACK(1) = playeringame[STACK(1)]; + STACK(1) = Level->PlayerInGame(STACK(1)); } break; case PCD_PLAYERISBOT: - if (STACK(1) < 0 || STACK(1) >= MAXPLAYERS || !playeringame[STACK(1)]) + if (STACK(1) < 0 || STACK(1) >= MAXPLAYERS || !Level->PlayerInGame(STACK(1))) { STACK(1) = false; } else { - STACK(1) = (players[STACK(1)].Bot != NULL); + STACK(1) = (Level->Players[STACK(1)]->Bot != nullptr); } break; @@ -9858,24 +9862,24 @@ scriptwait: break; case PCD_PLAYERCLASS: // [GRB] - if (STACK(1) < 0 || STACK(1) >= MAXPLAYERS || !playeringame[STACK(1)]) + if (STACK(1) < 0 || STACK(1) >= MAXPLAYERS || !Level->PlayerInGame(STACK(1))) { STACK(1) = -1; } else { - STACK(1) = players[STACK(1)].CurrentPlayerClass; + STACK(1) = Level->Players[STACK(1)]->CurrentPlayerClass; } break; case PCD_GETPLAYERINFO: // [GRB] - if (STACK(2) < 0 || STACK(2) >= MAXPLAYERS || !playeringame[STACK(2)]) + if (STACK(2) < 0 || STACK(2) >= MAXPLAYERS || !Level->PlayerInGame(STACK(2))) { STACK(2) = -1; } else { - player_t *pl = &players[STACK(2)]; + player_t *pl = Level->Players[STACK(2)]; userinfo_t *userinfo = &pl->userinfo; switch (STACK(1)) { @@ -9973,13 +9977,14 @@ scriptwait: { int playernum = STACK(1); - if (playernum < 0 || playernum >= MAXPLAYERS || !playeringame[playernum] || players[playernum].camera == NULL || players[playernum].camera->player != NULL) + if (playernum < 0 || playernum >= MAXPLAYERS || !Level->PlayerInGame(playernum) || + Level->Players[playernum]->camera == nullptr || Level->Players[playernum]->camera->player != nullptr) { STACK(1) = -1; } else { - STACK(1) = players[playernum].camera->tid; + STACK(1) = Level->Players[playernum]->camera->tid; } } break; @@ -10301,8 +10306,8 @@ void FLevelLocals::DoDeferedScripts () if (scriptdata) { P_GetScriptGoing (this, (unsigned)def->playernum < MAXPLAYERS && - playeringame[def->playernum] ? players[def->playernum].mo : NULL, - NULL, def->script, + PlayerInGame(def->playernum) ? Players[def->playernum]->mo : nullptr, + nullptr, def->script, scriptdata, module, def->args, 3, def->type == acsdefered_t::defexealways ? ACS_ALWAYS : 0); diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 913a42bc5..398343633 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -1684,18 +1684,20 @@ DEFINE_ACTION_FUNCTION(AActor, CheckIfSeen) { PARAM_SELF_PROLOGUE(AActor); + auto Level = self->Level; for (int i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i]) + if (Level->PlayerInGame(i)) { + auto p = Level->Players[i]; // Always check sight from each player. - if (P_CheckSight(players[i].mo, self, SF_IGNOREVISIBILITY)) + if (P_CheckSight(p->mo, self, SF_IGNOREVISIBILITY)) { ACTION_RETURN_BOOL(false); } // If a player is viewing from a non-player, then check that too. - if (players[i].camera != NULL && players[i].camera->player == NULL && - P_CheckSight(players[i].camera, self, SF_IGNOREVISIBILITY)) + if (p->camera != nullptr && p->camera->player == NULL && + P_CheckSight(p->camera, self, SF_IGNOREVISIBILITY)) { ACTION_RETURN_BOOL(false); } @@ -1755,18 +1757,20 @@ DEFINE_ACTION_FUNCTION(AActor, CheckSightOrRange) PARAM_BOOL(twodi); range *= range; - for (int i = 0; i < MAXPLAYERS; ++i) + auto Level = self->Level; + for (int i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i]) + if (Level->PlayerInGame(i)) { + auto p = Level->Players[i]; // Always check from each player. - if (DoCheckSightOrRange(self, players[i].mo, range, twodi, true)) + if (DoCheckSightOrRange(self, p->mo, range, twodi, true)) { ACTION_RETURN_BOOL(false); } // If a player is viewing from a non-player, check that too. - if (players[i].camera != NULL && players[i].camera->player == NULL && - DoCheckSightOrRange(self, players[i].camera, range, twodi, true)) + if (p->camera != nullptr && p->camera->player == nullptr && + DoCheckSightOrRange(self, p->camera, range, twodi, true)) { ACTION_RETURN_BOOL(false); } @@ -1783,18 +1787,20 @@ DEFINE_ACTION_FUNCTION(AActor, CheckRange) PARAM_BOOL(twodi); range *= range; - for (int i = 0; i < MAXPLAYERS; ++i) + auto Level = self->Level; + for (int i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i]) + if (Level->PlayerInGame(i)) { + auto p = Level->Players[i]; // Always check from each player. - if (DoCheckSightOrRange(self, players[i].mo, range, twodi, false)) + if (DoCheckSightOrRange(self, p->mo, range, twodi, false)) { ACTION_RETURN_BOOL(false); } // If a player is viewing from a non-player, check that too. - if (players[i].camera != NULL && players[i].camera->player == NULL && - DoCheckSightOrRange(self, players[i].camera, range, twodi, false)) + if (p->camera != nullptr && p->camera->player == nullptr && + DoCheckSightOrRange(self, p->camera, range, twodi, false)) { ACTION_RETURN_BOOL(false); } diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 5265b1010..e2185104a 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -738,7 +738,7 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang int i; // Make sure this is actually a player. - if (pc == nullptr || pc->player == nullptr || npc == nullptr) return; + if (pc == nullptr || pc->player == nullptr || npc == nullptr || pc->Level != currentUILevel) return; auto Level = pc->Level; // [CW] If an NPC is talking to a PC already, then don't let diff --git a/src/p_effect.cpp b/src/p_effect.cpp index 20312ced3..ce93fcdea 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -324,10 +324,6 @@ void P_SpawnParticle(FLevelLocals *Level, const DVector3 &pos, const DVector3 &v // void P_RunEffects (FLevelLocals *Level) { - if (players[consoleplayer].camera == NULL) return; - - int pnum = players[consoleplayer].camera->Sector->Index() * Level->sectors.Size(); - AActor *actor; auto iterator = Level->GetThinkerIterator(); diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index f97628510..6997cd738 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1005,12 +1005,12 @@ void P_RandomChaseDir (AActor *actor) { i = 0; } - else for (i = pr_newchasedir() & (MAXPLAYERS-1); !playeringame[i]; i = (i+1) & (MAXPLAYERS-1)) + else for (i = pr_newchasedir() & (MAXPLAYERS-1); !actor->Level->PlayerInGame(i); i = (i+1) & (MAXPLAYERS-1)) { } - player = players[i].mo; + player = actor->Level->Players[i]->mo; } - if (player != NULL && playeringame[i]) + if (player != NULL && actor->Level->PlayerInGame(i)) { if (pr_newchasedir() & 1 || !P_CheckSight (actor, player)) { @@ -1203,7 +1203,7 @@ int P_LookForMonsters (AActor *actor) AActor *mo; auto iterator = actor->Level->GetThinkerIterator(); - if (!P_CheckSight (players[0].mo, actor, SF_SEEPASTBLOCKEVERYTHING)) + if (!P_CheckSight (actor->Level->Players[0]->mo, actor, SF_SEEPASTBLOCKEVERYTHING)) { // Player can't see monster return false; } @@ -1592,11 +1592,13 @@ int P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) // Go back to a player, no matter whether it's visible or not for (int anyone=0; anyone<=1; anyone++) { + auto Level = actor->Level; for (int c=0; cIsFriend(players[c].mo) && - (anyone || P_IsVisible(actor, players[c].mo, allaround))) + auto p = Level->Players[i]; + if (Level->PlayerInGame(c) && p->playerstate==PST_LIVE && + actor->IsFriend(p->mo) && + (anyone || P_IsVisible(actor, p->mo, allaround))) { actor->target = players[c].mo; @@ -1623,8 +1625,9 @@ int P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) } // [SP] if false, and in deathmatch, intentional fall-through if (!(gameinfo.gametype & (GAME_DoomStrifeChex)) && + actor->Level->isPrimaryLevel() && !multiplayer && - players[0].health <= 0 && + actor->Level->Players[0]->health <= 0 && actor->goal == NULL && gamestate != GS_TITLELEVEL ) @@ -1648,7 +1651,7 @@ int P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) if (c++ < MAXPLAYERS) { pnum = (pnum + 1) & (MAXPLAYERS - 1); - if (!playeringame[pnum]) + if (!actor->Level->PlayerInGame(pnum)) continue; if (actor->TIDtoHate == 0) @@ -1686,12 +1689,12 @@ int P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) return actor->target == actor->goal && actor->goal != NULL; } - player = &players[pnum]; + player = actor->Level->Players[pnum]; if (!(player->mo->flags & MF_SHOOTABLE)) continue; // not shootable (observer or dead) - if (!((actor->flags ^ player->mo->flags) & MF_FRIENDLY)) + if (actor->IsFriend(player->mo)) continue; // same +MF_FRIENDLY, ignore if (player->cheats & CF_NOTARGET) @@ -2284,7 +2287,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi if (actor->FriendPlayer != 0) { - player = &players[actor->FriendPlayer - 1]; + player = actor->Level->Players[actor->FriendPlayer - 1]; } else { @@ -2293,10 +2296,10 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi { i = 0; } - else for (i = pr_newchasedir() & (MAXPLAYERS-1); !playeringame[i]; i = (i+1) & (MAXPLAYERS-1)) + else for (i = pr_newchasedir() & (MAXPLAYERS-1); !actor->Level->PlayerInGame(i); i = (i+1) & (MAXPLAYERS-1)) { } - player = &players[i]; + player = actor->Level->Players[i]; } if (player->attacker && player->attacker->health > 0 && player->attacker->flags & MF_SHOOTABLE && pr_newchasedir() < 80) { @@ -3037,7 +3040,7 @@ int CheckBossDeath (AActor *actor) // make sure there is a player alive for victory for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].health > 0) + if (actor->Level->PlayerInGame(i) && actor->Level->Players[i]->health > 0) break; if (i == MAXPLAYERS) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 448892cf3..d1f23094f 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -547,11 +547,11 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf } } } - else if (!multiplayer && CountsAsKill()) + else if (!multiplayer && CountsAsKill() && Level->isPrimaryLevel()) { // count all monster deaths, // even those caused by other monsters - players[0].killcount++; + Level->Players[0]->killcount++; } if (player) @@ -577,11 +577,12 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf //Added by MC: Discard enemies. for (int i = 0; i < MAXPLAYERS; i++) { - if (players[i].Bot != NULL && this == players[i].Bot->enemy) + DBot *Bot = Level->Players[i]->Bot; + if (Bot != nullptr && this == Bot->enemy) { - if (players[i].Bot->dest == players[i].Bot->enemy) - players[i].Bot->dest = nullptr; - players[i].Bot->enemy = nullptr; + if (Bot->dest == Bot->enemy) + Bot->dest = nullptr; + Bot->enemy = nullptr; } } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index fbb2dc873..2b180955f 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2835,24 +2835,25 @@ FUNC(LS_ChangeCamera) for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i]) + if (!Level->PlayerInGame(i)) continue; - AActor *oldcamera = players[i].camera; + auto p = Level->Players[i]; + AActor *oldcamera = p->camera; if (camera) { - players[i].camera = camera; + p->camera = camera; if (arg2) - players[i].cheats |= CF_REVERTPLEASE; + p->cheats |= CF_REVERTPLEASE; } else { - players[i].camera = players[i].mo; - players[i].cheats &= ~CF_REVERTPLEASE; + p->camera = p->mo; + p->cheats &= ~CF_REVERTPLEASE; } - if (oldcamera != players[i].camera) + if (oldcamera != p->camera) { - R_ClearPastViewer (players[i].camera); + R_ClearPastViewer (p->camera); } } } @@ -2977,14 +2978,15 @@ FUNC(LS_SetPlayerProperty) for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].mo == NULL) + auto p = Level->Players[i]; + if (!Level->PlayerInGame(i) || p->mo == nullptr) continue; if (arg1) { // Give power if (power != 4) { - auto item = players[i].mo->GiveInventoryType ((PClass::FindActor(powers[power]))); + auto item = p->mo->GiveInventoryType ((PClass::FindActor(powers[power]))); if (item != NULL && power == 0 && arg1 == 1) { item->ColorVar(NAME_BlendColor) = MakeSpecialColormap(INVERSECOLORMAP); @@ -2999,7 +3001,7 @@ FUNC(LS_SetPlayerProperty) { // Take power if (power != 4) { - auto item = players[i].mo->FindInventory (PClass::FindActor(powers[power])); + auto item = p->mo->FindInventory (PClass::FindActor(powers[power])); if (item != NULL) { item->Destroy (); @@ -3072,25 +3074,26 @@ FUNC(LS_SetPlayerProperty) for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i]) + if (!Level->PlayerInGame(i)) continue; + auto p = Level->Players[i]; if (arg1) { - players[i].cheats |= mask; + p->cheats |= mask; if (arg2 == PROP_FLY) { - players[i].mo->flags2 |= MF2_FLY; - players[i].mo->flags |= MF_NOGRAVITY; + p->mo->flags2 |= MF2_FLY; + p->mo->flags |= MF_NOGRAVITY; } } else { - players[i].cheats &= ~mask; + p->cheats &= ~mask; if (arg2 == PROP_FLY) { - players[i].mo->flags2 &= ~MF2_FLY; - players[i].mo->flags &= ~MF_NOGRAVITY; + p->mo->flags2 &= ~MF2_FLY; + p->mo->flags &= ~MF_NOGRAVITY; } } } @@ -3310,9 +3313,9 @@ FUNC(LS_GlassBreak) { for (int i = 0; i < MAXPLAYERS; ++i) { - if (playeringame[i]) + if (Level->PlayerInGame(i)) { - it = players[i].mo; + it = Level->Players[i]->mo; break; } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 57216d5e3..6b1144660 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -945,16 +945,17 @@ DEFINE_ACTION_FUNCTION(AActor, GiveBody) bool AActor::CheckLocalView (int playernum) const { - if (players[playernum].camera == this) + auto p = &players[playernum]; + if (p->camera == this) { return true; } - if (players[playernum].mo != this || players[playernum].camera == NULL) + if (p->mo != this || p->camera == nullptr) { return false; } - if (players[playernum].camera->player == NULL && - !(players[playernum].camera->flags3 & MF3_ISMONSTER)) + if (p->camera->player == NULL && + !(p->camera->flags3 & MF3_ISMONSTER)) { return true; } @@ -985,6 +986,10 @@ bool AActor::IsInsideVisibleAngles() const if (players[consoleplayer].camera == nullptr) return true; + // Not detectable. + if (!Level->isPrimaryLevel()) + return true; + DAngle anglestart = VisibleStartAngle; DAngle angleend = VisibleEndAngle; DAngle pitchstart = VisibleStartPitch; @@ -3264,7 +3269,7 @@ bool AActor::IsOkayToAttack (AActor *link) AActor * Friend; if (flags5 & MF5_SUMMONEDMONSTER) Friend = tracer; else if (flags2 & MF2_SEEKERMISSILE) Friend = target; - else if ((flags & MF_FRIENDLY) && FriendPlayer) Friend = players[FriendPlayer-1].mo; + else if ((flags & MF_FRIENDLY) && FriendPlayer) Friend = Level->Players[FriendPlayer-1]->mo; else Friend = this; // Friend checks @@ -5052,9 +5057,9 @@ AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flag for (int ii = 0; ii < MAXPLAYERS; ++ii) { - if (playeringame[ii] && players[ii].camera == oldactor) + if (PlayerInGame(ii) && Players[ii]->camera == oldactor) { - players[ii].camera = mobj; + Players[ii]->camera = mobj; } } @@ -6825,13 +6830,13 @@ bool AActor::IsFriend (AActor *other) if (deathmatch && teamplay) return IsTeammate(other) || (FriendPlayer != 0 && other->FriendPlayer != 0 && - players[FriendPlayer-1].mo->IsTeammate(players[other->FriendPlayer-1].mo)); + Level->Players[FriendPlayer-1]->mo->IsTeammate(Level->Players[other->FriendPlayer-1]->mo)); return !deathmatch || FriendPlayer == other->FriendPlayer || FriendPlayer == 0 || other->FriendPlayer == 0 || - players[FriendPlayer-1].mo->IsTeammate(players[other->FriendPlayer-1].mo); + Level->Players[FriendPlayer-1]->mo->IsTeammate(Level->Players[other->FriendPlayer-1]->mo); } // [SP] If friendly flags match, then they are on the same team. /*if (!((flags ^ other->flags) & MF_FRIENDLY)) @@ -6858,13 +6863,13 @@ bool AActor::IsHostile (AActor *other) if (deathmatch && teamplay) return !IsTeammate(other) && !(FriendPlayer != 0 && other->FriendPlayer != 0 && - players[FriendPlayer-1].mo->IsTeammate(players[other->FriendPlayer-1].mo)); + Level->Players[FriendPlayer-1]->mo->IsTeammate(Level->Players[other->FriendPlayer-1]->mo)); return deathmatch && FriendPlayer != other->FriendPlayer && FriendPlayer !=0 && other->FriendPlayer != 0 && - !players[FriendPlayer-1].mo->IsTeammate(players[other->FriendPlayer-1].mo); + !Level->Players[FriendPlayer-1]->mo->IsTeammate(Level->Players[other->FriendPlayer-1]->mo); } return true; } diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index a2378b316..b11de948c 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -573,7 +573,7 @@ void P_SerializePlayers(FLevelLocals *Level, FSerializer &arc, bool skipload) // Count the number of players present right now. for (numPlayersNow = 0, i = 0; i < MAXPLAYERS; ++i) { - if (playeringame[i]) + if (Level->PlayerInGame(i)) { ++numPlayersNow; } @@ -879,16 +879,16 @@ void FLevelLocals::SpawnExtraPlayers() // be sure to spawn the extra players. int i; - if (deathmatch) + if (deathmatch || !isPrimaryLevel()) { return; } for (i = 0; i < MAXPLAYERS; ++i) { - if (playeringame[i] && players[i].mo == NULL) + if (PlayerInGame(i) && Players[i]->mo == NULL) { - players[i].playerstate = PST_ENTER; + Players[i]->playerstate = PST_ENTER; SpawnPlayer(&playerstarts[i], i, (flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0); } } @@ -1019,9 +1019,9 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload) } for (int i = 0; i < MAXPLAYERS; ++i) { - if (playeringame[i] && players[i].mo != nullptr) + if (PlayerInGame(i) && Players[i]->mo != nullptr) { - FWeaponSlots::SetupWeaponSlots(players[i].mo); + FWeaponSlots::SetupWeaponSlots(Players[i]->mo); } } RecreateAllAttachedLights(); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 83724cd21..cee9f639b 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -378,13 +378,13 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame) Level->SetMusicVolume(Level->MusicVolume); for (i = 0; i < MAXPLAYERS; ++i) { - players[i].killcount = players[i].secretcount - = players[i].itemcount = 0; + Level->Players[i]->killcount = Level->Players[i]->secretcount + = Level->Players[i]->itemcount = 0; } } for (i = 0; i < MAXPLAYERS; ++i) { - players[i].mo = nullptr; + Level->Players[i]->mo = nullptr; } // [RH] Clear any scripted translation colors the previous level may have set. for (i = 0; i < int(translationtables[TRANSLATION_LevelScripted].Size()); ++i) @@ -439,9 +439,9 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame) { for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i]) + if (Level->PlayerInGame(i)) { - players[i].mo = nullptr; + Level->Players[i]->mo = nullptr; Level->DeathMatchSpawnPlayer(i); } } @@ -451,9 +451,9 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame) { for (i = 0; i < MAXPLAYERS; ++i) { - if (playeringame[i]) + if (Level->PlayerInGame(i)) { - players[i].mo = nullptr; + Level->Players[i]->mo = nullptr; FPlayerStart *mthing = Level->PickPlayerStart(i); Level->SpawnPlayer(mthing, i, (Level->flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0); } @@ -466,11 +466,12 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame) { for (i = 0; i < MAXPLAYERS; ++i) { - if (playeringame[i] && players[i].mo != nullptr) + auto p = Level->Players[i]; + if (Level->PlayerInGame(i) && p->mo != nullptr) { - if (!(players[i].mo->flags & MF_FRIENDLY)) + if (!(p->mo->flags & MF_FRIENDLY)) { - AActor * oldSpawn = players[i].mo; + AActor * oldSpawn = p->mo; Level->DeathMatchSpawnPlayer(i); oldSpawn->Destroy(); }