mirror of https://github.com/ZDoom/gzdoom.git
- redirect most references to the global players array through FLevelLocals.
The Map loader may not access any global state at all - everything it can touch must be exchangable. Furthermore, if we want to sandbox each level, there may be no direct access to any kind of global state whatsoever from the play code.
This commit is contained in:
parent
c15212ca82
commit
8bbdee5c28
|
@ -35,6 +35,7 @@
|
||||||
#include "actor.h"
|
#include "actor.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "g_levellocals.h"
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -61,14 +62,18 @@
|
||||||
Only one selector of each type can be used.
|
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)
|
AActor *COPY_AAPTR(AActor *origin, int selector)
|
||||||
{
|
{
|
||||||
if (selector == AAPTR_DEFAULT) return origin;
|
if (selector == AAPTR_DEFAULT) return origin;
|
||||||
|
|
||||||
FTranslatedLineTarget t;
|
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)
|
||||||
{
|
{
|
||||||
if (origin->player)
|
if (origin->player)
|
||||||
|
|
|
@ -154,12 +154,12 @@ void FS_EmulateCmd(FLevelLocals *Level, char * string)
|
||||||
{
|
{
|
||||||
sc.MustGetFloat();
|
sc.MustGetFloat();
|
||||||
double playerviewheight = sc.Float;
|
double playerviewheight = sc.Float;
|
||||||
for(int i=0;i<MAXPLAYERS;i++)
|
for (auto p : Level->Players)
|
||||||
{
|
{
|
||||||
// No, this is not correct. But this is the way Legacy WADs expect it to be handled!
|
// 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;
|
if (p->mo != nullptr) p->mo->FloatVar(NAME_ViewHeight) = playerviewheight;
|
||||||
players[i].viewheight = playerviewheight;
|
p->viewheight = playerviewheight;
|
||||||
players[i].Uncrouch();
|
p->Uncrouch();
|
||||||
}
|
}
|
||||||
while (sc.GetString())
|
while (sc.GetString())
|
||||||
{
|
{
|
||||||
|
|
|
@ -278,7 +278,7 @@ int FParser::T_GetPlayerNum(const svalue_t &arg)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(!playeringame[playernum]) // no error, just return -1
|
if(!Level->PlayerInGame(playernum)) // no error, just return -1
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ int FParser::T_GetPlayerNum(const svalue_t &arg)
|
||||||
AActor *FParser::T_GetPlayerActor(const svalue_t &arg)
|
AActor *FParser::T_GetPlayerActor(const svalue_t &arg)
|
||||||
{
|
{
|
||||||
int num = T_GetPlayerNum(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)
|
PClassActor *T_ClassType(const svalue_t &arg)
|
||||||
|
@ -659,7 +659,7 @@ void FParser::SF_PlayerTip(void)
|
||||||
if (CheckArgs(1))
|
if (CheckArgs(1))
|
||||||
{
|
{
|
||||||
int plnum = T_GetPlayerNum(t_argv[0]);
|
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());
|
C_MidPrint(SmallFont, GetFormatString(1).GetChars());
|
||||||
}
|
}
|
||||||
|
@ -692,7 +692,7 @@ void FParser::SF_PlayerMsg(void)
|
||||||
if (CheckArgs(1))
|
if (CheckArgs(1))
|
||||||
{
|
{
|
||||||
int plnum = T_GetPlayerNum(t_argv[0]);
|
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());
|
Printf(PRINT_HIGH, "%s\n", GetFormatString(1).GetChars());
|
||||||
}
|
}
|
||||||
|
@ -714,7 +714,7 @@ void FParser::SF_PlayerInGame(void)
|
||||||
if (plnum!=-1)
|
if (plnum!=-1)
|
||||||
{
|
{
|
||||||
t_return.type = svt_int;
|
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)
|
if(plnum !=-1)
|
||||||
{
|
{
|
||||||
t_return.type = svt_string;
|
t_return.type = svt_string;
|
||||||
t_return.string = players[plnum].userinfo.GetName();
|
t_return.string = Level->Players[plnum]->userinfo.GetName();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -773,7 +773,7 @@ void FParser::SF_PlayerObj(void)
|
||||||
if(plnum !=-1)
|
if(plnum !=-1)
|
||||||
{
|
{
|
||||||
t_return.type = svt_mobj;
|
t_return.type = svt_mobj;
|
||||||
t_return.value.mobj = players[plnum].mo;
|
t_return.value.mobj = Level->Players[plnum]->mo;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1402,8 +1402,8 @@ void FParser::SF_SetCamera(void)
|
||||||
|
|
||||||
if (CheckArgs(1))
|
if (CheckArgs(1))
|
||||||
{
|
{
|
||||||
player=Script->trigger->player;
|
player = Script->trigger->player;
|
||||||
if (!player) player=&players[0];
|
if (!player) player = Level->Players[0];
|
||||||
|
|
||||||
newcamera = actorvalue(t_argv[0]);
|
newcamera = actorvalue(t_argv[0]);
|
||||||
if(!newcamera)
|
if(!newcamera)
|
||||||
|
@ -1435,8 +1435,8 @@ void FParser::SF_SetCamera(void)
|
||||||
void FParser::SF_ClearCamera(void)
|
void FParser::SF_ClearCamera(void)
|
||||||
{
|
{
|
||||||
player_t * player;
|
player_t * player;
|
||||||
player=Script->trigger->player;
|
player = Script->trigger->player;
|
||||||
if (!player) player=&players[0];
|
if (!player) player = Level->Players[0];
|
||||||
|
|
||||||
AActor * cam=player->camera;
|
AActor * cam=player->camera;
|
||||||
if (cam)
|
if (cam)
|
||||||
|
@ -2419,13 +2419,13 @@ void FParser::SF_PlayerKeys(void)
|
||||||
if(t_argc == 2)
|
if(t_argc == 2)
|
||||||
{
|
{
|
||||||
t_return.type = svt_int;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
givetake = intvalue(t_argv[2]);
|
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.type = svt_int;
|
||||||
t_return.value.i = 0;
|
t_return.value.i = 0;
|
||||||
}
|
}
|
||||||
|
@ -2504,14 +2504,14 @@ void FParser::SF_PlayerWeapon()
|
||||||
|
|
||||||
if (t_argc == 2)
|
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.type = svt_int;
|
||||||
t_return.value.i = wp!=NULL;
|
t_return.value.i = wp!=NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AActor * wp = players[playernum].mo->FindInventory(ti);
|
AActor * wp = Level->Players[playernum]->mo->FindInventory(ti);
|
||||||
|
|
||||||
newweapon = !!intvalue(t_argv[2]);
|
newweapon = !!intvalue(t_argv[2]);
|
||||||
if (!newweapon)
|
if (!newweapon)
|
||||||
|
@ -2520,14 +2520,14 @@ void FParser::SF_PlayerWeapon()
|
||||||
{
|
{
|
||||||
wp->Destroy();
|
wp->Destroy();
|
||||||
// If the weapon is active pick a replacement. Legacy didn't do this!
|
// If the weapon is active pick a replacement. Legacy didn't do this!
|
||||||
if (players[playernum].PendingWeapon==wp) players[playernum].PendingWeapon=WP_NOCHANGE;
|
if (Level->Players[playernum]->PendingWeapon==wp) Level->Players[playernum]->PendingWeapon=WP_NOCHANGE;
|
||||||
if (players[playernum].ReadyWeapon==wp)
|
if (Level->Players[playernum]->ReadyWeapon==wp)
|
||||||
{
|
{
|
||||||
players[playernum].ReadyWeapon=nullptr;
|
Level->Players[playernum]->ReadyWeapon=nullptr;
|
||||||
|
|
||||||
IFVM(PlayerPawn, PickNewWeapon)
|
IFVM(PlayerPawn, PickNewWeapon)
|
||||||
{
|
{
|
||||||
VMValue param[] = { players[playernum].mo, (void*)nullptr };
|
VMValue param[] = { Level->Players[playernum]->mo, (void*)nullptr };
|
||||||
VMCall(func, param, 2, nullptr, 0);
|
VMCall(func, param, 2, nullptr, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2537,9 +2537,9 @@ void FParser::SF_PlayerWeapon()
|
||||||
{
|
{
|
||||||
if (!wp)
|
if (!wp)
|
||||||
{
|
{
|
||||||
auto pw=players[playernum].PendingWeapon;
|
auto pw=Level->Players[playernum]->PendingWeapon;
|
||||||
players[playernum].mo->GiveInventoryType(ti);
|
Level->Players[playernum]->mo->GiveInventoryType(ti);
|
||||||
players[playernum].PendingWeapon=pw;
|
Level->Players[playernum]->PendingWeapon=pw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2588,13 +2588,13 @@ void FParser::SF_PlayerSelectedWeapon()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
players[playernum].PendingWeapon = players[playernum].mo->FindInventory(ti);
|
Level->Players[playernum]->PendingWeapon = Level->Players[playernum]->mo->FindInventory(ti);
|
||||||
|
|
||||||
}
|
}
|
||||||
t_return.type = svt_int;
|
t_return.type = svt_int;
|
||||||
for(int i=0;i<9;i++)
|
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;
|
t_return.value.i=i;
|
||||||
break;
|
break;
|
||||||
|
@ -2620,7 +2620,7 @@ void FParser::SF_GiveInventory(void)
|
||||||
|
|
||||||
if(t_argc == 2) count=1;
|
if(t_argc == 2) count=1;
|
||||||
else count=intvalue(t_argv[2]);
|
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.type = svt_int;
|
||||||
t_return.value.i = 0;
|
t_return.value.i = 0;
|
||||||
}
|
}
|
||||||
|
@ -2643,7 +2643,7 @@ void FParser::SF_TakeInventory(void)
|
||||||
|
|
||||||
if(t_argc == 2) count=32767;
|
if(t_argc == 2) count=32767;
|
||||||
else count=intvalue(t_argv[2]);
|
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.type = svt_int;
|
||||||
t_return.value.i = 0;
|
t_return.value.i = 0;
|
||||||
}
|
}
|
||||||
|
@ -2668,7 +2668,7 @@ void FParser::SF_CheckInventory(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
t_return.type = svt_int;
|
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]);
|
playernum1 = T_GetPlayerNum(t_argv[0]);
|
||||||
|
|
||||||
players[playernum1].fragcount++;
|
Level->Players[playernum1]->fragcount++;
|
||||||
|
|
||||||
t_return.type = svt_int;
|
t_return.type = svt_int;
|
||||||
t_return.value.f = players[playernum1].fragcount;
|
t_return.value.f = Level->Players[playernum1]->fragcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -3232,10 +3232,10 @@ void FParser::SF_PlayerAddFrag()
|
||||||
playernum1 = T_GetPlayerNum(t_argv[0]);
|
playernum1 = T_GetPlayerNum(t_argv[0]);
|
||||||
playernum2 = T_GetPlayerNum(t_argv[1]);
|
playernum2 = T_GetPlayerNum(t_argv[1]);
|
||||||
|
|
||||||
players[playernum1].frags[playernum2]++;
|
Level->Players[playernum1]->frags[playernum2]++;
|
||||||
|
|
||||||
t_return.type = svt_int;
|
t_return.type = svt_int;
|
||||||
t_return.value.f = players[playernum1].frags[playernum2];
|
t_return.value.f = Level->Players[playernum1]->frags[playernum2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -616,7 +616,7 @@ void T_PreprocessScripts(FLevelLocals *Level)
|
||||||
// get the other scripts
|
// get the other scripts
|
||||||
|
|
||||||
// levelscript started by player 0 'superplayer'
|
// 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->Preprocess(Level);
|
||||||
th->LevelScript->ParseScript(nullptr, th);
|
th->LevelScript->ParseScript(nullptr, th);
|
||||||
|
|
|
@ -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 we get here, that means the actor isn't holding an appropriate key.
|
||||||
|
|
||||||
if (owner == players[consoleplayer].camera)
|
if (owner->CheckLocalView(consoleplayer))
|
||||||
{
|
{
|
||||||
PrintMessage(failtext);
|
PrintMessage(failtext);
|
||||||
|
|
||||||
|
|
|
@ -835,12 +835,12 @@ bool FLevelLocals::DoCompleted (FString nextlevel, wbstartstruct_t &wminfo)
|
||||||
|
|
||||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||||
{
|
{
|
||||||
wminfo.plyr[i].skills = players[i].killcount;
|
wminfo.plyr[i].skills = Players[i]->killcount;
|
||||||
wminfo.plyr[i].sitems = players[i].itemcount;
|
wminfo.plyr[i].sitems = Players[i]->itemcount;
|
||||||
wminfo.plyr[i].ssecret = players[i].secretcount;
|
wminfo.plyr[i].ssecret = Players[i]->secretcount;
|
||||||
wminfo.plyr[i].stime = time;
|
wminfo.plyr[i].stime = time;
|
||||||
memcpy (wminfo.plyr[i].frags, players[i].frags, sizeof(wminfo.plyr[i].frags));
|
memcpy (wminfo.plyr[i].frags, Players[i]->frags, sizeof(wminfo.plyr[i].frags));
|
||||||
wminfo.plyr[i].fragcount = players[i].fragcount;
|
wminfo.plyr[i].fragcount = Players[i]->fragcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [RH] If we're in a hub and staying within that hub, take a snapshot.
|
// [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++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (playeringame[i] && (deathmatch || players[i].playerstate == PST_DEAD))
|
if (PlayerInGame(i) && (deathmatch || Players[i]->playerstate == PST_DEAD))
|
||||||
players[i].playerstate = PST_ENTER; // [BC]
|
Players[i]->playerstate = PST_ENTER; // [BC]
|
||||||
memset (players[i].frags,0,sizeof(players[i].frags));
|
memset (Players[i]->frags,0,sizeof(Players[i]->frags));
|
||||||
if (!(dmflags2 & DF2_YES_KEEPFRAGS) && (alwaysapplydmflags || deathmatch))
|
if (!(dmflags2 & DF2_YES_KEEPFRAGS) && (alwaysapplydmflags || deathmatch))
|
||||||
players[i].fragcount = 0;
|
Players[i]->fragcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changeflags & CHANGELEVEL_NOMONSTERS)
|
if (changeflags & CHANGELEVEL_NOMONSTERS)
|
||||||
|
@ -1093,19 +1093,19 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au
|
||||||
{
|
{
|
||||||
for (int i = 0; i<MAXPLAYERS; i++)
|
for (int i = 0; i<MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (playeringame[i] && players[i].mo != NULL)
|
if (PlayerInGame(i) && Players[i]->mo != nullptr)
|
||||||
P_PlayerStartStomp(players[i].mo);
|
P_PlayerStartStomp(Players[i]->mo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each player, if they are viewing through a player, make sure it is themselves.
|
// For each player, if they are viewing through a player, make sure it is themselves.
|
||||||
for (int ii = 0; ii < MAXPLAYERS; ++ii)
|
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)
|
if (savegamerestore)
|
||||||
|
@ -1119,7 +1119,7 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au
|
||||||
if (fromSnapshot)
|
if (fromSnapshot)
|
||||||
{
|
{
|
||||||
// ENTER scripts are being handled when the player gets spawned, this cannot be changed due to its effect on voodoo dolls.
|
// 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.
|
// Strife needs a special case here to choose between good and sad ending. Bad is handled elsewhere.
|
||||||
if (endsequence == NAME_Inter_Strife)
|
if (endsequence == NAME_Inter_Strife)
|
||||||
{
|
{
|
||||||
if (players[0].mo->FindInventory (NAME_QuestItem25) ||
|
if (Players[0]->mo->FindInventory (NAME_QuestItem25) ||
|
||||||
players[0].mo->FindInventory (NAME_QuestItem28))
|
Players[0]->mo->FindInventory (NAME_QuestItem28))
|
||||||
{
|
{
|
||||||
endsequence = NAME_Inter_Strife_Good;
|
endsequence = NAME_Inter_Strife_Good;
|
||||||
}
|
}
|
||||||
|
@ -1317,12 +1317,12 @@ void FLevelLocals::StartTravel ()
|
||||||
{
|
{
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
{
|
{
|
||||||
AActor *pawn = players[i].mo;
|
AActor *pawn = Players[i]->mo;
|
||||||
AActor *inv;
|
AActor *inv;
|
||||||
players[i].camera = nullptr;
|
Players[i]->camera = nullptr;
|
||||||
|
|
||||||
// Only living players travel. Dead ones get a new body on the new level.
|
// 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);
|
pawn->UnlinkFromWorld (nullptr);
|
||||||
int tid = pawn->tid; // Save TID
|
int tid = pawn->tid; // Save TID
|
||||||
|
@ -1721,14 +1721,14 @@ void FLevelLocals::UnSnapshotLevel (bool hubLoad)
|
||||||
while ((pawn = next) != 0)
|
while ((pawn = next) != 0)
|
||||||
{
|
{
|
||||||
next = it.Next();
|
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;
|
int i;
|
||||||
|
|
||||||
// If this isn't the unmorphed original copy of a player, destroy it, because it's extra.
|
// If this isn't the unmorphed original copy of a player, destroy it, because it's extra.
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
#include "actor.h"
|
#include "actor.h"
|
||||||
#include "p_effect.h"
|
#include "p_effect.h"
|
||||||
|
#include "d_player.h"
|
||||||
#include "p_destructible.h"
|
#include "p_destructible.h"
|
||||||
#include "r_data/r_sections.h"
|
#include "r_data/r_sections.h"
|
||||||
#include "r_data/r_canvastexture.h"
|
#include "r_data/r_canvastexture.h"
|
||||||
|
@ -102,7 +103,15 @@ struct FLevelLocals
|
||||||
{
|
{
|
||||||
void *level;
|
void *level;
|
||||||
void *Level; // bug catchers.
|
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;
|
friend class MapLoader;
|
||||||
|
|
||||||
|
@ -494,6 +503,42 @@ public:
|
||||||
TObjPtr<DAutomapBase*> automap = nullptr;
|
TObjPtr<DAutomapBase*> automap = nullptr;
|
||||||
int bodyqueslot;
|
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;
|
int NumMapSections;
|
||||||
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
|
@ -122,9 +122,9 @@ void DEarthquake::Tick ()
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
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;
|
double dist;
|
||||||
|
|
||||||
dist = m_Spot->Distance2D(victim, true);
|
dist = m_Spot->Distance2D(victim, true);
|
||||||
|
|
|
@ -3247,8 +3247,8 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
|
||||||
|
|
||||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
if (playeringame[i] && players[i].mo != nullptr)
|
if (Level->PlayerInGame(i) && Level->Players[i]->mo != nullptr)
|
||||||
players[i].health = players[i].mo->health;
|
Level->Players[i]->health = Level->Players[i]->mo->health;
|
||||||
}
|
}
|
||||||
if (!map->HasBehavior && !map->isText)
|
if (!map->HasBehavior && !map->isText)
|
||||||
TranslateTeleportThings(); // [RH] Assign teleport destination TIDs
|
TranslateTeleportThings(); // [RH] Assign teleport destination TIDs
|
||||||
|
|
|
@ -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;
|
PClassActor *info;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -1743,8 +1743,8 @@ static int UseInventory (AActor *activator, const char *type)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
if (playeringame[i])
|
if (Level->PlayerInGame(i))
|
||||||
ret += DoUseInv (players[i].mo, info);
|
ret += DoUseInv (Level->Players[i]->mo, info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1759,6 +1759,7 @@ static int UseInventory (AActor *activator, const char *type)
|
||||||
// CheckInventory
|
// CheckInventory
|
||||||
//
|
//
|
||||||
// Returns how much of a particular item an actor has.
|
// 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;
|
int count = 0, i;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
if (playeringame[i])
|
if (Level->PlayerInGame(i))
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -3850,9 +3851,9 @@ void DLevelScript::DoFadeRange (int r1, int g1, int b1, int a1,
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
for (i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
if (playeringame[i])
|
if (Level->PlayerInGame(i))
|
||||||
{
|
{
|
||||||
viewer = &players[i];
|
viewer = Level->Players[i];
|
||||||
showme:
|
showme:
|
||||||
if (ftime <= 0.f)
|
if (ftime <= 0.f)
|
||||||
{
|
{
|
||||||
|
@ -3965,7 +3966,7 @@ int DoGetMasterTID (AActor *self)
|
||||||
if (self->master) return self->master->tid;
|
if (self->master) return self->master->tid;
|
||||||
else if (self->FriendPlayer)
|
else if (self->FriendPlayer)
|
||||||
{
|
{
|
||||||
player_t *player = &players[(self->FriendPlayer)-1];
|
player_t *player = self->Level->Players[(self->FriendPlayer)-1];
|
||||||
return player->mo->tid;
|
return player->mo->tid;
|
||||||
}
|
}
|
||||||
else return 0;
|
else return 0;
|
||||||
|
@ -4504,13 +4505,13 @@ int DLevelScript::GetPlayerInput(int playernum, int inputnum)
|
||||||
}
|
}
|
||||||
p = activator->player;
|
p = activator->player;
|
||||||
}
|
}
|
||||||
else if (playernum >= MAXPLAYERS || !playeringame[playernum])
|
else if (playernum >= MAXPLAYERS || !Level->PlayerInGame(playernum))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p = &players[playernum];
|
p = Level->Players[playernum];
|
||||||
}
|
}
|
||||||
if (p == NULL)
|
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)
|
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;
|
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;
|
FBaseCVar *cvar;
|
||||||
// Only mod-created cvars may be set.
|
// Only mod-created cvars may be set.
|
||||||
if (cvar_p == NULL || (cvar = *cvar_p) == NULL || (cvar->GetFlags() & CVAR_IGNORE) || !(cvar->GetFlags() & CVAR_MOD))
|
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);
|
DoSetCVar(cvar, value, is_string);
|
||||||
|
|
||||||
// If we are this player, then also reflect this change in the local version of this cvar.
|
// 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);
|
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,
|
// 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 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);
|
DoSetCVar(cvar, value, is_string);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -5388,25 +5391,25 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
||||||
|
|
||||||
case ACSF_GetAirSupply:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return players[args[0]].air_finished - Level->time;
|
return Level->Players[args[0]]->air_finished - Level->time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case ACSF_SetAirSupply:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
players[args[0]].air_finished = args[1] + Level->time;
|
Level->Players[args[0]]->air_finished = args[1] + Level->time;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5420,14 +5423,14 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
||||||
|
|
||||||
case ACSF_GetArmorType:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FName p(Level->Behaviors.LookupString(args[0]));
|
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);
|
if (armor && armor->NameVar(NAME_ArmorType) == p) return armor->IntVar(NAME_Amount);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -8454,9 +8457,9 @@ scriptwait:
|
||||||
player = activator->player;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -8610,6 +8613,7 @@ scriptwait:
|
||||||
{
|
{
|
||||||
optstart = sp;
|
optstart = sp;
|
||||||
}
|
}
|
||||||
|
if (Level->isPrimaryLevel())
|
||||||
{
|
{
|
||||||
AActor *screen = activator;
|
AActor *screen = activator;
|
||||||
if (screen != NULL &&
|
if (screen != NULL &&
|
||||||
|
@ -9198,7 +9202,7 @@ scriptwait:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCD_USEINVENTORY:
|
case PCD_USEINVENTORY:
|
||||||
STACK(1) = UseInventory (activator, Level->Behaviors.LookupString (STACK(1)));
|
STACK(1) = UseInventory (Level, activator, Level->Behaviors.LookupString (STACK(1)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCD_USEACTORINVENTORY:
|
case PCD_USEACTORINVENTORY:
|
||||||
|
@ -9207,7 +9211,7 @@ scriptwait:
|
||||||
const char *type = Level->Behaviors.LookupString(STACK(1));
|
const char *type = Level->Behaviors.LookupString(STACK(1));
|
||||||
if (STACK(2) == 0)
|
if (STACK(2) == 0)
|
||||||
{
|
{
|
||||||
ret = UseInventory(NULL, type);
|
ret = UseInventory(Level, NULL, type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -9215,7 +9219,7 @@ scriptwait:
|
||||||
AActor *actor;
|
AActor *actor;
|
||||||
for (actor = it.Next(); actor != NULL; actor = it.Next())
|
for (actor = it.Next(); actor != NULL; actor = it.Next())
|
||||||
{
|
{
|
||||||
ret += UseInventory(actor, type);
|
ret += UseInventory(Level, actor, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
STACK(2) = ret;
|
STACK(2) = ret;
|
||||||
|
@ -9655,18 +9659,18 @@ scriptwait:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
STACK(1) = playeringame[STACK(1)];
|
STACK(1) = Level->PlayerInGame(STACK(1));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCD_PLAYERISBOT:
|
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;
|
STACK(1) = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
STACK(1) = (players[STACK(1)].Bot != NULL);
|
STACK(1) = (Level->Players[STACK(1)]->Bot != nullptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -9858,24 +9862,24 @@ scriptwait:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCD_PLAYERCLASS: // [GRB]
|
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;
|
STACK(1) = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
STACK(1) = players[STACK(1)].CurrentPlayerClass;
|
STACK(1) = Level->Players[STACK(1)]->CurrentPlayerClass;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCD_GETPLAYERINFO: // [GRB]
|
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;
|
STACK(2) = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
player_t *pl = &players[STACK(2)];
|
player_t *pl = Level->Players[STACK(2)];
|
||||||
userinfo_t *userinfo = &pl->userinfo;
|
userinfo_t *userinfo = &pl->userinfo;
|
||||||
switch (STACK(1))
|
switch (STACK(1))
|
||||||
{
|
{
|
||||||
|
@ -9973,13 +9977,14 @@ scriptwait:
|
||||||
{
|
{
|
||||||
int playernum = STACK(1);
|
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;
|
STACK(1) = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
STACK(1) = players[playernum].camera->tid;
|
STACK(1) = Level->Players[playernum]->camera->tid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -10301,8 +10306,8 @@ void FLevelLocals::DoDeferedScripts ()
|
||||||
if (scriptdata)
|
if (scriptdata)
|
||||||
{
|
{
|
||||||
P_GetScriptGoing (this, (unsigned)def->playernum < MAXPLAYERS &&
|
P_GetScriptGoing (this, (unsigned)def->playernum < MAXPLAYERS &&
|
||||||
playeringame[def->playernum] ? players[def->playernum].mo : NULL,
|
PlayerInGame(def->playernum) ? Players[def->playernum]->mo : nullptr,
|
||||||
NULL, def->script,
|
nullptr, def->script,
|
||||||
scriptdata, module,
|
scriptdata, module,
|
||||||
def->args, 3,
|
def->args, 3,
|
||||||
def->type == acsdefered_t::defexealways ? ACS_ALWAYS : 0);
|
def->type == acsdefered_t::defexealways ? ACS_ALWAYS : 0);
|
||||||
|
|
|
@ -1684,18 +1684,20 @@ DEFINE_ACTION_FUNCTION(AActor, CheckIfSeen)
|
||||||
{
|
{
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
|
||||||
|
auto Level = self->Level;
|
||||||
for (int i = 0; i < MAXPLAYERS; i++)
|
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.
|
// 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);
|
ACTION_RETURN_BOOL(false);
|
||||||
}
|
}
|
||||||
// If a player is viewing from a non-player, then check that too.
|
// If a player is viewing from a non-player, then check that too.
|
||||||
if (players[i].camera != NULL && players[i].camera->player == NULL &&
|
if (p->camera != nullptr && p->camera->player == NULL &&
|
||||||
P_CheckSight(players[i].camera, self, SF_IGNOREVISIBILITY))
|
P_CheckSight(p->camera, self, SF_IGNOREVISIBILITY))
|
||||||
{
|
{
|
||||||
ACTION_RETURN_BOOL(false);
|
ACTION_RETURN_BOOL(false);
|
||||||
}
|
}
|
||||||
|
@ -1755,18 +1757,20 @@ DEFINE_ACTION_FUNCTION(AActor, CheckSightOrRange)
|
||||||
PARAM_BOOL(twodi);
|
PARAM_BOOL(twodi);
|
||||||
|
|
||||||
range *= range;
|
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.
|
// 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);
|
ACTION_RETURN_BOOL(false);
|
||||||
}
|
}
|
||||||
// If a player is viewing from a non-player, check that too.
|
// If a player is viewing from a non-player, check that too.
|
||||||
if (players[i].camera != NULL && players[i].camera->player == NULL &&
|
if (p->camera != nullptr && p->camera->player == nullptr &&
|
||||||
DoCheckSightOrRange(self, players[i].camera, range, twodi, true))
|
DoCheckSightOrRange(self, p->camera, range, twodi, true))
|
||||||
{
|
{
|
||||||
ACTION_RETURN_BOOL(false);
|
ACTION_RETURN_BOOL(false);
|
||||||
}
|
}
|
||||||
|
@ -1783,18 +1787,20 @@ DEFINE_ACTION_FUNCTION(AActor, CheckRange)
|
||||||
PARAM_BOOL(twodi);
|
PARAM_BOOL(twodi);
|
||||||
|
|
||||||
range *= range;
|
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.
|
// 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);
|
ACTION_RETURN_BOOL(false);
|
||||||
}
|
}
|
||||||
// If a player is viewing from a non-player, check that too.
|
// If a player is viewing from a non-player, check that too.
|
||||||
if (players[i].camera != NULL && players[i].camera->player == NULL &&
|
if (p->camera != nullptr && p->camera->player == nullptr &&
|
||||||
DoCheckSightOrRange(self, players[i].camera, range, twodi, false))
|
DoCheckSightOrRange(self, p->camera, range, twodi, false))
|
||||||
{
|
{
|
||||||
ACTION_RETURN_BOOL(false);
|
ACTION_RETURN_BOOL(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -738,7 +738,7 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Make sure this is actually a player.
|
// 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;
|
auto Level = pc->Level;
|
||||||
|
|
||||||
// [CW] If an NPC is talking to a PC already, then don't let
|
// [CW] If an NPC is talking to a PC already, then don't let
|
||||||
|
|
|
@ -324,10 +324,6 @@ void P_SpawnParticle(FLevelLocals *Level, const DVector3 &pos, const DVector3 &v
|
||||||
//
|
//
|
||||||
void P_RunEffects (FLevelLocals *Level)
|
void P_RunEffects (FLevelLocals *Level)
|
||||||
{
|
{
|
||||||
if (players[consoleplayer].camera == NULL) return;
|
|
||||||
|
|
||||||
int pnum = players[consoleplayer].camera->Sector->Index() * Level->sectors.Size();
|
|
||||||
|
|
||||||
AActor *actor;
|
AActor *actor;
|
||||||
auto iterator = Level->GetThinkerIterator<AActor>();
|
auto iterator = Level->GetThinkerIterator<AActor>();
|
||||||
|
|
||||||
|
|
|
@ -1005,12 +1005,12 @@ void P_RandomChaseDir (AActor *actor)
|
||||||
{
|
{
|
||||||
i = 0;
|
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))
|
if (pr_newchasedir() & 1 || !P_CheckSight (actor, player))
|
||||||
{
|
{
|
||||||
|
@ -1203,7 +1203,7 @@ int P_LookForMonsters (AActor *actor)
|
||||||
AActor *mo;
|
AActor *mo;
|
||||||
auto iterator = actor->Level->GetThinkerIterator<AActor>();
|
auto iterator = actor->Level->GetThinkerIterator<AActor>();
|
||||||
|
|
||||||
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
|
{ // Player can't see monster
|
||||||
return false;
|
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
|
// Go back to a player, no matter whether it's visible or not
|
||||||
for (int anyone=0; anyone<=1; anyone++)
|
for (int anyone=0; anyone<=1; anyone++)
|
||||||
{
|
{
|
||||||
|
auto Level = actor->Level;
|
||||||
for (int c=0; c<MAXPLAYERS; c++)
|
for (int c=0; c<MAXPLAYERS; c++)
|
||||||
{
|
{
|
||||||
if (playeringame[c] && players[c].playerstate==PST_LIVE &&
|
auto p = Level->Players[i];
|
||||||
actor->IsFriend(players[c].mo) &&
|
if (Level->PlayerInGame(c) && p->playerstate==PST_LIVE &&
|
||||||
(anyone || P_IsVisible(actor, players[c].mo, allaround)))
|
actor->IsFriend(p->mo) &&
|
||||||
|
(anyone || P_IsVisible(actor, p->mo, allaround)))
|
||||||
{
|
{
|
||||||
actor->target = players[c].mo;
|
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
|
} // [SP] if false, and in deathmatch, intentional fall-through
|
||||||
|
|
||||||
if (!(gameinfo.gametype & (GAME_DoomStrifeChex)) &&
|
if (!(gameinfo.gametype & (GAME_DoomStrifeChex)) &&
|
||||||
|
actor->Level->isPrimaryLevel() &&
|
||||||
!multiplayer &&
|
!multiplayer &&
|
||||||
players[0].health <= 0 &&
|
actor->Level->Players[0]->health <= 0 &&
|
||||||
actor->goal == NULL &&
|
actor->goal == NULL &&
|
||||||
gamestate != GS_TITLELEVEL
|
gamestate != GS_TITLELEVEL
|
||||||
)
|
)
|
||||||
|
@ -1648,7 +1651,7 @@ int P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params)
|
||||||
if (c++ < MAXPLAYERS)
|
if (c++ < MAXPLAYERS)
|
||||||
{
|
{
|
||||||
pnum = (pnum + 1) & (MAXPLAYERS - 1);
|
pnum = (pnum + 1) & (MAXPLAYERS - 1);
|
||||||
if (!playeringame[pnum])
|
if (!actor->Level->PlayerInGame(pnum))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (actor->TIDtoHate == 0)
|
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;
|
return actor->target == actor->goal && actor->goal != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
player = &players[pnum];
|
player = actor->Level->Players[pnum];
|
||||||
|
|
||||||
if (!(player->mo->flags & MF_SHOOTABLE))
|
if (!(player->mo->flags & MF_SHOOTABLE))
|
||||||
continue; // not shootable (observer or dead)
|
continue; // not shootable (observer or dead)
|
||||||
|
|
||||||
if (!((actor->flags ^ player->mo->flags) & MF_FRIENDLY))
|
if (actor->IsFriend(player->mo))
|
||||||
continue; // same +MF_FRIENDLY, ignore
|
continue; // same +MF_FRIENDLY, ignore
|
||||||
|
|
||||||
if (player->cheats & CF_NOTARGET)
|
if (player->cheats & CF_NOTARGET)
|
||||||
|
@ -2284,7 +2287,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
|
||||||
|
|
||||||
if (actor->FriendPlayer != 0)
|
if (actor->FriendPlayer != 0)
|
||||||
{
|
{
|
||||||
player = &players[actor->FriendPlayer - 1];
|
player = actor->Level->Players[actor->FriendPlayer - 1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2293,10 +2296,10 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
|
||||||
{
|
{
|
||||||
i = 0;
|
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)
|
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
|
// make sure there is a player alive for victory
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
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;
|
break;
|
||||||
|
|
||||||
if (i == MAXPLAYERS)
|
if (i == MAXPLAYERS)
|
||||||
|
|
|
@ -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,
|
// count all monster deaths,
|
||||||
// even those caused by other monsters
|
// even those caused by other monsters
|
||||||
players[0].killcount++;
|
Level->Players[0]->killcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player)
|
if (player)
|
||||||
|
@ -577,11 +577,12 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
|
||||||
//Added by MC: Discard enemies.
|
//Added by MC: Discard enemies.
|
||||||
for (int i = 0; i < MAXPLAYERS; i++)
|
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)
|
if (Bot->dest == Bot->enemy)
|
||||||
players[i].Bot->dest = nullptr;
|
Bot->dest = nullptr;
|
||||||
players[i].Bot->enemy = nullptr;
|
Bot->enemy = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2835,24 +2835,25 @@ FUNC(LS_ChangeCamera)
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (!playeringame[i])
|
if (!Level->PlayerInGame(i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AActor *oldcamera = players[i].camera;
|
auto p = Level->Players[i];
|
||||||
|
AActor *oldcamera = p->camera;
|
||||||
if (camera)
|
if (camera)
|
||||||
{
|
{
|
||||||
players[i].camera = camera;
|
p->camera = camera;
|
||||||
if (arg2)
|
if (arg2)
|
||||||
players[i].cheats |= CF_REVERTPLEASE;
|
p->cheats |= CF_REVERTPLEASE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
players[i].camera = players[i].mo;
|
p->camera = p->mo;
|
||||||
players[i].cheats &= ~CF_REVERTPLEASE;
|
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++)
|
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;
|
continue;
|
||||||
|
|
||||||
if (arg1)
|
if (arg1)
|
||||||
{ // Give power
|
{ // Give power
|
||||||
if (power != 4)
|
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)
|
if (item != NULL && power == 0 && arg1 == 1)
|
||||||
{
|
{
|
||||||
item->ColorVar(NAME_BlendColor) = MakeSpecialColormap(INVERSECOLORMAP);
|
item->ColorVar(NAME_BlendColor) = MakeSpecialColormap(INVERSECOLORMAP);
|
||||||
|
@ -2999,7 +3001,7 @@ FUNC(LS_SetPlayerProperty)
|
||||||
{ // Take power
|
{ // Take power
|
||||||
if (power != 4)
|
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)
|
if (item != NULL)
|
||||||
{
|
{
|
||||||
item->Destroy ();
|
item->Destroy ();
|
||||||
|
@ -3072,25 +3074,26 @@ FUNC(LS_SetPlayerProperty)
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (!playeringame[i])
|
if (!Level->PlayerInGame(i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
auto p = Level->Players[i];
|
||||||
if (arg1)
|
if (arg1)
|
||||||
{
|
{
|
||||||
players[i].cheats |= mask;
|
p->cheats |= mask;
|
||||||
if (arg2 == PROP_FLY)
|
if (arg2 == PROP_FLY)
|
||||||
{
|
{
|
||||||
players[i].mo->flags2 |= MF2_FLY;
|
p->mo->flags2 |= MF2_FLY;
|
||||||
players[i].mo->flags |= MF_NOGRAVITY;
|
p->mo->flags |= MF_NOGRAVITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
players[i].cheats &= ~mask;
|
p->cheats &= ~mask;
|
||||||
if (arg2 == PROP_FLY)
|
if (arg2 == PROP_FLY)
|
||||||
{
|
{
|
||||||
players[i].mo->flags2 &= ~MF2_FLY;
|
p->mo->flags2 &= ~MF2_FLY;
|
||||||
players[i].mo->flags &= ~MF_NOGRAVITY;
|
p->mo->flags &= ~MF_NOGRAVITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3310,9 +3313,9 @@ FUNC(LS_GlassBreak)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
if (playeringame[i])
|
if (Level->PlayerInGame(i))
|
||||||
{
|
{
|
||||||
it = players[i].mo;
|
it = Level->Players[i]->mo;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -945,16 +945,17 @@ DEFINE_ACTION_FUNCTION(AActor, GiveBody)
|
||||||
|
|
||||||
bool AActor::CheckLocalView (int playernum) const
|
bool AActor::CheckLocalView (int playernum) const
|
||||||
{
|
{
|
||||||
if (players[playernum].camera == this)
|
auto p = &players[playernum];
|
||||||
|
if (p->camera == this)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (players[playernum].mo != this || players[playernum].camera == NULL)
|
if (p->mo != this || p->camera == nullptr)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (players[playernum].camera->player == NULL &&
|
if (p->camera->player == NULL &&
|
||||||
!(players[playernum].camera->flags3 & MF3_ISMONSTER))
|
!(p->camera->flags3 & MF3_ISMONSTER))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -985,6 +986,10 @@ bool AActor::IsInsideVisibleAngles() const
|
||||||
if (players[consoleplayer].camera == nullptr)
|
if (players[consoleplayer].camera == nullptr)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Not detectable.
|
||||||
|
if (!Level->isPrimaryLevel())
|
||||||
|
return true;
|
||||||
|
|
||||||
DAngle anglestart = VisibleStartAngle;
|
DAngle anglestart = VisibleStartAngle;
|
||||||
DAngle angleend = VisibleEndAngle;
|
DAngle angleend = VisibleEndAngle;
|
||||||
DAngle pitchstart = VisibleStartPitch;
|
DAngle pitchstart = VisibleStartPitch;
|
||||||
|
@ -3264,7 +3269,7 @@ bool AActor::IsOkayToAttack (AActor *link)
|
||||||
AActor * Friend;
|
AActor * Friend;
|
||||||
if (flags5 & MF5_SUMMONEDMONSTER) Friend = tracer;
|
if (flags5 & MF5_SUMMONEDMONSTER) Friend = tracer;
|
||||||
else if (flags2 & MF2_SEEKERMISSILE) Friend = target;
|
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;
|
else Friend = this;
|
||||||
|
|
||||||
// Friend checks
|
// Friend checks
|
||||||
|
@ -5052,9 +5057,9 @@ AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flag
|
||||||
|
|
||||||
for (int ii = 0; ii < MAXPLAYERS; ++ii)
|
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)
|
if (deathmatch && teamplay)
|
||||||
return IsTeammate(other) ||
|
return IsTeammate(other) ||
|
||||||
(FriendPlayer != 0 && other->FriendPlayer != 0 &&
|
(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 ||
|
return !deathmatch ||
|
||||||
FriendPlayer == other->FriendPlayer ||
|
FriendPlayer == other->FriendPlayer ||
|
||||||
FriendPlayer == 0 ||
|
FriendPlayer == 0 ||
|
||||||
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);
|
||||||
}
|
}
|
||||||
// [SP] If friendly flags match, then they are on the same team.
|
// [SP] If friendly flags match, then they are on the same team.
|
||||||
/*if (!((flags ^ other->flags) & MF_FRIENDLY))
|
/*if (!((flags ^ other->flags) & MF_FRIENDLY))
|
||||||
|
@ -6858,13 +6863,13 @@ bool AActor::IsHostile (AActor *other)
|
||||||
if (deathmatch && teamplay)
|
if (deathmatch && teamplay)
|
||||||
return !IsTeammate(other) &&
|
return !IsTeammate(other) &&
|
||||||
!(FriendPlayer != 0 && other->FriendPlayer != 0 &&
|
!(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 &&
|
return deathmatch &&
|
||||||
FriendPlayer != other->FriendPlayer &&
|
FriendPlayer != other->FriendPlayer &&
|
||||||
FriendPlayer !=0 &&
|
FriendPlayer !=0 &&
|
||||||
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 true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -573,7 +573,7 @@ void P_SerializePlayers(FLevelLocals *Level, FSerializer &arc, bool skipload)
|
||||||
// Count the number of players present right now.
|
// Count the number of players present right now.
|
||||||
for (numPlayersNow = 0, i = 0; i < MAXPLAYERS; ++i)
|
for (numPlayersNow = 0, i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
if (playeringame[i])
|
if (Level->PlayerInGame(i))
|
||||||
{
|
{
|
||||||
++numPlayersNow;
|
++numPlayersNow;
|
||||||
}
|
}
|
||||||
|
@ -879,16 +879,16 @@ void FLevelLocals::SpawnExtraPlayers()
|
||||||
// be sure to spawn the extra players.
|
// be sure to spawn the extra players.
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (deathmatch)
|
if (deathmatch || !isPrimaryLevel())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
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);
|
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)
|
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();
|
RecreateAllAttachedLights();
|
||||||
|
|
|
@ -378,13 +378,13 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame)
|
||||||
Level->SetMusicVolume(Level->MusicVolume);
|
Level->SetMusicVolume(Level->MusicVolume);
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
for (i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
players[i].killcount = players[i].secretcount
|
Level->Players[i]->killcount = Level->Players[i]->secretcount
|
||||||
= players[i].itemcount = 0;
|
= Level->Players[i]->itemcount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
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.
|
// [RH] Clear any scripted translation colors the previous level may have set.
|
||||||
for (i = 0; i < int(translationtables[TRANSLATION_LevelScripted].Size()); ++i)
|
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++)
|
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);
|
Level->DeathMatchSpawnPlayer(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,9 +451,9 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame)
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
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);
|
FPlayerStart *mthing = Level->PickPlayerStart(i);
|
||||||
Level->SpawnPlayer(mthing, i, (Level->flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
|
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)
|
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);
|
Level->DeathMatchSpawnPlayer(i);
|
||||||
oldSpawn->Destroy();
|
oldSpawn->Destroy();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue