From 71e5b7ed3ad17b9eb22101d47d270bd2683e9317 Mon Sep 17 00:00:00 2001 From: trml Date: Thu, 14 Oct 2021 22:59:39 +0200 Subject: [PATCH] Fix switch state for super, cleanup door snapping, add dragger/gun/light --- datasrc/network.py | 2 +- src/game/client/components/items.cpp | 50 +++++++++++++++++++--------- src/game/client/gameclient.cpp | 8 ++++- src/game/client/gameclient.h | 1 + src/game/server/entities/door.cpp | 38 ++++++++------------- src/game/server/entities/dragger.cpp | 40 +++++++++++++++++----- src/game/server/entities/gun.cpp | 28 ++++++++++++++-- src/game/server/entities/light.cpp | 20 ++++++++--- 8 files changed, 129 insertions(+), 58 deletions(-) diff --git a/datasrc/network.py b/datasrc/network.py index 3d4e11996..618fcee4a 100644 --- a/datasrc/network.py +++ b/datasrc/network.py @@ -36,7 +36,7 @@ Emoticons = ["OOP", "EXCLAMATION", "HEARTS", "DROP", "DOTDOT", "MUSIC", "SORRY", Powerups = ["HEALTH", "ARMOR", "WEAPON", "NINJA"] Authed = ["NO", "HELPER", "MOD", "ADMIN"] -EntityClasses = ["PICKUP", "PROJECTILE", "DOOR"] +EntityClasses = ["PROJECTILE", "DOOR", "DRAGGER_WEAK", "DRAGGER_NORMAL", "DRAGGER_STRONG", "GUN_NORMAL", "GUN_EXPLOSIVE", "GUN_FREEZE", "GUN_UNFREEZE", "LIGHT", "PICKUP"] RawHeader = ''' diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp index 773435fd4..cfdefae37 100644 --- a/src/game/client/components/items.cpp +++ b/src/game/client/components/items.cpp @@ -302,19 +302,23 @@ void CItems::OnRender() if(Client()->State() < IClient::STATE_ONLINE) return; + bool IsSuper = m_pClient->IsLocalCharSuper(); int Ticks = Client()->GameTick(g_Config.m_ClDummy) % Client()->GameTickSpeed(); - bool BlinkingSwitchPickup = (Ticks % 22) < 4; - bool BlinkingSwitchDoor = (Ticks % 22) < 4; - bool BlinkingSwitchProj = (Ticks % 20) < 2; - bool BlinkingSwitchProjEx = (Ticks % 6) < 2; + bool BlinkingPickup = (Ticks % 22) < 4; + bool BlinkingGun = (Ticks % 22) < 4; + bool BlinkingDragger = (Ticks % 22) < 4; + bool BlinkingProj = (Ticks % 20) < 2; + bool BlinkingProjEx = (Ticks % 6) < 2; + bool BlinkingLight = (Ticks % 6) < 2; int OwnTeam = m_pClient->OwnTeam(); + int DraggerStartTick = maximum((Client()->GameTick(g_Config.m_ClDummy) / 7) * 7, Client()->GameTick(g_Config.m_ClDummy) - 4); bool UsePredicted = GameClient()->Predict() && GameClient()->AntiPingGunfire(); if(UsePredicted) { for(auto *pProj = (CProjectile *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile *)pProj->NextEntity()) { - if(pProj->m_Number > 0 && !Collision()->m_pSwitchers[pProj->m_Number].m_Status[OwnTeam] && (pProj->m_Explosive ? BlinkingSwitchProjEx : BlinkingSwitchProj)) + if(!IsSuper && pProj->m_Number > 0 && !Collision()->m_pSwitchers[pProj->m_Number].m_Status[OwnTeam] && (pProj->m_Explosive ? BlinkingProjEx : BlinkingProj)) continue; CProjectileData Data = pProj->GetData(); @@ -330,7 +334,7 @@ void CItems::OnRender() } for(auto *pPickup = (CPickup *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity()) { - if(pPickup->m_Layer == LAYER_SWITCH && pPickup->m_Number > 0 && !Collision()->m_pSwitchers[pPickup->m_Number].m_Status[OwnTeam] && BlinkingSwitchPickup) + if(!IsSuper && pPickup->m_Layer == LAYER_SWITCH && pPickup->m_Number > 0 && !Collision()->m_pSwitchers[pPickup->m_Number].m_Status[OwnTeam] && BlinkingPickup) continue; if(pPickup->InDDNetTile()) @@ -353,6 +357,10 @@ void CItems::OnRender() const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); CNetObj_EntityEx *pEntEx = (CNetObj_EntityEx *)Client()->SnapFindItem(IClient::SNAP_CURRENT, NETOBJTYPE_ENTITYEX, Item.m_ID); + bool Inactive = false; + if(pEntEx) + Inactive = !IsSuper && pEntEx->m_SwitchNumber > 0 && !Collision()->m_pSwitchers[pEntEx->m_SwitchNumber].m_Status[OwnTeam]; + if(Item.m_Type == NETOBJTYPE_PROJECTILE || Item.m_Type == NETOBJTYPE_DDNETPROJECTILE) { CProjectileData Data; @@ -381,20 +389,20 @@ void CItems::OnRender() continue; } } - if(pEntEx && pEntEx->m_SwitchNumber > 0 && !Collision()->m_pSwitchers[pEntEx->m_SwitchNumber].m_Status[OwnTeam] && (Data.m_Explosive ? BlinkingSwitchProjEx : BlinkingSwitchProj)) + if(Inactive && (Data.m_Explosive ? BlinkingProjEx : BlinkingProj)) continue; RenderProjectile(&Data, Item.m_ID); } else if(Item.m_Type == NETOBJTYPE_PICKUP) { + if(Inactive && BlinkingPickup) + continue; if(UsePredicted) { auto *pPickup = (CPickup *)GameClient()->m_GameWorld.FindMatch(Item.m_ID, Item.m_Type, pData); if(pPickup && pPickup->InDDNetTile()) continue; } - if(pEntEx && pEntEx->m_SwitchNumber > 0 && !Collision()->m_pSwitchers[pEntEx->m_SwitchNumber].m_Status[OwnTeam] && BlinkingSwitchPickup) - continue; const void *pPrev = Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_ID); if(pPrev) RenderPickup((const CNetObj_Pickup *)pPrev, (const CNetObj_Pickup *)pData); @@ -408,16 +416,28 @@ void CItems::OnRender() continue; } CNetObj_Laser Laser = *((const CNetObj_Laser *)pData); - if(pEntEx && pEntEx->m_EntityClass == ENTITYCLASS_DOOR) + + if(pEntEx) { - if(pEntEx->m_SwitchNumber > 0 && !Collision()->m_pSwitchers[pEntEx->m_SwitchNumber].m_Status[OwnTeam]) + if(pEntEx->m_EntityClass == ENTITYCLASS_LIGHT && Inactive && BlinkingLight) + continue; + if(pEntEx->m_EntityClass >= ENTITYCLASS_GUN_NORMAL && pEntEx->m_EntityClass <= ENTITYCLASS_GUN_UNFREEZE && Inactive && BlinkingGun) + continue; + if(pEntEx->m_EntityClass >= ENTITYCLASS_DRAGGER_WEAK && pEntEx->m_EntityClass <= ENTITYCLASS_DRAGGER_STRONG) { - if(BlinkingSwitchDoor) + if(Inactive && BlinkingDragger) continue; - Laser.m_FromX = Laser.m_X; - Laser.m_FromY = Laser.m_Y; + Laser.m_StartTick = DraggerStartTick; + } + if(pEntEx->m_EntityClass == ENTITYCLASS_DOOR) + { + if(Inactive || IsSuper) + { + Laser.m_FromX = Laser.m_X; + Laser.m_FromY = Laser.m_Y; + } + Laser.m_StartTick = Client()->GameTick(g_Config.m_ClDummy); } - Laser.m_StartTick = Client()->GameTick(g_Config.m_ClDummy); } RenderLaser(&Laser); } diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 34db4f888..e4e97d338 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -2598,10 +2598,16 @@ int CGameClient::OwnTeam() return 0; else if(m_Snap.m_SpecInfo.m_Active && m_Snap.m_SpecInfo.m_SpectatorID != SPEC_FREEVIEW) return m_Teams.Team(m_Snap.m_SpecInfo.m_SpectatorID); - return m_Teams.Team(m_Snap.m_LocalClientID); } +bool CGameClient::IsLocalCharSuper() +{ + if(m_Snap.m_LocalClientID < 0) + return 0; + return m_aClients[m_Snap.m_LocalClientID].m_Super; +} + void CGameClient::LoadGameSkin(const char *pPath, bool AsDir) { if(m_GameSkinLoaded) diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 4ff4daef8..be2b1664b 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -512,6 +512,7 @@ public: void Echo(const char *pString); bool IsOtherTeam(int ClientID); int OwnTeam(); + bool IsLocalCharSuper(); bool CanDisplayWarning(); bool IsDisplayingWarning(); diff --git a/src/game/server/entities/door.cpp b/src/game/server/entities/door.cpp index 1a8a7ec53..95ed2eafd 100644 --- a/src/game/server/entities/door.cpp +++ b/src/game/server/entities/door.cpp @@ -62,12 +62,6 @@ void CDoor::Snap(int SnappingClient) pObj->m_X = (int)m_Pos.x; pObj->m_Y = (int)m_Pos.y; - CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient); - int Tick = (Server()->Tick() % Server()->TickSpeed()) % 11; - - if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) - Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); - int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; if(SnappingClientVersion >= VERSION_DDNET_SWITCH) @@ -76,29 +70,23 @@ void CDoor::Snap(int SnappingClient) pObj->m_FromY = (int)m_To.y; pObj->m_StartTick = 0; } - else if(Char) + else { - if(Char->Team() == TEAM_SUPER) + CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient); + + if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) + Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); + + if(Char && Char->Team() != TEAM_SUPER && Char->IsAlive() && GameServer()->Collision()->m_NumSwitchers > 0 && GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()]) + { + pObj->m_FromX = (int)m_To.x; + pObj->m_FromY = (int)m_To.y; + } + else { pObj->m_FromX = (int)m_Pos.x; pObj->m_FromY = (int)m_Pos.y; } - else - { - if(Char->IsAlive() && GameServer()->Collision()->m_NumSwitchers > 0 && !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()] && (!Tick)) - return; - - if(Char->IsAlive() && GameServer()->Collision()->m_NumSwitchers > 0 && GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()]) - { - pObj->m_FromX = (int)m_To.x; - pObj->m_FromY = (int)m_To.y; - } - else - { - pObj->m_FromX = (int)m_Pos.x; - pObj->m_FromY = (int)m_Pos.y; - } - pObj->m_StartTick = Server()->Tick(); - } + pObj->m_StartTick = Server()->Tick(); } } diff --git a/src/game/server/entities/dragger.cpp b/src/game/server/entities/dragger.cpp index fcf735402..aed4f80d6 100644 --- a/src/game/server/entities/dragger.cpp +++ b/src/game/server/entities/dragger.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "character.h" @@ -164,6 +165,16 @@ void CDragger::Snap(int SnappingClient) if(((CGameControllerDDRace *)GameServer()->m_pController)->m_Teams.GetTeamState(m_CaughtTeam) == CGameTeams::TEAMSTATE_EMPTY) return; + CNetObj_EntityEx *pEntData = static_cast(Server()->SnapNewItem(NETOBJTYPE_ENTITYEX, GetID(), sizeof(CNetObj_EntityEx))); + if(!pEntData) + return; + + pEntData->m_SwitchNumber = m_Number; + pEntData->m_Layer = m_Layer; + pEntData->m_EntityClass = clamp(ENTITYCLASS_DRAGGER_WEAK + round_to_int(m_Strength) - 1, (int)ENTITYCLASS_DRAGGER_WEAK, (int)ENTITYCLASS_DRAGGER_STRONG); + + int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; + CCharacter *Target = m_Target; for(int &SoloID : m_SoloIDs) @@ -200,9 +211,13 @@ void CDragger::Snap(int SnappingClient) if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); - int Tick = (Server()->Tick() % Server()->TickSpeed()) % 11; - if(Char && Char->IsAlive() && (m_Layer == LAYER_SWITCH && m_Number && !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()] && (!Tick))) - continue; + if(i != -1 || SnappingClientVersion < VERSION_DDNET_SWITCH) + { + int Tick = (Server()->Tick() % Server()->TickSpeed()) % 11; + if(Char && Char->IsAlive() && (m_Layer == LAYER_SWITCH && m_Number && !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()] && (!Tick))) + continue; + } + if(Char && Char->IsAlive()) { if(Char->Team() != m_CaughtTeam) @@ -250,12 +265,19 @@ void CDragger::Snap(int SnappingClient) obj->m_FromY = (int)m_Pos.y; } - int StartTick = m_EvalTick; - if(StartTick < Server()->Tick() - 4) - StartTick = Server()->Tick() - 4; - else if(StartTick > Server()->Tick()) - StartTick = Server()->Tick(); - obj->m_StartTick = StartTick; + if(i != -1 || SnappingClientVersion < VERSION_DDNET_SWITCH) + { + int StartTick = m_EvalTick; + if(StartTick < Server()->Tick() - 4) + StartTick = Server()->Tick() - 4; + else if(StartTick > Server()->Tick()) + StartTick = Server()->Tick(); + obj->m_StartTick = StartTick; + } + else + { + obj->m_StartTick = 0; + } } } diff --git a/src/game/server/entities/gun.cpp b/src/game/server/entities/gun.cpp index e90298378..042e7f879 100644 --- a/src/game/server/entities/gun.cpp +++ b/src/game/server/entities/gun.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "character.h" #include "gun.h" @@ -111,6 +112,22 @@ void CGun::Tick() void CGun::Snap(int SnappingClient) { + CNetObj_EntityEx *pEntData = static_cast(Server()->SnapNewItem(NETOBJTYPE_ENTITYEX, GetID(), sizeof(CNetObj_EntityEx))); + if(!pEntData) + return; + + pEntData->m_SwitchNumber = m_Number; + pEntData->m_Layer = m_Layer; + + if(m_Explosive && !m_Freeze) + pEntData->m_EntityClass = ENTITYCLASS_GUN_NORMAL; + else if(m_Explosive && m_Freeze) + pEntData->m_EntityClass = ENTITYCLASS_GUN_EXPLOSIVE; + else if(!m_Explosive && m_Freeze) + pEntData->m_EntityClass = ENTITYCLASS_GUN_FREEZE; + else + pEntData->m_EntityClass = ENTITYCLASS_GUN_UNFREEZE; + if(NetworkClipped(SnappingClient)) return; @@ -120,9 +137,14 @@ void CGun::Snap(int SnappingClient) GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); - int Tick = (Server()->Tick() % Server()->TickSpeed()) % 11; - if(Char && Char->IsAlive() && (m_Layer == LAYER_SWITCH && m_Number > 0 && !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()]) && (!Tick)) - return; + int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; + if(SnappingClientVersion < VERSION_DDNET_SWITCH) + { + int Tick = (Server()->Tick() % Server()->TickSpeed()) % 11; + if(Char && Char->IsAlive() && (m_Layer == LAYER_SWITCH && m_Number > 0 && !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()]) && (!Tick)) + return; + } + CNetObj_Laser *pObj = static_cast(Server()->SnapNewItem(NETOBJTYPE_LASER, GetID(), sizeof(CNetObj_Laser))); if(!pObj) diff --git a/src/game/server/entities/light.cpp b/src/game/server/entities/light.cpp index 561f1d24d..bca643fbc 100644 --- a/src/game/server/entities/light.cpp +++ b/src/game/server/entities/light.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "character.h" @@ -101,6 +102,14 @@ void CLight::Tick() void CLight::Snap(int SnappingClient) { + CNetObj_EntityEx *pEntData = static_cast(Server()->SnapNewItem(NETOBJTYPE_ENTITYEX, GetID(), sizeof(CNetObj_EntityEx))); + if(!pEntData) + return; + + pEntData->m_SwitchNumber = m_Number; + pEntData->m_Layer = m_Layer; + pEntData->m_EntityClass = ENTITYCLASS_LIGHT; + if(NetworkClipped(SnappingClient, m_Pos) && NetworkClipped(SnappingClient, m_To)) return; @@ -109,10 +118,13 @@ void CLight::Snap(int SnappingClient) if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); - int Tick = (Server()->Tick() % Server()->TickSpeed()) % 6; - - if(Char && Char->IsAlive() && m_Layer == LAYER_SWITCH && m_Number > 0 && !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()] && (Tick)) - return; + int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; + if(SnappingClientVersion < VERSION_DDNET_SWITCH) + { + int Tick = (Server()->Tick() % Server()->TickSpeed()) % 6; + if(Char && Char->IsAlive() && m_Layer == LAYER_SWITCH && m_Number > 0 && !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()] && Tick) + return; + } CNetObj_Laser *pObj = static_cast(Server()->SnapNewItem( NETOBJTYPE_LASER, GetID(), sizeof(CNetObj_Laser)));