Make invincible players immune to freeze, death and teleport tiles and give them unlimited jumps

Specifically:
* Ignore freeze, deep freeze, deep unfreeze, live freeze, and live unfreeze tiles
* Ignore also the switched variants of those tiles
* Allow movement when deep and live frozen
* Ignore death tiles
* Ignore red tele, blue tele, red checkpoint tele, and blue checkpoint tele tiles
* Unlimited jumps
* Disable /rescue

Switches, doors, draggers, etc. are not disabled for invincible players in this patch
This commit is contained in:
Tim Schumacher 2024-09-24 01:16:40 +02:00
parent f51664e5ce
commit b564110675
2 changed files with 38 additions and 36 deletions

View file

@ -757,19 +757,19 @@ void CCharacter::HandleTiles(int Index)
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aType[Team()] = TILE_SWITCHCLOSE;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aLastUpdateTick[Team()] = GameWorld()->GameTick();
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER)
else if(Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER && !m_Core.m_Invincible)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aStatus[Team()])
{
Freeze(Collision()->GetSwitchDelay(MapIndex));
}
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER)
else if(Collision()->GetSwitchType(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER && !m_Core.m_Invincible)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aStatus[Team()])
m_Core.m_DeepFrozen = true;
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_DUNFREEZE && Team() != TEAM_SUPER)
else if(Collision()->GetSwitchType(MapIndex) == TILE_DUNFREEZE && Team() != TEAM_SUPER && !m_Core.m_Invincible)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aStatus[Team()])
m_Core.m_DeepFrozen = false;
@ -817,14 +817,14 @@ void CCharacter::HandleTiles(int Index)
if(NewJumps != m_Core.m_Jumps)
m_Core.m_Jumps = NewJumps;
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_LFREEZE && Team() != TEAM_SUPER)
else if(Collision()->GetSwitchType(MapIndex) == TILE_LFREEZE && Team() != TEAM_SUPER && !m_Core.m_Invincible)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aStatus[Team()])
{
m_Core.m_LiveFrozen = true;
}
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_LUNFREEZE && Team() != TEAM_SUPER)
else if(Collision()->GetSwitchType(MapIndex) == TILE_LUNFREEZE && Team() != TEAM_SUPER && !m_Core.m_Invincible)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aStatus[Team()])
{
@ -833,7 +833,7 @@ void CCharacter::HandleTiles(int Index)
}
// freeze
if(((m_TileIndex == TILE_FREEZE) || (m_TileFIndex == TILE_FREEZE)) && !m_Core.m_Super && !m_Core.m_DeepFrozen)
if(((m_TileIndex == TILE_FREEZE) || (m_TileFIndex == TILE_FREEZE)) && !m_Core.m_Super && !m_Core.m_Invincible && !m_Core.m_DeepFrozen)
{
Freeze();
}
@ -843,21 +843,21 @@ void CCharacter::HandleTiles(int Index)
}
// deep freeze
if(((m_TileIndex == TILE_DFREEZE) || (m_TileFIndex == TILE_DFREEZE)) && !m_Core.m_Super && !m_Core.m_DeepFrozen)
if(((m_TileIndex == TILE_DFREEZE) || (m_TileFIndex == TILE_DFREEZE)) && !m_Core.m_Super && !m_Core.m_Invincible && !m_Core.m_DeepFrozen)
{
m_Core.m_DeepFrozen = true;
}
else if(((m_TileIndex == TILE_DUNFREEZE) || (m_TileFIndex == TILE_DUNFREEZE)) && !m_Core.m_Super && m_Core.m_DeepFrozen)
else if(((m_TileIndex == TILE_DUNFREEZE) || (m_TileFIndex == TILE_DUNFREEZE)) && !m_Core.m_Super && !m_Core.m_Invincible && m_Core.m_DeepFrozen)
{
m_Core.m_DeepFrozen = false;
}
// live freeze
if(((m_TileIndex == TILE_LFREEZE) || (m_TileFIndex == TILE_LFREEZE)) && !m_Core.m_Super)
if(((m_TileIndex == TILE_LFREEZE) || (m_TileFIndex == TILE_LFREEZE)) && !m_Core.m_Super && !m_Core.m_Invincible)
{
m_Core.m_LiveFrozen = true;
}
else if(((m_TileIndex == TILE_LUNFREEZE) || (m_TileFIndex == TILE_LUNFREEZE)) && !m_Core.m_Super)
else if(((m_TileIndex == TILE_LUNFREEZE) || (m_TileFIndex == TILE_LUNFREEZE)) && !m_Core.m_Super && !m_Core.m_Invincible)
{
m_Core.m_LiveFrozen = false;
}
@ -959,7 +959,7 @@ void CCharacter::HandleTuneLayer()
void CCharacter::DDRaceTick()
{
mem_copy(&m_Input, &m_SavedInput, sizeof(m_Input));
if(m_Core.m_LiveFrozen && !m_CanMoveInFreeze && !m_Core.m_Super)
if(m_Core.m_LiveFrozen && !m_CanMoveInFreeze && !m_Core.m_Super && !m_Core.m_Invincible)
{
m_Input.m_Direction = 0;
m_Input.m_Jump = 0;
@ -1007,7 +1007,7 @@ void CCharacter::DDRacePostCoreTick()
m_FrozenLastTick = false;
if(m_Core.m_DeepFrozen && !m_Core.m_Super)
if(m_Core.m_DeepFrozen && !m_Core.m_Super && !m_Core.m_Invincible)
Freeze();
// following jump rules can be overridden by tiles, like Refill Jumps, Stopper and Wall Jump
@ -1032,9 +1032,9 @@ void CCharacter::DDRacePostCoreTick()
m_Core.m_Jumped = 1;
}
if((m_Core.m_Super || m_Core.m_EndlessJump) && m_Core.m_Jumped > 1)
if((m_Core.m_Super || m_Core.m_Invincible || m_Core.m_EndlessJump) && m_Core.m_Jumped > 1)
{
// Super players and players with infinite jumps always have light feet
// Super players, invincible players and players with infinite jumps always have light feet
m_Core.m_Jumped = 1;
}
@ -1056,7 +1056,7 @@ bool CCharacter::Freeze(int Seconds)
{
if(!GameWorld()->m_WorldConfig.m_PredictFreeze)
return false;
if(Seconds <= 0 || m_Core.m_Super || m_FreezeTime > Seconds * GameWorld()->GameTickSpeed())
if(Seconds <= 0 || m_Core.m_Super || m_Core.m_Invincible || m_FreezeTime > Seconds * GameWorld()->GameTickSpeed())
return false;
if(m_Core.m_FreezeStart < GameWorld()->GameTick() - GameWorld()->GameTickSpeed())
{

View file

@ -199,6 +199,8 @@ void CCharacter::SetInvincible(bool Invincible)
SetSuper(false);
m_Core.m_Invincible = Invincible;
if(Invincible)
UnFreeze();
}
void CCharacter::SetLiveFrozen(bool Active)
@ -1377,7 +1379,7 @@ void CCharacter::HandleSkippableTiles(int Index)
Collision()->GetFCollisionAt(m_Pos.x + GetProximityRadius() / 3.f, m_Pos.y + GetProximityRadius() / 3.f) == TILE_DEATH ||
Collision()->GetFCollisionAt(m_Pos.x - GetProximityRadius() / 3.f, m_Pos.y - GetProximityRadius() / 3.f) == TILE_DEATH ||
Collision()->GetFCollisionAt(m_Pos.x - GetProximityRadius() / 3.f, m_Pos.y + GetProximityRadius() / 3.f) == TILE_DEATH) &&
!m_Core.m_Super && !(Team() && Teams()->TeeFinished(m_pPlayer->GetCid())))
!m_Core.m_Super && !m_Core.m_Invincible && !(Team() && Teams()->TeeFinished(m_pPlayer->GetCid())))
{
Die(m_pPlayer->GetCid(), WEAPON_WORLD);
return;
@ -1507,7 +1509,7 @@ void CCharacter::HandleTiles(int Index)
return;
// freeze
if(((m_TileIndex == TILE_FREEZE) || (m_TileFIndex == TILE_FREEZE)) && !m_Core.m_Super && !m_Core.m_DeepFrozen)
if(((m_TileIndex == TILE_FREEZE) || (m_TileFIndex == TILE_FREEZE)) && !m_Core.m_Super && !m_Core.m_Invincible && !m_Core.m_DeepFrozen)
{
Freeze();
}
@ -1515,17 +1517,17 @@ void CCharacter::HandleTiles(int Index)
UnFreeze();
// deep freeze
if(((m_TileIndex == TILE_DFREEZE) || (m_TileFIndex == TILE_DFREEZE)) && !m_Core.m_Super && !m_Core.m_DeepFrozen)
if(((m_TileIndex == TILE_DFREEZE) || (m_TileFIndex == TILE_DFREEZE)) && !m_Core.m_Super && !m_Core.m_Invincible && !m_Core.m_DeepFrozen)
m_Core.m_DeepFrozen = true;
else if(((m_TileIndex == TILE_DUNFREEZE) || (m_TileFIndex == TILE_DUNFREEZE)) && !m_Core.m_Super && m_Core.m_DeepFrozen)
else if(((m_TileIndex == TILE_DUNFREEZE) || (m_TileFIndex == TILE_DUNFREEZE)) && !m_Core.m_Super && !m_Core.m_Invincible && m_Core.m_DeepFrozen)
m_Core.m_DeepFrozen = false;
// live freeze
if(((m_TileIndex == TILE_LFREEZE) || (m_TileFIndex == TILE_LFREEZE)) && !m_Core.m_Super)
if(((m_TileIndex == TILE_LFREEZE) || (m_TileFIndex == TILE_LFREEZE)) && !m_Core.m_Super && !m_Core.m_Invincible)
{
m_Core.m_LiveFrozen = true;
}
else if(((m_TileIndex == TILE_LUNFREEZE) || (m_TileFIndex == TILE_LUNFREEZE)) && !m_Core.m_Super)
else if(((m_TileIndex == TILE_LUNFREEZE) || (m_TileFIndex == TILE_LUNFREEZE)) && !m_Core.m_Super && !m_Core.m_Invincible)
{
m_Core.m_LiveFrozen = false;
}
@ -1706,31 +1708,31 @@ void CCharacter::HandleTiles(int Index)
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aType[Team()] = TILE_SWITCHCLOSE;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aLastUpdateTick[Team()] = Server()->Tick();
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER)
else if(Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER && !m_Core.m_Invincible)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aStatus[Team()])
{
Freeze(Collision()->GetSwitchDelay(MapIndex));
}
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER)
else if(Collision()->GetSwitchType(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER && !m_Core.m_Invincible)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aStatus[Team()])
m_Core.m_DeepFrozen = true;
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_DUNFREEZE && Team() != TEAM_SUPER)
else if(Collision()->GetSwitchType(MapIndex) == TILE_DUNFREEZE && Team() != TEAM_SUPER && !m_Core.m_Invincible)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aStatus[Team()])
m_Core.m_DeepFrozen = false;
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_LFREEZE && Team() != TEAM_SUPER)
else if(Collision()->GetSwitchType(MapIndex) == TILE_LFREEZE && Team() != TEAM_SUPER && !m_Core.m_Invincible)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aStatus[Team()])
{
m_Core.m_LiveFrozen = true;
}
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_LUNFREEZE && Team() != TEAM_SUPER)
else if(Collision()->GetSwitchType(MapIndex) == TILE_LUNFREEZE && Team() != TEAM_SUPER && !m_Core.m_Invincible)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_aStatus[Team()])
{
@ -1862,7 +1864,7 @@ void CCharacter::HandleTiles(int Index)
int z = Collision()->IsTeleport(MapIndex);
if(!g_Config.m_SvOldTeleportHook && !g_Config.m_SvOldTeleportWeapons && z && !Collision()->TeleOuts(z - 1).empty())
{
if(m_Core.m_Super)
if(m_Core.m_Super || m_Core.m_Invincible)
return;
int TeleOut = GameWorld()->m_Core.RandomOr0(Collision()->TeleOuts(z - 1).size());
m_Core.m_Pos = Collision()->TeleOuts(z - 1)[TeleOut];
@ -1877,7 +1879,7 @@ void CCharacter::HandleTiles(int Index)
int evilz = Collision()->IsEvilTeleport(MapIndex);
if(evilz && !Collision()->TeleOuts(evilz - 1).empty())
{
if(m_Core.m_Super)
if(m_Core.m_Super || m_Core.m_Invincible)
return;
int TeleOut = GameWorld()->m_Core.RandomOr0(Collision()->TeleOuts(evilz - 1).size());
m_Core.m_Pos = Collision()->TeleOuts(evilz - 1)[TeleOut];
@ -1899,7 +1901,7 @@ void CCharacter::HandleTiles(int Index)
}
if(Collision()->IsCheckEvilTeleport(MapIndex))
{
if(m_Core.m_Super)
if(m_Core.m_Super || m_Core.m_Invincible)
return;
// first check if there is a TeleCheckOut for the current recorded checkpoint, if not check previous checkpoints
for(int k = m_TeleCheckpoint - 1; k >= 0; k--)
@ -1936,7 +1938,7 @@ void CCharacter::HandleTiles(int Index)
}
if(Collision()->IsCheckTeleport(MapIndex))
{
if(m_Core.m_Super)
if(m_Core.m_Super || m_Core.m_Invincible)
return;
// first check if there is a TeleCheckOut for the current recorded checkpoint, if not check previous checkpoints
for(int k = m_TeleCheckpoint - 1; k >= 0; k--)
@ -2082,7 +2084,7 @@ void CCharacter::DDRaceTick()
if(m_Input.m_Direction != 0 || m_Input.m_Jump != 0)
m_LastMove = Server()->Tick();
if(m_Core.m_LiveFrozen && !m_Core.m_Super)
if(m_Core.m_LiveFrozen && !m_Core.m_Super && !m_Core.m_Invincible)
{
m_Input.m_Direction = 0;
m_Input.m_Jump = 0;
@ -2136,7 +2138,7 @@ void CCharacter::DDRacePostCoreTick()
m_FrozenLastTick = false;
if(m_Core.m_DeepFrozen && !m_Core.m_Super)
if(m_Core.m_DeepFrozen && !m_Core.m_Super && !m_Core.m_Invincible)
Freeze();
// following jump rules can be overridden by tiles, like Refill Jumps, Stopper and Wall Jump
@ -2161,9 +2163,9 @@ void CCharacter::DDRacePostCoreTick()
m_Core.m_Jumped = 1;
}
if((m_Core.m_Super || m_Core.m_EndlessJump) && m_Core.m_Jumped > 1)
if((m_Core.m_Super || m_Core.m_Invincible || m_Core.m_EndlessJump) && m_Core.m_Jumped > 1)
{
// Super players and players with infinite jumps always have light feet
// Super players, invincible players and players with infinite jumps always have light feet
m_Core.m_Jumped = 1;
}
@ -2208,7 +2210,7 @@ void CCharacter::DDRacePostCoreTick()
bool CCharacter::Freeze(int Seconds)
{
if(Seconds <= 0 || m_Core.m_Super || m_FreezeTime > Seconds * Server()->TickSpeed())
if(Seconds <= 0 || m_Core.m_Super || m_Core.m_Invincible || m_FreezeTime > Seconds * Server()->TickSpeed())
return false;
if(m_FreezeTime == 0 || m_Core.m_FreezeStart < Server()->Tick() - Server()->TickSpeed())
{
@ -2382,7 +2384,7 @@ void CCharacter::DDRaceInit()
void CCharacter::Rescue()
{
if(m_SetSavePos[GetPlayer()->m_RescueMode] && !m_Core.m_Super)
if(m_SetSavePos[GetPlayer()->m_RescueMode] && !m_Core.m_Super && !m_Core.m_Invincible)
{
if(m_LastRescue + (int64_t)g_Config.m_SvRescueDelay * Server()->TickSpeed() > Server()->Tick())
{