diff --git a/datasrc/network.py b/datasrc/network.py index c6c641c57..a2c273040 100644 --- a/datasrc/network.py +++ b/datasrc/network.py @@ -10,7 +10,8 @@ GameStateFlags = ["GAMEOVER", "SUDDENDEATH", "PAUSED", "RACETIME"] CharacterFlags = ["SOLO", "JETPACK", "NO_COLLISION", "ENDLESS_HOOK", "ENDLESS_JUMP", "SUPER", "NO_HAMMER_HIT", "NO_SHOTGUN_HIT", "NO_GRENADE_HIT", "NO_LASER_HIT", "NO_HOOK", "TELEGUN_GUN", "TELEGUN_GRENADE", "TELEGUN_LASER", - "WEAPON_HAMMER", "WEAPON_GUN", "WEAPON_SHOTGUN", "WEAPON_GRENADE", "WEAPON_LASER", "WEAPON_NINJA", "NO_MOVEMENTS"] + "WEAPON_HAMMER", "WEAPON_GUN", "WEAPON_SHOTGUN", "WEAPON_GRENADE", "WEAPON_LASER", "WEAPON_NINJA", + "NO_MOVEMENTS"] GameInfoFlags = [ "TIMESCORE", "GAMETYPE_RACE", "GAMETYPE_FASTCAP", "GAMETYPE_FNG", "GAMETYPE_DDRACE", "GAMETYPE_DDNET", "GAMETYPE_BLOCK_WORLDS", diff --git a/src/game/client/components/ghost.cpp b/src/game/client/components/ghost.cpp index ef2f134e2..73d77eb51 100644 --- a/src/game/client/components/ghost.cpp +++ b/src/game/client/components/ghost.cpp @@ -26,7 +26,7 @@ void CGhost::GetGhostSkin(CGhostSkin *pSkin, const char *pSkinName, int UseCusto pSkin->m_ColorFeet = ColorFeet; } -void CGhost::GetGhostCharacter(CGhostCharacter *pGhostChar, const CNetObj_Character *pChar) +void CGhost::GetGhostCharacter(CGhostCharacter *pGhostChar, const CNetObj_Character *pChar, const CNetObj_DDNetCharacter *pDDnetChar) { pGhostChar->m_X = pChar->m_X; pGhostChar->m_Y = pChar->m_Y; @@ -34,7 +34,12 @@ void CGhost::GetGhostCharacter(CGhostCharacter *pGhostChar, const CNetObj_Charac pGhostChar->m_VelY = 0; pGhostChar->m_Angle = pChar->m_Angle; pGhostChar->m_Direction = pChar->m_Direction; - pGhostChar->m_Weapon = pChar->m_Weapon; + int Weapon = pChar->m_Weapon; + if(pDDnetChar != nullptr && pDDnetChar->m_FreezeEnd != 0) + { + Weapon = WEAPON_NINJA; + } + pGhostChar->m_Weapon = Weapon; pGhostChar->m_HookState = pChar->m_HookState; pGhostChar->m_HookX = pChar->m_HookX; pGhostChar->m_HookY = pChar->m_HookY; @@ -134,7 +139,7 @@ void CGhost::GetPath(char *pBuf, int Size, const char *pPlayerName, int Time) co str_format(pBuf, Size, "%s/%s_%s_%d.%03d_%s.gho", ms_pGhostDir, pMap, aPlayerName, Time / 1000, Time % 1000, aSha256); } -void CGhost::AddInfos(const CNetObj_Character *pChar) +void CGhost::AddInfos(const CNetObj_Character *pChar, const CNetObj_DDNetCharacter *pDDnetChar) { int NumTicks = m_CurGhost.m_Path.Size(); @@ -151,7 +156,7 @@ void CGhost::AddInfos(const CNetObj_Character *pChar) } CGhostCharacter GhostChar; - GetGhostCharacter(&GhostChar, pChar); + GetGhostCharacter(&GhostChar, pChar, pDDnetChar); m_CurGhost.m_Path.Add(GhostChar); if(GhostRecorder()->IsRecording()) GhostRecorder()->WriteData(GHOSTDATA_TYPE_CHARACTER, &GhostChar, sizeof(CGhostCharacter)); @@ -279,7 +284,7 @@ void CGhost::OnNewSnapshot() CheckStart(); if(m_Recording) - AddInfos(m_pClient->m_Snap.m_pLocalCharacter); + AddInfos(m_pClient->m_Snap.m_pLocalCharacter, (m_pClient->m_Snap.m_LocalClientID != -1 && m_pClient->m_Snap.m_aCharacters[m_pClient->m_Snap.m_LocalClientID].m_HasExtendedData) ? &m_pClient->m_Snap.m_aCharacters[m_pClient->m_Snap.m_LocalClientID].m_ExtendedData : nullptr); } // Record m_LastRaceTick for g_Config.m_ClConfirmDisconnect/QuitTime anyway diff --git a/src/game/client/components/ghost.h b/src/game/client/components/ghost.h index 49c09a6fe..a51c5c7bd 100644 --- a/src/game/client/components/ghost.h +++ b/src/game/client/components/ghost.h @@ -5,6 +5,7 @@ #include #include +#include #include @@ -124,12 +125,12 @@ private: bool m_RenderingStartedByServer; static void GetGhostSkin(CGhostSkin *pSkin, const char *pSkinName, int UseCustomColor, int ColorBody, int ColorFeet); - static void GetGhostCharacter(CGhostCharacter *pGhostChar, const CNetObj_Character *pChar); + static void GetGhostCharacter(CGhostCharacter *pGhostChar, const CNetObj_Character *pChar, const CNetObj_DDNetCharacter *pDDnetChar); static void GetNetObjCharacter(CNetObj_Character *pChar, const CGhostCharacter *pGhostChar); void GetPath(char *pBuf, int Size, const char *pPlayerName, int Time = -1) const; - void AddInfos(const CNetObj_Character *pChar); + void AddInfos(const CNetObj_Character *pChar, const CNetObj_DDNetCharacter *pDDnetChar); int GetSlot() const; void CheckStart(); diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index 99963d439..334da459f 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -726,7 +726,8 @@ void CPlayers::OnRender() { m_aRenderInfo[i] = m_pClient->m_aClients[i].m_RenderInfo; m_aRenderInfo[i].m_ShineDecoration = m_pClient->m_aClients[i].m_LiveFrozen; - if(m_pClient->m_Snap.m_aCharacters[i].m_Cur.m_Weapon == WEAPON_NINJA && g_Config.m_ClShowNinja) + CGameClient::CSnapState::CCharacterInfo &CharacterInfo = m_pClient->m_Snap.m_aCharacters[i]; + if((CharacterInfo.m_Cur.m_Weapon == WEAPON_NINJA || (CharacterInfo.m_HasExtendedData && CharacterInfo.m_ExtendedData.m_FreezeEnd != 0)) && g_Config.m_ClShowNinja) { // change the skin for the player to the ninja int Skin = m_pClient->m_Skins.Find("x_ninja"); diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 8c614900a..0727ae160 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -8,7 +8,6 @@ #include #include "character.h" -#include "engine/shared/protocol.h" #include "laser.h" #include "projectile.h" @@ -915,6 +914,9 @@ bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon) //TODO: Move the emote stuff to a function void CCharacter::SnapCharacter(int SnappingClient, int ID) { + int SnappingClientVersion = SnappingClient != SERVER_DEMO_CLIENT ? + GameServer()->GetClientVersion(SnappingClient) : + CLIENT_VERSIONNR; CCharacterCore *pCore; int Tick, Emote = m_EmoteType, Weapon = m_Core.m_ActiveWeapon, AmmoCount = 0, Health = 0, Armor = 0; @@ -935,7 +937,7 @@ void CCharacter::SnapCharacter(int SnappingClient, int ID) if(Emote == EMOTE_NORMAL) Emote = (m_DeepFreeze || m_LiveFreeze) ? EMOTE_PAIN : EMOTE_BLINK; - if(m_DeepFreeze || m_FreezeTime > 0 || m_FreezeTime == -1) + if((m_DeepFreeze || m_FreezeTime > 0 || m_FreezeTime == -1) && SnappingClientVersion < VERSION_DDNET_NEW_HUD) Weapon = WEAPON_NINJA; } @@ -962,7 +964,8 @@ void CCharacter::SnapCharacter(int SnappingClient, int ID) } // change eyes, use ninja graphic and set ammo count if player has ninjajetpack - if(m_pPlayer->m_NinjaJetpack && m_Jetpack && m_Core.m_ActiveWeapon == WEAPON_GUN && !m_DeepFreeze && !(m_FreezeTime > 0 || m_FreezeTime == -1) && !m_Core.m_HasTelegunGun) + if(m_pPlayer->m_NinjaJetpack && m_Jetpack && m_Core.m_ActiveWeapon == WEAPON_GUN && !m_DeepFreeze && + !(m_FreezeTime > 0 || m_FreezeTime == -1) && !m_Core.m_HasTelegunGun) { if(Emote == EMOTE_NORMAL) Emote = EMOTE_HAPPY; @@ -1152,9 +1155,7 @@ void CCharacter::Snap(int SnappingClient) if(m_Core.m_ActiveWeapon == WEAPON_NINJA) pDDNetCharacter->m_Flags |= CHARACTERFLAG_WEAPON_NINJA; if(m_Core.m_LiveFrozen) - { pDDNetCharacter->m_Flags |= CHARACTERFLAG_NO_MOVEMENTS; - } pDDNetCharacter->m_FreezeEnd = m_DeepFreeze ? -1 : m_FreezeTime == 0 ? 0 : Server()->Tick() + m_FreezeTime; pDDNetCharacter->m_Jumps = m_Core.m_Jumps;