mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-17 13:38:18 +00:00
Merge pull request #9047 from timakro/pr-add-invincible-mode
Add invincible mode
This commit is contained in:
commit
d51a726129
BIN
data/extras.png
BIN
data/extras.png
Binary file not shown.
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 6.7 KiB |
|
@ -452,6 +452,7 @@ container.sprites.Add(Sprite("hud_lock_mode", set_hud, 10,6,2,2))
|
|||
container.sprites.Add(Sprite("hud_team0_mode", set_hud, 12,6,2,2))
|
||||
|
||||
container.sprites.Add(Sprite("part_snowflake", set_extras, 0,0,2,2))
|
||||
container.sprites.Add(Sprite("part_sparkle", set_extras, 2,0,2,2))
|
||||
|
||||
|
||||
anim = Animation("base")
|
||||
|
|
|
@ -11,7 +11,7 @@ CharacterFlags = ["SOLO", "JETPACK", "COLLISION_DISABLED", "ENDLESS_HOOK", "ENDL
|
|||
"HAMMER_HIT_DISABLED", "SHOTGUN_HIT_DISABLED", "GRENADE_HIT_DISABLED", "LASER_HIT_DISABLED", "HOOK_HIT_DISABLED",
|
||||
"TELEGUN_GUN", "TELEGUN_GRENADE", "TELEGUN_LASER",
|
||||
"WEAPON_HAMMER", "WEAPON_GUN", "WEAPON_SHOTGUN", "WEAPON_GRENADE", "WEAPON_LASER", "WEAPON_NINJA",
|
||||
"MOVEMENTS_DISABLED", "IN_FREEZE", "PRACTICE_MODE", "LOCK_MODE", "TEAM0_MODE"]
|
||||
"MOVEMENTS_DISABLED", "IN_FREEZE", "PRACTICE_MODE", "LOCK_MODE", "TEAM0_MODE", "INVINCIBLE"]
|
||||
GameInfoFlags = [
|
||||
"TIMESCORE", "GAMETYPE_RACE", "GAMETYPE_FASTCAP", "GAMETYPE_FNG",
|
||||
"GAMETYPE_DDRACE", "GAMETYPE_DDNET", "GAMETYPE_BLOCK_WORLDS",
|
||||
|
|
|
@ -103,6 +103,26 @@ void CEffects::FreezingFlakes(vec2 Pos, vec2 Size, float Alpha)
|
|||
m_pClient->m_Particles.Add(CParticles::GROUP_EXTRA, &p);
|
||||
}
|
||||
|
||||
void CEffects::SparkleTrail(vec2 Pos, float Alpha)
|
||||
{
|
||||
if(!m_Add50hz)
|
||||
return;
|
||||
|
||||
CParticle p;
|
||||
p.SetDefault();
|
||||
p.m_Spr = SPRITE_PART_SPARKLE;
|
||||
p.m_Pos = Pos + random_direction() * random_float(40.0f);
|
||||
p.m_Vel = vec2(0, 0);
|
||||
p.m_LifeSpan = 0.5f;
|
||||
p.m_StartSize = 0.0f;
|
||||
p.m_EndSize = random_float(20.0f, 30.0f);
|
||||
p.m_UseAlphaFading = true;
|
||||
p.m_StartAlpha = Alpha;
|
||||
p.m_EndAlpha = std::min(0.2f, Alpha);
|
||||
p.m_Collides = false;
|
||||
m_pClient->m_Particles.Add(CParticles::GROUP_TRAIL_EXTRA, &p);
|
||||
}
|
||||
|
||||
void CEffects::SmokeTrail(vec2 Pos, vec2 Vel, float Alpha, float TimePassed)
|
||||
{
|
||||
if(!m_Add50hz && TimePassed < 0.001f)
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
void PlayerDeath(vec2 Pos, int ClientId, float Alpha = 1.0f);
|
||||
void PowerupShine(vec2 Pos, vec2 Size, float Alpha = 1.0f);
|
||||
void FreezingFlakes(vec2 Pos, vec2 Size, float Alpha = 1.0f);
|
||||
void SparkleTrail(vec2 Pos, float Alpha = 1.0f);
|
||||
void Confetti(vec2 Pos, float Alpha = 1.0f);
|
||||
|
||||
void Update();
|
||||
|
|
|
@ -14,6 +14,7 @@ CParticles::CParticles()
|
|||
{
|
||||
OnReset();
|
||||
m_RenderTrail.m_pParts = this;
|
||||
m_RenderTrailExtra.m_pParts = this;
|
||||
m_RenderExplosions.m_pParts = this;
|
||||
m_RenderExtra.m_pParts = this;
|
||||
m_RenderGeneral.m_pParts = this;
|
||||
|
@ -181,9 +182,12 @@ void CParticles::OnInit()
|
|||
|
||||
m_ExtraParticleQuadContainerIndex = Graphics()->CreateQuadContainer(false);
|
||||
|
||||
// TODO: Use a loop similar to the one for m_ParticleQuadContainerIndex if you add more additional particles
|
||||
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
||||
RenderTools()->QuadContainerAddSprite(m_ExtraParticleQuadContainerIndex, 1.f);
|
||||
for(int i = 0; i <= (SPRITE_PART_SPARKLE - SPRITE_PART_SNOWFLAKE); ++i)
|
||||
{
|
||||
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
||||
RenderTools()->QuadContainerAddSprite(m_ExtraParticleQuadContainerIndex, 1.f);
|
||||
}
|
||||
|
||||
Graphics()->QuadContainerUpload(m_ExtraParticleQuadContainerIndex);
|
||||
}
|
||||
|
||||
|
@ -207,7 +211,7 @@ void CParticles::RenderGroup(int Group)
|
|||
IGraphics::CTextureHandle *aParticles = GameClient()->m_ParticlesSkin.m_aSpriteParticles;
|
||||
int FirstParticleOffset = SPRITE_PART_SLICE;
|
||||
int ParticleQuadContainerIndex = m_ParticleQuadContainerIndex;
|
||||
if(Group == GROUP_EXTRA)
|
||||
if(Group == GROUP_EXTRA || Group == GROUP_TRAIL_EXTRA)
|
||||
{
|
||||
aParticles = GameClient()->m_ExtrasSkin.m_aSpriteParticles;
|
||||
FirstParticleOffset = SPRITE_PART_SNOWFLAKE;
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
enum
|
||||
{
|
||||
GROUP_PROJECTILE_TRAIL = 0,
|
||||
GROUP_TRAIL_EXTRA,
|
||||
GROUP_EXPLOSIONS,
|
||||
GROUP_EXTRA,
|
||||
GROUP_GENERAL,
|
||||
|
@ -111,7 +112,10 @@ private:
|
|||
virtual void OnRender() override { m_pParts->RenderGroup(TGROUP); }
|
||||
};
|
||||
|
||||
// behind players
|
||||
CRenderGroup<GROUP_PROJECTILE_TRAIL> m_RenderTrail;
|
||||
CRenderGroup<GROUP_TRAIL_EXTRA> m_RenderTrailExtra;
|
||||
// in front of players
|
||||
CRenderGroup<GROUP_EXPLOSIONS> m_RenderExplosions;
|
||||
CRenderGroup<GROUP_EXTRA> m_RenderExtra;
|
||||
CRenderGroup<GROUP_GENERAL> m_RenderGeneral;
|
||||
|
|
|
@ -742,6 +742,10 @@ void CPlayers::RenderPlayer(
|
|||
{
|
||||
GameClient()->m_Effects.FreezingFlakes(BodyPos, vec2(32, 32), Alpha);
|
||||
}
|
||||
if(RenderInfo.m_TeeRenderFlags & TEE_EFFECT_SPARKLE)
|
||||
{
|
||||
GameClient()->m_Effects.SparkleTrail(BodyPos, Alpha);
|
||||
}
|
||||
|
||||
if(ClientId < 0)
|
||||
return;
|
||||
|
@ -833,6 +837,8 @@ void CPlayers::OnRender()
|
|||
aRenderInfo[i].m_TeeRenderFlags |= TEE_EFFECT_FROZEN | TEE_NO_WEAPON;
|
||||
if(m_pClient->m_aClients[i].m_LiveFrozen)
|
||||
aRenderInfo[i].m_TeeRenderFlags |= TEE_EFFECT_FROZEN;
|
||||
if(m_pClient->m_aClients[i].m_Invincible)
|
||||
aRenderInfo[i].m_TeeRenderFlags |= TEE_EFFECT_SPARKLE;
|
||||
|
||||
const CGameClient::CSnapState::CCharacterInfo &CharacterInfo = m_pClient->m_Snap.m_aCharacters[i];
|
||||
const bool Frozen = CharacterInfo.m_HasExtendedData && CharacterInfo.m_ExtendedData.m_FreezeEnd != 0;
|
||||
|
|
|
@ -128,6 +128,7 @@ void CGameClient::OnConsoleInit()
|
|||
&m_Background, // render instead of m_MapLayersBackground when g_Config.m_ClOverlayEntities == 100
|
||||
&m_MapLayersBackground, // first to render
|
||||
&m_Particles.m_RenderTrail,
|
||||
&m_Particles.m_RenderTrailExtra,
|
||||
&m_Items,
|
||||
&m_Ghost,
|
||||
&m_Players,
|
||||
|
@ -1683,6 +1684,7 @@ void CGameClient::OnNewSnapshot()
|
|||
pClient->m_ShotgunHitDisabled = pCharacterData->m_Flags & CHARACTERFLAG_SHOTGUN_HIT_DISABLED;
|
||||
pClient->m_HookHitDisabled = pCharacterData->m_Flags & CHARACTERFLAG_HOOK_HIT_DISABLED;
|
||||
pClient->m_Super = pCharacterData->m_Flags & CHARACTERFLAG_SUPER;
|
||||
pClient->m_Invincible = pCharacterData->m_Flags & CHARACTERFLAG_INVINCIBLE;
|
||||
|
||||
// Endless
|
||||
pClient->m_EndlessHook = pCharacterData->m_Flags & CHARACTERFLAG_ENDLESS_HOOK;
|
||||
|
@ -2457,6 +2459,7 @@ void CGameClient::CClientData::Reset()
|
|||
m_ShotgunHitDisabled = false;
|
||||
m_HookHitDisabled = false;
|
||||
m_Super = false;
|
||||
m_Invincible = false;
|
||||
m_HasTelegunGun = false;
|
||||
m_HasTelegunGrenade = false;
|
||||
m_HasTelegunLaser = false;
|
||||
|
@ -3694,6 +3697,7 @@ void CGameClient::LoadExtrasSkin(const char *pPath, bool AsDir)
|
|||
if(m_ExtrasSkinLoaded)
|
||||
{
|
||||
Graphics()->UnloadTexture(&m_ExtrasSkin.m_SpriteParticleSnowflake);
|
||||
Graphics()->UnloadTexture(&m_ExtrasSkin.m_SpriteParticleSparkle);
|
||||
|
||||
for(auto &SpriteParticle : m_ExtrasSkin.m_aSpriteParticles)
|
||||
SpriteParticle = IGraphics::CTextureHandle();
|
||||
|
@ -3728,7 +3732,11 @@ void CGameClient::LoadExtrasSkin(const char *pPath, bool AsDir)
|
|||
else if(PngLoaded && Graphics()->CheckImageDivisibility(aPath, ImgInfo, g_pData->m_aSprites[SPRITE_PART_SNOWFLAKE].m_pSet->m_Gridx, g_pData->m_aSprites[SPRITE_PART_SNOWFLAKE].m_pSet->m_Gridy, true) && Graphics()->IsImageFormatRgba(aPath, ImgInfo))
|
||||
{
|
||||
m_ExtrasSkin.m_SpriteParticleSnowflake = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SNOWFLAKE]);
|
||||
m_ExtrasSkin.m_SpriteParticleSparkle = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SPARKLE]);
|
||||
|
||||
m_ExtrasSkin.m_aSpriteParticles[0] = m_ExtrasSkin.m_SpriteParticleSnowflake;
|
||||
m_ExtrasSkin.m_aSpriteParticles[1] = m_ExtrasSkin.m_SpriteParticleSparkle;
|
||||
|
||||
m_ExtrasSkinLoaded = true;
|
||||
}
|
||||
ImgInfo.Free();
|
||||
|
|
|
@ -394,6 +394,7 @@ public:
|
|||
bool m_ShotgunHitDisabled;
|
||||
bool m_HookHitDisabled;
|
||||
bool m_Super;
|
||||
bool m_Invincible;
|
||||
bool m_HasTelegunGun;
|
||||
bool m_HasTelegunGrenade;
|
||||
bool m_HasTelegunLaser;
|
||||
|
@ -768,7 +769,8 @@ public:
|
|||
struct SClientExtrasSkin
|
||||
{
|
||||
IGraphics::CTextureHandle m_SpriteParticleSnowflake;
|
||||
IGraphics::CTextureHandle m_aSpriteParticles[1];
|
||||
IGraphics::CTextureHandle m_SpriteParticleSparkle;
|
||||
IGraphics::CTextureHandle m_aSpriteParticles[2];
|
||||
};
|
||||
|
||||
SClientExtrasSkin m_ExtrasSkin;
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -123,6 +123,7 @@ enum
|
|||
{
|
||||
TEE_EFFECT_FROZEN = 1,
|
||||
TEE_NO_WEAPON = 2,
|
||||
TEE_EFFECT_SPARKLE = 4,
|
||||
};
|
||||
|
||||
// sprite renderings
|
||||
|
|
|
@ -173,6 +173,7 @@ void CCharacterCore::Reset()
|
|||
m_ShotgunHitDisabled = false;
|
||||
m_HookHitDisabled = false;
|
||||
m_Super = false;
|
||||
m_Invincible = false;
|
||||
m_HasTelegunGun = false;
|
||||
m_HasTelegunGrenade = false;
|
||||
m_HasTelegunLaser = false;
|
||||
|
@ -647,6 +648,7 @@ void CCharacterCore::ReadDDNet(const CNetObj_DDNetCharacter *pObjDDNet)
|
|||
m_LaserHitDisabled = pObjDDNet->m_Flags & CHARACTERFLAG_LASER_HIT_DISABLED;
|
||||
m_HookHitDisabled = pObjDDNet->m_Flags & CHARACTERFLAG_HOOK_HIT_DISABLED;
|
||||
m_Super = pObjDDNet->m_Flags & CHARACTERFLAG_SUPER;
|
||||
m_Invincible = pObjDDNet->m_Flags & CHARACTERFLAG_INVINCIBLE;
|
||||
|
||||
// Endless
|
||||
m_EndlessHook = pObjDDNet->m_Flags & CHARACTERFLAG_ENDLESS_HOOK;
|
||||
|
|
|
@ -256,6 +256,7 @@ public:
|
|||
bool m_ShotgunHitDisabled;
|
||||
bool m_HookHitDisabled;
|
||||
bool m_Super;
|
||||
bool m_Invincible;
|
||||
bool m_HasTelegunGun;
|
||||
bool m_HasTelegunGrenade;
|
||||
bool m_HasTelegunLaser;
|
||||
|
|
|
@ -2169,6 +2169,13 @@ void CGameContext::ConPracticeUnNinja(IConsole::IResult *pResult, void *pUserDat
|
|||
ConUnNinja(pResult, pUserData);
|
||||
}
|
||||
|
||||
void CGameContext::ConPracticeToggleInvincible(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(pSelf->GetPracticeCharacter(pResult))
|
||||
ConToggleInvincible(pResult, pUserData);
|
||||
}
|
||||
|
||||
void CGameContext::ConPracticeAddWeapon(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
|
|
|
@ -160,6 +160,14 @@ void CGameContext::ConUnSuper(IConsole::IResult *pResult, void *pUserData)
|
|||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConToggleInvincible(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
CCharacter *pChr = pSelf->GetPlayerChar(pResult->m_ClientId);
|
||||
if(pChr)
|
||||
pChr->SetInvincible(pResult->NumArguments() == 0 ? !pChr->Core()->m_Invincible : pResult->GetInteger(0));
|
||||
}
|
||||
|
||||
void CGameContext::ConSolo(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
|
|
|
@ -174,19 +174,35 @@ void CCharacter::SetSolo(bool Solo)
|
|||
|
||||
void CCharacter::SetSuper(bool Super)
|
||||
{
|
||||
m_Core.m_Super = Super;
|
||||
// Disable invincible mode before activating super mode. Both modes active at the same time wouldn't necessarily break anything but it's not useful.
|
||||
if(Super)
|
||||
SetInvincible(false);
|
||||
|
||||
bool WasSuper = m_Core.m_Super;
|
||||
m_Core.m_Super = Super;
|
||||
if(Super && !WasSuper)
|
||||
{
|
||||
m_TeamBeforeSuper = Team();
|
||||
Teams()->SetCharacterTeam(GetPlayer()->GetCid(), TEAM_SUPER);
|
||||
m_DDRaceState = DDRACE_CHEAT;
|
||||
}
|
||||
else
|
||||
else if(!Super && WasSuper)
|
||||
{
|
||||
Teams()->SetForceCharacterTeam(GetPlayer()->GetCid(), m_TeamBeforeSuper);
|
||||
}
|
||||
}
|
||||
|
||||
void CCharacter::SetInvincible(bool Invincible)
|
||||
{
|
||||
// Disable super mode before activating invincible mode. Both modes active at the same time wouldn't necessarily break anything but it's not useful.
|
||||
if(Invincible)
|
||||
SetSuper(false);
|
||||
|
||||
m_Core.m_Invincible = Invincible;
|
||||
if(Invincible)
|
||||
UnFreeze();
|
||||
}
|
||||
|
||||
void CCharacter::SetLiveFrozen(bool Active)
|
||||
{
|
||||
m_Core.m_LiveFrozen = Active;
|
||||
|
@ -1219,6 +1235,8 @@ void CCharacter::Snap(int SnappingClient)
|
|||
pDDNetCharacter->m_Flags |= CHARACTERFLAG_SOLO;
|
||||
if(m_Core.m_Super)
|
||||
pDDNetCharacter->m_Flags |= CHARACTERFLAG_SUPER;
|
||||
if(m_Core.m_Invincible)
|
||||
pDDNetCharacter->m_Flags |= CHARACTERFLAG_INVINCIBLE;
|
||||
if(m_Core.m_EndlessHook)
|
||||
pDDNetCharacter->m_Flags |= CHARACTERFLAG_ENDLESS_HOOK;
|
||||
if(m_Core.m_CollisionDisabled || !Tuning()->m_PlayerCollision)
|
||||
|
@ -1361,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;
|
||||
|
@ -1491,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();
|
||||
}
|
||||
|
@ -1499,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;
|
||||
}
|
||||
|
@ -1690,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()])
|
||||
{
|
||||
|
@ -1846,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];
|
||||
|
@ -1861,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];
|
||||
|
@ -1883,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--)
|
||||
|
@ -1920,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--)
|
||||
|
@ -2066,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;
|
||||
|
@ -2120,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
|
||||
|
@ -2145,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;
|
||||
}
|
||||
|
||||
|
@ -2192,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())
|
||||
{
|
||||
|
@ -2366,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())
|
||||
{
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
void SetJumps(int Jumps);
|
||||
void SetSolo(bool Solo);
|
||||
void SetSuper(bool Super);
|
||||
void SetInvincible(bool Invincible);
|
||||
void SetLiveFrozen(bool Active);
|
||||
void SetDeepFrozen(bool Active);
|
||||
void HandleWeaponSwitch();
|
||||
|
|
|
@ -3691,6 +3691,7 @@ void CGameContext::RegisterDDRaceCommands()
|
|||
Console()->Register("unninja", "", CFGFLAG_SERVER | CMDFLAG_TEST, ConUnNinja, this, "Removes ninja from you");
|
||||
Console()->Register("super", "", CFGFLAG_SERVER | CMDFLAG_TEST, ConSuper, this, "Makes you super");
|
||||
Console()->Register("unsuper", "", CFGFLAG_SERVER, ConUnSuper, this, "Removes super from you");
|
||||
Console()->Register("invincible", "?i['0'|'1']", CFGFLAG_SERVER | CMDFLAG_TEST, ConToggleInvincible, this, "Toggles invincible mode");
|
||||
Console()->Register("endless_hook", "", CFGFLAG_SERVER | CMDFLAG_TEST, ConEndlessHook, this, "Gives you endless hook");
|
||||
Console()->Register("unendless_hook", "", CFGFLAG_SERVER | CMDFLAG_TEST, ConUnEndlessHook, this, "Removes endless hook from you");
|
||||
Console()->Register("solo", "", CFGFLAG_SERVER | CMDFLAG_TEST, ConSolo, this, "Puts you into solo part");
|
||||
|
@ -3820,6 +3821,7 @@ void CGameContext::RegisterChatCommands()
|
|||
Console()->Register("unweapons", "", CFGFLAG_CHAT | CMDFLAG_PRACTICE, ConPracticeUnWeapons, this, "Removes all weapons from you");
|
||||
Console()->Register("ninja", "", CFGFLAG_CHAT | CMDFLAG_PRACTICE, ConPracticeNinja, this, "Makes you a ninja");
|
||||
Console()->Register("unninja", "", CFGFLAG_CHAT | CMDFLAG_PRACTICE, ConPracticeUnNinja, this, "Removes ninja from you");
|
||||
Console()->Register("invincible", "?i['0'|'1']", CFGFLAG_CHAT | CMDFLAG_PRACTICE, ConPracticeToggleInvincible, this, "Toggles invincible mode");
|
||||
Console()->Register("kill", "", CFGFLAG_CHAT | CFGFLAG_SERVER, ConProtectedKill, this, "Kill yourself when kill-protected during a long game (use f1, kill for regular kill)");
|
||||
}
|
||||
|
||||
|
|
|
@ -391,6 +391,7 @@ private:
|
|||
static void ConUnLiveFreeze(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConUnSuper(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConSuper(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConToggleInvincible(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConShotgun(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConGrenade(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConLaser(IConsole::IResult *pResult, void *pUserData);
|
||||
|
@ -492,6 +493,7 @@ private:
|
|||
static void ConPracticeUnWeapons(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConPracticeNinja(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConPracticeUnNinja(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConPracticeToggleInvincible(IConsole::IResult *pResult, void *pUserData);
|
||||
|
||||
static void ConPracticeAddWeapon(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConPracticeRemoveWeapon(IConsole::IResult *pResult, void *pUserData);
|
||||
|
|
Loading…
Reference in a new issue