Fix switch state for super, cleanup door snapping, add dragger/gun/light

This commit is contained in:
trml 2021-10-14 22:59:39 +02:00
parent f0bd4cf5fa
commit 71e5b7ed3a
8 changed files with 129 additions and 58 deletions

View file

@ -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 = '''

View file

@ -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,17 +416,29 @@ 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(BlinkingSwitchDoor)
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(Inactive && BlinkingDragger)
continue;
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);
}
}
RenderLaser(&Laser);
}
}

View file

@ -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)

View file

@ -512,6 +512,7 @@ public:
void Echo(const char *pString);
bool IsOtherTeam(int ClientID);
int OwnTeam();
bool IsLocalCharSuper();
bool CanDisplayWarning();
bool IsDisplayingWarning();

View file

@ -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,19 +70,14 @@ void CDoor::Snap(int SnappingClient)
pObj->m_FromY = (int)m_To.y;
pObj->m_StartTick = 0;
}
else if(Char)
{
if(Char->Team() == TEAM_SUPER)
{
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;
CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient);
if(Char->IsAlive() && GameServer()->Collision()->m_NumSwitchers > 0 && GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()])
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;
@ -100,5 +89,4 @@ void CDoor::Snap(int SnappingClient)
}
pObj->m_StartTick = Server()->Tick();
}
}
}

View file

@ -8,6 +8,7 @@
#include <game/server/gamemodes/DDRace.h>
#include <game/server/player.h>
#include <game/server/teams.h>
#include <game/version.h>
#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<CNetObj_EntityEx *>(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);
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,6 +265,8 @@ void CDragger::Snap(int SnappingClient)
obj->m_FromY = (int)m_Pos.y;
}
if(i != -1 || SnappingClientVersion < VERSION_DDNET_SWITCH)
{
int StartTick = m_EvalTick;
if(StartTick < Server()->Tick() - 4)
StartTick = Server()->Tick() - 4;
@ -257,6 +274,11 @@ void CDragger::Snap(int SnappingClient)
StartTick = Server()->Tick();
obj->m_StartTick = StartTick;
}
else
{
obj->m_StartTick = 0;
}
}
}
CDraggerTeam::CDraggerTeam(CGameWorld *pGameWorld, vec2 Pos, float Strength,

View file

@ -5,6 +5,7 @@
#include <game/server/gamecontext.h>
#include <game/server/player.h>
#include <game/server/teams.h>
#include <game/version.h>
#include "character.h"
#include "gun.h"
@ -111,6 +112,22 @@ void CGun::Tick()
void CGun::Snap(int SnappingClient)
{
CNetObj_EntityEx *pEntData = static_cast<CNetObj_EntityEx *>(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 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<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, GetID(), sizeof(CNetObj_Laser)));
if(!pObj)

View file

@ -6,6 +6,7 @@
#include <game/mapitems.h>
#include <game/server/gamecontext.h>
#include <game/server/player.h>
#include <game/version.h>
#include "character.h"
@ -101,6 +102,14 @@ void CLight::Tick()
void CLight::Snap(int SnappingClient)
{
CNetObj_EntityEx *pEntData = static_cast<CNetObj_EntityEx *>(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 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))
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<CNetObj_Laser *>(Server()->SnapNewItem(
NETOBJTYPE_LASER, GetID(), sizeof(CNetObj_Laser)));