mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-04 01:41:42 +00:00
Improved "respawn where died" functionality (#2831)
Now uses a "last safe position" system instead. This: -Prevents players from slipping into places they shouldn't via their dead body and then respawning there -No longer sends players back to spawn if they fall into kill pits -Adds a safety feature where the kill command always resets back to spawn should a player ever get stuck somewhere
This commit is contained in:
parent
9b62379645
commit
941f9502e9
6 changed files with 43 additions and 10 deletions
|
@ -1438,6 +1438,7 @@ void FLevelLocals::PlayerReborn (int player)
|
|||
p->cheats |= chasecam;
|
||||
p->Bot = Bot; //Added by MC:
|
||||
p->settings_controller = settings_controller;
|
||||
p->LastSafePos = p->mo->Pos();
|
||||
|
||||
p->oldbuttons = ~0, p->attackdown = true; p->usedown = true; // don't do anything immediately
|
||||
p->original_oldbuttons = ~0;
|
||||
|
|
|
@ -805,6 +805,8 @@ public:
|
|||
void RemoveForceField();
|
||||
int Index() const { return sectornum; }
|
||||
|
||||
bool IsDangerous(const DVector3& pos, double height) const;
|
||||
|
||||
void AdjustFloorClip () const;
|
||||
void SetColor(PalEntry pe, int desat);
|
||||
void SetFade(PalEntry pe);
|
||||
|
|
|
@ -435,6 +435,8 @@ public:
|
|||
DAngle ConversationNPCAngle = nullAngle;
|
||||
bool ConversationFaceTalker = false;
|
||||
|
||||
DVector3 LastSafePos = {}; // Mark the last known safe location the player was standing.
|
||||
|
||||
double GetDeltaViewHeight() const
|
||||
{
|
||||
return (mo->FloatVar(NAME_ViewHeight) + crouchviewdelta - viewheight) / 8;
|
||||
|
|
|
@ -5594,16 +5594,13 @@ AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flag
|
|||
|
||||
PlayerSpawnPickClass(playernum);
|
||||
|
||||
if (( dmflags2 & DF2_SAME_SPAWN_SPOT ) &&
|
||||
( p->playerstate == PST_REBORN ) &&
|
||||
( deathmatch == false ) &&
|
||||
( gameaction != ga_worlddone ) &&
|
||||
( p->mo != NULL ) &&
|
||||
( !(p->mo->Sector->Flags & SECF_NORESPAWN) ) &&
|
||||
( NULL != p->attacker ) && // don't respawn on damaging floors
|
||||
( p->mo->Sector->damageamount < TELEFRAG_DAMAGE )) // this really should be a bit smarter...
|
||||
if ((dmflags2 & DF2_SAME_SPAWN_SPOT) && !deathmatch
|
||||
&& p->mo != nullptr && p->playerstate == PST_REBORN
|
||||
&& gameaction != ga_worlddone
|
||||
&& !(p->mo->Sector->Flags & SECF_NORESPAWN)
|
||||
&& p->LastDamageType != NAME_Suicide)
|
||||
{
|
||||
spawn = p->mo->Pos();
|
||||
spawn = p->LastSafePos;
|
||||
SpawnAngle = p->mo->Angles.Yaw;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -129,6 +129,28 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, NextSpecialSector, P_NextSpecialSector)
|
|||
ACTION_RETURN_POINTER(P_NextSpecialSector(self, type, nogood));
|
||||
}
|
||||
|
||||
bool sector_t::IsDangerous(const DVector3& pos, double height) const
|
||||
{
|
||||
if (damageamount > 0)
|
||||
return true;
|
||||
|
||||
auto cl = dyn_cast<DCeiling>(ceilingdata.Get());
|
||||
if (cl != nullptr && cl->getCrush() > 0)
|
||||
return true;
|
||||
|
||||
for (auto rover : e->XFloor.ffloors)
|
||||
{
|
||||
if ((rover->flags & FF_EXISTS) && rover->model->damageamount > 0
|
||||
&& pos.Z <= rover->top.plane->ZatPoint(pos)
|
||||
&& pos.Z + height >= rover->bottom.plane->ZatPoint(pos))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// P_FindLowestFloorSurrounding()
|
||||
// FIND LOWEST FLOOR HEIGHT IN SURROUNDING SECTORS
|
||||
|
|
|
@ -361,6 +361,7 @@ void player_t::CopyFrom(player_t &p, bool copyPSP)
|
|||
MUSINFOactor = p.MUSINFOactor;
|
||||
MUSINFOtics = p.MUSINFOtics;
|
||||
SoundClass = p.SoundClass;
|
||||
LastSafePos = p.LastSafePos;
|
||||
angleOffsetTargets = p.angleOffsetTargets;
|
||||
if (copyPSP)
|
||||
{
|
||||
|
@ -1291,6 +1292,13 @@ void P_PlayerThink (player_t *player)
|
|||
player->SubtitleCounter--;
|
||||
}
|
||||
|
||||
if (player->playerstate == PST_LIVE
|
||||
&& player->mo->Z() <= player->mo->floorz
|
||||
&& !player->mo->Sector->IsDangerous(player->mo->Pos(), player->mo->Height))
|
||||
{
|
||||
player->LastSafePos = player->mo->Pos();
|
||||
}
|
||||
|
||||
// Bots do not think in freeze mode.
|
||||
if (player->mo->Level->isFrozen() && player->Bot != nullptr)
|
||||
{
|
||||
|
@ -1779,7 +1787,8 @@ void player_t::Serialize(FSerializer &arc)
|
|||
("onground", onground)
|
||||
("musinfoactor", MUSINFOactor)
|
||||
("musinfotics", MUSINFOtics)
|
||||
("soundclass", SoundClass);
|
||||
("soundclass", SoundClass)
|
||||
("lastsafepos", LastSafePos);
|
||||
|
||||
if (arc.isWriting ())
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue