diff --git a/datasrc/network.py b/datasrc/network.py index 04c02748b..01c6661e2 100644 --- a/datasrc/network.py +++ b/datasrc/network.py @@ -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", diff --git a/src/game/gamecore.cpp b/src/game/gamecore.cpp index 042e64579..45081cad3 100644 --- a/src/game/gamecore.cpp +++ b/src/game/gamecore.cpp @@ -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; diff --git a/src/game/gamecore.h b/src/game/gamecore.h index c33b14e17..0cce06c2c 100644 --- a/src/game/gamecore.h +++ b/src/game/gamecore.h @@ -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; diff --git a/src/game/server/ddracecommands.cpp b/src/game/server/ddracecommands.cpp index e65cad482..e7e9b8251 100644 --- a/src/game/server/ddracecommands.cpp +++ b/src/game/server/ddracecommands.cpp @@ -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; diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index d785e5179..214228809 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -174,6 +174,10 @@ void CCharacter::SetSolo(bool Solo) void CCharacter::SetSuper(bool 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) @@ -188,6 +192,15 @@ void CCharacter::SetSuper(bool Super) } } +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; +} + void CCharacter::SetLiveFrozen(bool Active) { m_Core.m_LiveFrozen = Active; @@ -1220,6 +1233,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) diff --git a/src/game/server/entities/character.h b/src/game/server/entities/character.h index df569dc2c..59793707c 100644 --- a/src/game/server/entities/character.h +++ b/src/game/server/entities/character.h @@ -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(); diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 3b0356a8e..73606fcac 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -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"); diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index d25758c53..dce2499dc 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -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);