Skip to content

Commit

Permalink
Added PlayerRespawning event
Browse files Browse the repository at this point in the history
Allows denying player respawns for better control on special game modes e.g. Last Man Standing.
  • Loading branch information
Boondorl authored and madame-rachelle committed Feb 14, 2025
1 parent 567a180 commit a7d4d40
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 5 deletions.
34 changes: 34 additions & 0 deletions src/events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,24 @@ void EventManager::PlayerSpawned(int num)
handler->PlayerSpawned(num);
}

bool EventManager::PlayerRespawning(int num)
{
if (ShouldCallStatic(true))
{
bool res = staticEventManager.PlayerRespawning(num);
if (!res)
return false;
}

for (DStaticEventHandler* handler = FirstEventHandler; handler; handler = handler->next)
{
if (!handler->PlayerRespawning(num))
return false;
}

return true;
}

void EventManager::PlayerRespawned(int num)
{
if (ShouldCallStatic(true)) staticEventManager.PlayerRespawned(num);
Expand Down Expand Up @@ -2131,6 +2149,22 @@ void DStaticEventHandler::PlayerSpawned(int num)
}
}

bool DStaticEventHandler::PlayerRespawning(int num)
{
int res = true;
IFVIRTUAL(DStaticEventHandler, PlayerRespawning)
{
// don't create excessive DObjects if not going to be processed anyway
if (isEmpty(func)) return res;
FPlayerEvent e = { num, false };
VMValue params[] = { (DStaticEventHandler*)this, &e };
VMReturn returns[] = { &res };
VMCall(func, params, 2, returns, 1);
}

return res;
}

void DStaticEventHandler::PlayerRespawned(int num)
{
IFVIRTUAL(DStaticEventHandler, PlayerRespawned)
Expand Down
3 changes: 3 additions & 0 deletions src/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ class DStaticEventHandler : public DObject // make it a part of normal GC proces
//
void PlayerEntered(int num, bool fromhub);
void PlayerSpawned(int num);
bool PlayerRespawning(int num);
void PlayerRespawned(int num);
void PlayerDied(int num);
void PlayerDisconnected(int num);
Expand Down Expand Up @@ -524,6 +525,8 @@ struct EventManager
void PlayerEntered(int num, bool fromhub);
// this executes at the same time as ENTER scripts
void PlayerSpawned(int num);
// Executes when a player is attempting to respawn. Does not include resurrect cheat.
bool PlayerRespawning(int num);
// this executes when a player respawns. includes resurrect cheat.
void PlayerRespawned(int num);
// this executes when a player dies (partially duplicating worldthingdied, but whatever)
Expand Down
11 changes: 9 additions & 2 deletions src/g_game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1153,7 +1153,7 @@ void G_Ticker ()
}
if (players[i].playerstate == PST_REBORN || players[i].playerstate == PST_ENTER)
{
primaryLevel->DoReborn(i, false);
primaryLevel->DoReborn(i);
}
}
}
Expand Down Expand Up @@ -1766,7 +1766,7 @@ void FLevelLocals::QueueBody (AActor *body)
// G_DoReborn
//
EXTERN_CVAR(Bool, sv_singleplayerrespawn)
void FLevelLocals::DoReborn (int playernum, bool freshbot)
void FLevelLocals::DoReborn (int playernum, bool force)
{
if (!multiplayer && !(flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn &&
!G_SkillProperty(SKILLP_PlayerRespawn))
Expand All @@ -1786,6 +1786,13 @@ void FLevelLocals::DoReborn (int playernum, bool freshbot)
}
else
{
// Check if the player should be allowed to actually respawn first.
if (!force && players[playernum].playerstate == PST_REBORN && !localEventManager->PlayerRespawning(playernum))
{
players[playernum].playerstate = PST_DEAD;
return;
}

bool isUnfriendly;

PlayerSpawnPickClass(playernum);
Expand Down
2 changes: 1 addition & 1 deletion src/g_level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ void FLevelLocals::ChangeLevel(const char *levelname, int position, int inflags,
player->mo->special1 = 0;
}
// ]]
DoReborn(i, false);
DoReborn(i, true);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/g_levellocals.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ struct FLevelLocals
// g_Game
void PlayerReborn (int player);
bool CheckSpot (int playernum, FPlayerStart *mthing);
void DoReborn (int playernum, bool freshbot);
void DoReborn (int playernum, bool force = false);
void QueueBody (AActor *body);
double PlayersRangeFromSpot (FPlayerStart *spot);
FPlayerStart *SelectFarthestDeathmatchSpot (size_t selections);
Expand Down
2 changes: 1 addition & 1 deletion src/playsim/bots/b_game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ bool FCajunMaster::DoAddBot (FLevelLocals *Level, uint8_t *info, botskill_t skil
else
Printf ("%s joined the game\n", players[bnum].userinfo.GetName());

Level->DoReborn (bnum, true);
Level->DoReborn (bnum);
Level->localEventManager->PlayerEntered(bnum, false);
return true;
}
Expand Down
1 change: 1 addition & 0 deletions wadsrc/static/zscript/events.zs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ class StaticEventHandler : Object native play version("2.4")
//
virtual void PlayerEntered(PlayerEvent e) {}
virtual void PlayerSpawned(PlayerEvent e) {}
virtual bool PlayerRespawning(PlayerEvent e) { return true; }
virtual void PlayerRespawned(PlayerEvent e) {}
virtual void PlayerDied(PlayerEvent e) {}
virtual void PlayerDisconnected(PlayerEvent e) {}
Expand Down

0 comments on commit a7d4d40

Please sign in to comment.