From 7efe2b436ebc472b16c5caa07bdb803d348139f7 Mon Sep 17 00:00:00 2001 From: Ryozuki Date: Tue, 2 Oct 2018 14:32:59 +0200 Subject: [PATCH 1/9] code improvement on gameclient.cpp --- src/game/client/gameclient.cpp | 262 ++++++++++++++++----------------- 1 file changed, 124 insertions(+), 138 deletions(-) diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 0aa8758fd..31cd3482e 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -345,9 +345,9 @@ void CGameClient::OnInit() for(unsigned int i = 0; i < 16; i++) { if(rand() % 2) - g_Config.m_ClTimeoutCode[i] = (rand() % 26) + 97; + g_Config.m_ClTimeoutCode[i] = static_cast((rand() % 26) + 97); else - g_Config.m_ClTimeoutCode[i] = (rand() % 26) + 65; + g_Config.m_ClTimeoutCode[i] = static_cast((rand() % 26) + 65); } } @@ -356,9 +356,9 @@ void CGameClient::OnInit() for(unsigned int i = 0; i < 16; i++) { if(rand() % 2) - g_Config.m_ClDummyTimeoutCode[i] = (rand() % 26) + 97; + g_Config.m_ClDummyTimeoutCode[i] = static_cast((rand() % 26) + 97); else - g_Config.m_ClDummyTimeoutCode[i] = (rand() % 26) + 65; + g_Config.m_ClDummyTimeoutCode[i] = static_cast((rand() % 26) + 65); } } } @@ -446,8 +446,8 @@ int CGameClient::OnSnapInput(int *pData, bool Dummy, bool Force) vec2 Main = m_LocalCharacterPos; vec2 Dummy = m_aClients[m_LocalIDs[!g_Config.m_ClDummy]].m_Predicted.m_Pos; vec2 Dir = Main - Dummy; - m_HammerInput.m_TargetX = Dir.x; - m_HammerInput.m_TargetY = Dir.y; + m_HammerInput.m_TargetX = static_cast(Dir.x); + m_HammerInput.m_TargetY = static_cast(Dir.y); mem_copy(pData, &m_HammerInput, sizeof(m_HammerInput)); return sizeof(m_HammerInput); @@ -1019,7 +1019,7 @@ void CGameClient::OnNewSnapshot() char aMessage[64]; int MsgLen = rand()%(sizeof(aMessage)-1); for(int i = 0; i < MsgLen; i++) - aMessage[i] = 'a'+(rand()%('z'-'a')); + aMessage[i] = static_cast('a' + (rand() % ('z' - 'a'))); aMessage[MsgLen] = 0; CNetMsg_Cl_Say Msg; @@ -1135,7 +1135,7 @@ void CGameClient::OnNewSnapshot() static bool s_GameOver = 0; static bool s_GamePaused = 0; m_Snap.m_pGameInfoObj = (const CNetObj_GameInfo *)pData; - bool CurrentTickGameOver = m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER; + bool CurrentTickGameOver = static_cast(m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_GAMEOVER); if(!s_GameOver && CurrentTickGameOver) OnGameOver(); else if(s_GameOver && !CurrentTickGameOver) @@ -1150,7 +1150,7 @@ void CGameClient::OnNewSnapshot() m_pStatboard->OnReset(); m_LastRoundStartTick = m_Snap.m_pGameInfoObj->m_RoundStartTick; s_GameOver = CurrentTickGameOver; - s_GamePaused = m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED; + s_GamePaused = static_cast(m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED); } else if(Item.m_Type == NETOBJTYPE_GAMEDATA) { @@ -1228,19 +1228,17 @@ void CGameClient::OnNewSnapshot() // update friend state for(int i = 0; i < MAX_CLIENTS; ++i) { - if(i == m_Snap.m_LocalClientID || !m_Snap.m_paPlayerInfos[i] || !Friends()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)) - m_aClients[i].m_Friend = false; - else - m_aClients[i].m_Friend = true; + m_aClients[i].m_Friend = !(i == m_Snap.m_LocalClientID + || !m_Snap.m_paPlayerInfos[i] + || !Friends()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)); } // update foe state for(int i = 0; i < MAX_CLIENTS; ++i) { - if(i == m_Snap.m_LocalClientID || !m_Snap.m_paPlayerInfos[i] || !Foes()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)) - m_aClients[i].m_Foe = false; - else - m_aClients[i].m_Foe = true; + m_aClients[i].m_Foe = !(i == m_Snap.m_LocalClientID + || !m_Snap.m_paPlayerInfos[i] + || !Foes()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)); } // sort player infos by name @@ -1414,7 +1412,6 @@ void CGameClient::OnPredict() class CLocalProjectile PredictedProjectiles[MaxProjectiles]; int NumProjectiles = 0; int ReloadTimer = 0; - vec2 PrevPos; if(AntiPingWeapons()) { @@ -1518,125 +1515,117 @@ void CGameClient::OnPredict() bool WeaponFired = false; bool NewPresses = false; + // handle weapons - do - { - if(ReloadTimer) - break; - if(!World.m_apCharacters[m_Snap.m_LocalClientID]) - break; - if(!pInput || !pPrevInput) - break; + if(ReloadTimer) + break; + if(!World.m_apCharacters[m_Snap.m_LocalClientID]) + break; + if(!pInput || !pPrevInput) + break; + bool FullAuto = false; + if(Local->m_ActiveWeapon == WEAPON_GRENADE || Local->m_ActiveWeapon == WEAPON_SHOTGUN || Local->m_ActiveWeapon == WEAPON_RIFLE) + FullAuto = true; + bool WillFire = false; + if(CountInput(PrevInput.m_Fire, Input.m_Fire).m_Presses) + { + WillFire = true; + NewPresses = true; + } + if(FullAuto && (Input.m_Fire & 1)) + WillFire = true; + if(!WillFire) + break; + if(!IsRace(&Info) && !m_Snap.m_pLocalCharacter->m_AmmoCount && Local->m_ActiveWeapon != WEAPON_HAMMER) + break; + int ExpectedStartTick = Tick - 1; + ReloadTimer = g_pData->m_Weapons.m_aId[Local->m_ActiveWeapon].m_Firedelay * SERVER_TICK_SPEED / 1000; + bool DirectInput = Client()->InputExists(Tick); + if(!DirectInput) + { + ReloadTimer++; + ExpectedStartTick++; + } + switch(Local->m_ActiveWeapon) + { + case WEAPON_RIFLE: + case WEAPON_SHOTGUN: + case WEAPON_GUN: + { + WeaponFired = true; + } break; + case WEAPON_GRENADE: + { + if(NumProjectiles >= MaxProjectiles) + break; + PredictedProjectiles[NumProjectiles].Init( + this, &World, Collision(), + Direction, //StartDir + ProjStartPos, //StartPos + ExpectedStartTick, //StartTick + WEAPON_GRENADE, //Type + m_Snap.m_LocalClientID, //Owner + WEAPON_GRENADE, //Weapon + 1, 0, 0, 1); //Explosive, Bouncing, Freeze, ExtraInfo + NumProjectiles++; + WeaponFired = true; + } break; + case WEAPON_HAMMER: + { + vec2 ProjPos = ProjStartPos; + float Radius = ProximityRadius*0.5f; - bool FullAuto = false; - if(Local->m_ActiveWeapon == WEAPON_GRENADE || Local->m_ActiveWeapon == WEAPON_SHOTGUN || Local->m_ActiveWeapon == WEAPON_RIFLE) - FullAuto = true; + int Hits = 0; + bool OwnerCanProbablyHitOthers = (m_Tuning[g_Config.m_ClDummy].m_PlayerCollision || m_Tuning[g_Config.m_ClDummy].m_PlayerHooking); + if(!OwnerCanProbablyHitOthers) + break; + for(int i = 0; i < MAX_CLIENTS; i++) + { + if(!World.m_apCharacters[i]) + continue; + if(i == m_Snap.m_LocalClientID) + continue; + if(distance(World.m_apCharacters[i]->m_Pos, ProjPos) >= Radius + ProximityRadius) + continue; - bool WillFire = false; + CCharacterCore *pTarget = World.m_apCharacters[i]; - if(CountInput(PrevInput.m_Fire, Input.m_Fire).m_Presses) - { - WillFire = true; - NewPresses = true; - } - if(FullAuto && (Input.m_Fire&1)) - WillFire = true; - if(!WillFire) - break; - if(!IsRace(&Info) && !m_Snap.m_pLocalCharacter->m_AmmoCount && Local->m_ActiveWeapon != WEAPON_HAMMER) - break; + if(m_aClients[i].m_Active && !m_Teams.CanCollide(i, m_Snap.m_LocalClientID)) + continue; - int ExpectedStartTick = Tick-1; - ReloadTimer = g_pData->m_Weapons.m_aId[Local->m_ActiveWeapon].m_Firedelay * SERVER_TICK_SPEED / 1000; + vec2 Dir; + if(length(pTarget->m_Pos - Pos) > 0.0f) + Dir = normalize(pTarget->m_Pos - Pos); + else + Dir = vec2(0.f, -1.f); - bool DirectInput = Client()->InputExists(Tick); - if(!DirectInput) - { - ReloadTimer++; - ExpectedStartTick++; - } + float Strength; + Strength = World.m_Tuning[g_Config.m_ClDummy].m_HammerStrength; - switch(Local->m_ActiveWeapon) - { - case WEAPON_RIFLE: - case WEAPON_SHOTGUN: - case WEAPON_GUN: - { - WeaponFired = true; - } break; - case WEAPON_GRENADE: - { - if(NumProjectiles >= MaxProjectiles) - break; - PredictedProjectiles[NumProjectiles].Init( - this, &World, Collision(), - Direction, //StartDir - ProjStartPos, //StartPos - ExpectedStartTick, //StartTick - WEAPON_GRENADE, //Type - m_Snap.m_LocalClientID, //Owner - WEAPON_GRENADE, //Weapon - 1, 0, 0, 1); //Explosive, Bouncing, Freeze, ExtraInfo - NumProjectiles++; - WeaponFired = true; - } break; - case WEAPON_HAMMER: - { - vec2 ProjPos = ProjStartPos; - float Radius = ProximityRadius*0.5f; + vec2 Temp = pTarget->m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f; - int Hits = 0; - bool OwnerCanProbablyHitOthers = (m_Tuning[g_Config.m_ClDummy].m_PlayerCollision || m_Tuning[g_Config.m_ClDummy].m_PlayerHooking); - if(!OwnerCanProbablyHitOthers) - break; - for(int i = 0; i < MAX_CLIENTS; i++) - { - if(!World.m_apCharacters[i]) - continue; - if(i == m_Snap.m_LocalClientID) - continue; - if(!(distance(World.m_apCharacters[i]->m_Pos, ProjPos) < Radius+ProximityRadius)) - continue; + pTarget->LimitForce(&Temp); - CCharacterCore *pTarget = World.m_apCharacters[i]; + Temp -= pTarget->m_Vel; + pTarget->ApplyForce((vec2(0.f, -1.0f) + Temp) * Strength); + Hits++; + } + // if we Hit anything, we have to wait for the reload + if(Hits) + { + ReloadTimer = SERVER_TICK_SPEED/3; + WeaponFired = true; + } + } break; + } + if(!ReloadTimer) + { + ReloadTimer = g_pData->m_Weapons.m_aId[Local->m_ActiveWeapon].m_Firedelay * SERVER_TICK_SPEED / 1000; + if(!DirectInput) + ReloadTimer++; + } - if(m_aClients[i].m_Active && !m_Teams.CanCollide(i, m_Snap.m_LocalClientID)) - continue; - - vec2 Dir; - if(length(pTarget->m_Pos - Pos) > 0.0f) - Dir = normalize(pTarget->m_Pos - Pos); - else - Dir = vec2(0.f, -1.f); - - float Strength; - Strength = World.m_Tuning[g_Config.m_ClDummy].m_HammerStrength; - - vec2 Temp = pTarget->m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f; - - pTarget->LimitForce(&Temp); - - Temp -= pTarget->m_Vel; - pTarget->ApplyForce((vec2(0.f, -1.0f) + Temp) * Strength); - Hits++; - } - // if we Hit anything, we have to wait for the reload - if(Hits) - { - ReloadTimer = SERVER_TICK_SPEED/3; - WeaponFired = true; - } - } break; - } - if(!ReloadTimer) - { - ReloadTimer = g_pData->m_Weapons.m_aId[Local->m_ActiveWeapon].m_Firedelay * SERVER_TICK_SPEED / 1000; - if(!DirectInput) - ReloadTimer++; - } - } while(false); - - if(ReloadTimer) + if(ReloadTimer) ReloadTimer--; if(Tick > Client()->GameTick()+1) @@ -1693,10 +1682,7 @@ void CGameClient::OnPredict() { if(!World.m_apCharacters[c]) continue; - if(m_Snap.m_LocalClientID == c) - World.m_apCharacters[c]->Tick(true, true); - else - World.m_apCharacters[c]->Tick(false, true); + World.m_apCharacters[c]->Tick(m_Snap.m_LocalClientID == c, true); } } @@ -2103,7 +2089,7 @@ void CLocalProjectile::Init(CGameClient *pGameClient, CWorldCore *pWorld, CColli { bool StandardVel = (fabs(1.0f - length(m_Direction)) < 0.015); m_Owner = -1; - m_Explosive = ((m_Type == WEAPON_GRENADE && StandardVel) ? true : false); + m_Explosive = m_Type == WEAPON_GRENADE && StandardVel; m_Bouncing = 0; m_Freeze = 0; m_ExtraInfo = false; @@ -2155,8 +2141,8 @@ vec2 CLocalProjectile::GetPos(float Time) bool CLocalProjectile::GameLayerClipped(vec2 CheckPos) { - return round_to_int(CheckPos.x)/32 < -200 || round_to_int(CheckPos.x)/32 > m_pCollision->GetWidth()+200 || - round_to_int(CheckPos.y)/32 < -200 || round_to_int(CheckPos.y)/32 > m_pCollision->GetHeight()+200 ? true : false; + return round_to_int(CheckPos.x) / 32 < -200 || round_to_int(CheckPos.x) / 32 > m_pCollision->GetWidth() + 200 || + round_to_int(CheckPos.y)/32 < -200 || round_to_int(CheckPos.y)/32 > m_pCollision->GetHeight()+200; } void CLocalProjectile::Tick(int CurrentTick, int GameTickSpeed, int LocalClientID) @@ -2183,7 +2169,7 @@ void CLocalProjectile::Tick(int CurrentTick, int GameTickSpeed, int LocalClientI bool OwnerCanProbablyHitOthers = (m_pWorld->m_Tuning[g_Config.m_ClDummy].m_PlayerCollision || m_pWorld->m_Tuning[g_Config.m_ClDummy].m_PlayerHooking); - if(((Target >= 0 && (m_Owner >= 0 ? OwnerCanProbablyHitOthers : 1 || Target == m_Owner)) || Collide || GameLayerClipped(CurPos)) && !IsWeaponCollide) + if(((Target >= 0 && (m_Owner >= 0 ? OwnerCanProbablyHitOthers : true)) || Collide || GameLayerClipped(CurPos)) && !IsWeaponCollide) { if(m_Explosive && (Target < 0 || (Target >= 0 && (!m_Freeze || (m_Weapon == WEAPON_SHOTGUN && Collide))))) CreateExplosion(ColPos, m_Owner); @@ -2209,11 +2195,11 @@ void CLocalProjectile::Tick(int CurrentTick, int GameTickSpeed, int LocalClientI { int Lifetime = 0; if(m_Weapon == WEAPON_GRENADE) - Lifetime = m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_GrenadeLifetime * SERVER_TICK_SPEED; + Lifetime = static_cast(m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_GrenadeLifetime * SERVER_TICK_SPEED); else if(m_Weapon == WEAPON_GUN) - Lifetime = m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_GrenadeLifetime * SERVER_TICK_SPEED; + Lifetime = static_cast(m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_GrenadeLifetime * SERVER_TICK_SPEED); else if(m_Weapon == WEAPON_SHOTGUN) - Lifetime = m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_ShotgunLifetime * SERVER_TICK_SPEED; + Lifetime = static_cast(m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_ShotgunLifetime * SERVER_TICK_SPEED); int LifeSpan = Lifetime - (CurrentTick - m_StartTick); if(LifeSpan == -1) { From e21a08f70054f1039dc82d85a427c03a1124204e Mon Sep 17 00:00:00 2001 From: Ryozuki Date: Tue, 2 Oct 2018 14:35:50 +0200 Subject: [PATCH 2/9] another improvement --- src/game/client/gameclient.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 31cd3482e..7791258fd 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -1225,20 +1225,17 @@ void CGameClient::OnNewSnapshot() } } - // update friend state for(int i = 0; i < MAX_CLIENTS; ++i) { + // update friend state m_aClients[i].m_Friend = !(i == m_Snap.m_LocalClientID || !m_Snap.m_paPlayerInfos[i] || !Friends()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)); - } - // update foe state - for(int i = 0; i < MAX_CLIENTS; ++i) - { + // update foe state m_aClients[i].m_Foe = !(i == m_Snap.m_LocalClientID - || !m_Snap.m_paPlayerInfos[i] - || !Foes()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)); + || !m_Snap.m_paPlayerInfos[i] + || !Foes()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)); } // sort player infos by name From 0a91fef8c8d81377e8272ce57b5a9b9448cedee8 Mon Sep 17 00:00:00 2001 From: Ryozuki Date: Tue, 2 Oct 2018 14:36:55 +0200 Subject: [PATCH 3/9] fix tabs --- src/game/client/gameclient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 7791258fd..d79a1ae59 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -1234,8 +1234,8 @@ void CGameClient::OnNewSnapshot() // update foe state m_aClients[i].m_Foe = !(i == m_Snap.m_LocalClientID - || !m_Snap.m_paPlayerInfos[i] - || !Foes()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)); + || !m_Snap.m_paPlayerInfos[i] + || !Foes()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)); } // sort player infos by name From be3cfe88e677fdf0c0a5d7eb71d27c5a2e58962b Mon Sep 17 00:00:00 2001 From: Ryozuki Date: Tue, 2 Oct 2018 20:45:44 +0200 Subject: [PATCH 4/9] fix --- src/game/client/gameclient.cpp | 199 ++++++++++++++++----------------- 1 file changed, 99 insertions(+), 100 deletions(-) diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index d79a1ae59..d26128f21 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -1514,113 +1514,112 @@ void CGameClient::OnPredict() bool NewPresses = false; // handle weapons - if(ReloadTimer) - break; - if(!World.m_apCharacters[m_Snap.m_LocalClientID]) - break; - if(!pInput || !pPrevInput) - break; - bool FullAuto = false; - if(Local->m_ActiveWeapon == WEAPON_GRENADE || Local->m_ActiveWeapon == WEAPON_SHOTGUN || Local->m_ActiveWeapon == WEAPON_RIFLE) - FullAuto = true; - bool WillFire = false; - if(CountInput(PrevInput.m_Fire, Input.m_Fire).m_Presses) - { - WillFire = true; - NewPresses = true; - } - if(FullAuto && (Input.m_Fire & 1)) - WillFire = true; - if(!WillFire) - break; - if(!IsRace(&Info) && !m_Snap.m_pLocalCharacter->m_AmmoCount && Local->m_ActiveWeapon != WEAPON_HAMMER) - break; - int ExpectedStartTick = Tick - 1; - ReloadTimer = g_pData->m_Weapons.m_aId[Local->m_ActiveWeapon].m_Firedelay * SERVER_TICK_SPEED / 1000; - bool DirectInput = Client()->InputExists(Tick); - if(!DirectInput) - { - ReloadTimer++; - ExpectedStartTick++; - } - switch(Local->m_ActiveWeapon) - { - case WEAPON_RIFLE: - case WEAPON_SHOTGUN: - case WEAPON_GUN: - { - WeaponFired = true; - } break; - case WEAPON_GRENADE: - { - if(NumProjectiles >= MaxProjectiles) - break; - PredictedProjectiles[NumProjectiles].Init( - this, &World, Collision(), - Direction, //StartDir - ProjStartPos, //StartPos - ExpectedStartTick, //StartTick - WEAPON_GRENADE, //Type - m_Snap.m_LocalClientID, //Owner - WEAPON_GRENADE, //Weapon - 1, 0, 0, 1); //Explosive, Bouncing, Freeze, ExtraInfo - NumProjectiles++; - WeaponFired = true; - } break; - case WEAPON_HAMMER: - { - vec2 ProjPos = ProjStartPos; - float Radius = ProximityRadius*0.5f; - int Hits = 0; - bool OwnerCanProbablyHitOthers = (m_Tuning[g_Config.m_ClDummy].m_PlayerCollision || m_Tuning[g_Config.m_ClDummy].m_PlayerHooking); - if(!OwnerCanProbablyHitOthers) - break; - for(int i = 0; i < MAX_CLIENTS; i++) - { - if(!World.m_apCharacters[i]) - continue; - if(i == m_Snap.m_LocalClientID) - continue; - if(distance(World.m_apCharacters[i]->m_Pos, ProjPos) >= Radius + ProximityRadius) - continue; + if(!ReloadTimer && World.m_apCharacters[m_Snap.m_LocalClientID] && (pInput && pPrevInput)) + { + bool FullAuto = false; + if(Local->m_ActiveWeapon == WEAPON_GRENADE || Local->m_ActiveWeapon == WEAPON_SHOTGUN || Local->m_ActiveWeapon == WEAPON_RIFLE) + FullAuto = true; - CCharacterCore *pTarget = World.m_apCharacters[i]; + bool WillFire = false; + if(CountInput(PrevInput.m_Fire, Input.m_Fire).m_Presses) + { + WillFire = true; + NewPresses = true; + } - if(m_aClients[i].m_Active && !m_Teams.CanCollide(i, m_Snap.m_LocalClientID)) - continue; + if(FullAuto && (Input.m_Fire & 1)) + WillFire = true; - vec2 Dir; - if(length(pTarget->m_Pos - Pos) > 0.0f) - Dir = normalize(pTarget->m_Pos - Pos); - else - Dir = vec2(0.f, -1.f); + if(WillFire && ((IsRace(&Info) || m_Snap.m_pLocalCharacter->m_AmmoCount) || Local->m_ActiveWeapon == WEAPON_HAMMER)) { + int ExpectedStartTick = Tick - 1; + ReloadTimer = g_pData->m_Weapons.m_aId[Local->m_ActiveWeapon].m_Firedelay * SERVER_TICK_SPEED / 1000; + bool DirectInput = Client()->InputExists(Tick); + if(!DirectInput) + { + ReloadTimer++; + ExpectedStartTick++; + } + switch(Local->m_ActiveWeapon) + { + case WEAPON_RIFLE: + case WEAPON_SHOTGUN: + case WEAPON_GUN: + { + WeaponFired = true; + } break; + case WEAPON_GRENADE: + { + if(NumProjectiles >= MaxProjectiles) + break; + PredictedProjectiles[NumProjectiles].Init( + this, &World, Collision(), + Direction, //StartDir + ProjStartPos, //StartPos + ExpectedStartTick, //StartTick + WEAPON_GRENADE, //Type + m_Snap.m_LocalClientID, //Owner + WEAPON_GRENADE, //Weapon + 1, 0, 0, 1); //Explosive, Bouncing, Freeze, ExtraInfo + NumProjectiles++; + WeaponFired = true; + } break; + case WEAPON_HAMMER: + { + vec2 ProjPos = ProjStartPos; + float Radius = ProximityRadius*0.5f; - float Strength; - Strength = World.m_Tuning[g_Config.m_ClDummy].m_HammerStrength; + int Hits = 0; + bool OwnerCanProbablyHitOthers = (m_Tuning[g_Config.m_ClDummy].m_PlayerCollision || m_Tuning[g_Config.m_ClDummy].m_PlayerHooking); + if(!OwnerCanProbablyHitOthers) + break; + for(int i = 0; i < MAX_CLIENTS; i++) + { + if(!World.m_apCharacters[i]) + continue; + if(i == m_Snap.m_LocalClientID) + continue; + if(distance(World.m_apCharacters[i]->m_Pos, ProjPos) >= Radius + ProximityRadius) + continue; - vec2 Temp = pTarget->m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f; + CCharacterCore *pTarget = World.m_apCharacters[i]; - pTarget->LimitForce(&Temp); + if(m_aClients[i].m_Active && !m_Teams.CanCollide(i, m_Snap.m_LocalClientID)) + continue; - Temp -= pTarget->m_Vel; - pTarget->ApplyForce((vec2(0.f, -1.0f) + Temp) * Strength); - Hits++; - } - // if we Hit anything, we have to wait for the reload - if(Hits) - { - ReloadTimer = SERVER_TICK_SPEED/3; - WeaponFired = true; - } - } break; - } - if(!ReloadTimer) - { - ReloadTimer = g_pData->m_Weapons.m_aId[Local->m_ActiveWeapon].m_Firedelay * SERVER_TICK_SPEED / 1000; - if(!DirectInput) - ReloadTimer++; - } + vec2 Dir; + if(length(pTarget->m_Pos - Pos) > 0.0f) + Dir = normalize(pTarget->m_Pos - Pos); + else + Dir = vec2(0.f, -1.f); + + float Strength; + Strength = World.m_Tuning[g_Config.m_ClDummy].m_HammerStrength; + + vec2 Temp = pTarget->m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f; + + pTarget->LimitForce(&Temp); + + Temp -= pTarget->m_Vel; + pTarget->ApplyForce((vec2(0.f, -1.0f) + Temp) * Strength); + Hits++; + } + // if we Hit anything, we have to wait for the reload + if(Hits) + { + ReloadTimer = SERVER_TICK_SPEED/3; + WeaponFired = true; + } + } break; + } + if(!ReloadTimer) + { + ReloadTimer = g_pData->m_Weapons.m_aId[Local->m_ActiveWeapon].m_Firedelay * SERVER_TICK_SPEED / 1000; + if(!DirectInput) + ReloadTimer++; + } + } + } if(ReloadTimer) ReloadTimer--; @@ -1679,7 +1678,7 @@ void CGameClient::OnPredict() { if(!World.m_apCharacters[c]) continue; - World.m_apCharacters[c]->Tick(m_Snap.m_LocalClientID == c, true); + World.m_apCharacters[c]->Tick(m_Snap.m_LocalClientID == c, true); } } From 5c51e3b80de618c5b929e45ac2529524b83589a3 Mon Sep 17 00:00:00 2001 From: Ryozuki Date: Tue, 2 Oct 2018 20:52:21 +0200 Subject: [PATCH 5/9] change to c style casts --- src/game/client/gameclient.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index d26128f21..26e2909ca 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -345,9 +345,9 @@ void CGameClient::OnInit() for(unsigned int i = 0; i < 16; i++) { if(rand() % 2) - g_Config.m_ClTimeoutCode[i] = static_cast((rand() % 26) + 97); + g_Config.m_ClTimeoutCode[i] =(char)((rand() % 26) + 97); else - g_Config.m_ClTimeoutCode[i] = static_cast((rand() % 26) + 65); + g_Config.m_ClTimeoutCode[i] = (char)((rand() % 26) + 65); } } @@ -356,9 +356,9 @@ void CGameClient::OnInit() for(unsigned int i = 0; i < 16; i++) { if(rand() % 2) - g_Config.m_ClDummyTimeoutCode[i] = static_cast((rand() % 26) + 97); + g_Config.m_ClDummyTimeoutCode[i] = (char)((rand() % 26) + 97); else - g_Config.m_ClDummyTimeoutCode[i] = static_cast((rand() % 26) + 65); + g_Config.m_ClDummyTimeoutCode[i] = (char)((rand() % 26) + 65); } } } @@ -446,8 +446,8 @@ int CGameClient::OnSnapInput(int *pData, bool Dummy, bool Force) vec2 Main = m_LocalCharacterPos; vec2 Dummy = m_aClients[m_LocalIDs[!g_Config.m_ClDummy]].m_Predicted.m_Pos; vec2 Dir = Main - Dummy; - m_HammerInput.m_TargetX = static_cast(Dir.x); - m_HammerInput.m_TargetY = static_cast(Dir.y); + m_HammerInput.m_TargetX = (int)(Dir.x); + m_HammerInput.m_TargetY = (int)(Dir.y); mem_copy(pData, &m_HammerInput, sizeof(m_HammerInput)); return sizeof(m_HammerInput); @@ -1019,7 +1019,7 @@ void CGameClient::OnNewSnapshot() char aMessage[64]; int MsgLen = rand()%(sizeof(aMessage)-1); for(int i = 0; i < MsgLen; i++) - aMessage[i] = static_cast('a' + (rand() % ('z' - 'a'))); + aMessage[i] = (char)('a' + (rand() % ('z' - 'a'))); aMessage[MsgLen] = 0; CNetMsg_Cl_Say Msg; @@ -1135,7 +1135,7 @@ void CGameClient::OnNewSnapshot() static bool s_GameOver = 0; static bool s_GamePaused = 0; m_Snap.m_pGameInfoObj = (const CNetObj_GameInfo *)pData; - bool CurrentTickGameOver = static_cast(m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_GAMEOVER); + bool CurrentTickGameOver = (bool)(m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_GAMEOVER); if(!s_GameOver && CurrentTickGameOver) OnGameOver(); else if(s_GameOver && !CurrentTickGameOver) @@ -1150,7 +1150,7 @@ void CGameClient::OnNewSnapshot() m_pStatboard->OnReset(); m_LastRoundStartTick = m_Snap.m_pGameInfoObj->m_RoundStartTick; s_GameOver = CurrentTickGameOver; - s_GamePaused = static_cast(m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED); + s_GamePaused = (bool)(m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED); } else if(Item.m_Type == NETOBJTYPE_GAMEDATA) { @@ -2191,11 +2191,11 @@ void CLocalProjectile::Tick(int CurrentTick, int GameTickSpeed, int LocalClientI { int Lifetime = 0; if(m_Weapon == WEAPON_GRENADE) - Lifetime = static_cast(m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_GrenadeLifetime * SERVER_TICK_SPEED); + Lifetime = (int)(m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_GrenadeLifetime * SERVER_TICK_SPEED); else if(m_Weapon == WEAPON_GUN) - Lifetime = static_cast(m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_GrenadeLifetime * SERVER_TICK_SPEED); + Lifetime = (int)(m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_GrenadeLifetime * SERVER_TICK_SPEED); else if(m_Weapon == WEAPON_SHOTGUN) - Lifetime = static_cast(m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_ShotgunLifetime * SERVER_TICK_SPEED); + Lifetime = (int)(m_pGameClient->m_Tuning[g_Config.m_ClDummy].m_ShotgunLifetime * SERVER_TICK_SPEED); int LifeSpan = Lifetime - (CurrentTick - m_StartTick); if(LifeSpan == -1) { From 09c82fba7ad5755b9ebc5fb3822de585bad7dd68 Mon Sep 17 00:00:00 2001 From: Ryozuki Date: Wed, 3 Oct 2018 07:40:50 +0200 Subject: [PATCH 6/9] indent --- src/game/client/gameclient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 26e2909ca..340df4a1c 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -1621,7 +1621,7 @@ void CGameClient::OnPredict() } } - if(ReloadTimer) + if(ReloadTimer) ReloadTimer--; if(Tick > Client()->GameTick()+1) From cdce9d84ac0baab83c66e714052137a0e7fb7c49 Mon Sep 17 00:00:00 2001 From: Learath Date: Tue, 9 Oct 2018 13:41:52 +0300 Subject: [PATCH 7/9] Mark unused envelopes. Fix #1139 --- src/game/editor/editor.cpp | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index d1d6422db..97a5872d8 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -4647,7 +4647,34 @@ void CEditor::RenderEnvelopeEditor(CUIRect View) Shifter.VSplitLeft(15.0f, &Dec, &Shifter); char aBuf[512]; str_format(aBuf, sizeof(aBuf),"%d/%d", m_SelectedEnvelope+1, m_Map.m_lEnvelopes.size()); - RenderTools()->DrawUIRect(&Shifter, vec4(1,1,1,0.5f), 0, 0.0f); + + vec4 EnvColor = vec4(1, 1, 1, 0.5f); + if(m_Map.m_lEnvelopes.size()) + { + bool Found = false; + for(int i = 0; !Found && i < m_Map.m_lGroups.size(); ++i) + { + for(int j = 0; !Found && j < m_Map.m_lGroups[i]->m_lLayers.size(); ++j) + { + if(m_Map.m_lGroups[i]->m_lLayers[j]->m_Type == LAYERTYPE_QUADS) + { + CLayerQuads *pQuadLayer = (CLayerQuads *)m_Map.m_lGroups[i]->m_lLayers[j]; + for(int k = 0; !Found && k < pQuadLayer->m_lQuads.size(); k++) + { + if(pQuadLayer->m_lQuads[k].m_PosEnv == m_SelectedEnvelope + || pQuadLayer->m_lQuads[k].m_ColorEnv == m_SelectedEnvelope) + { + Found = true; + break; + } + } + } + } + } + EnvColor = Found ? vec4(0.7f, 1, 0.7f, 0.5f) : vec4(1, 0.7f, 0.7f, 0.5f); + } + + RenderTools()->DrawUIRect(&Shifter, EnvColor, 0, 0.0f); UI()->DoLabel(&Shifter, aBuf, 10.0f, 0, -1); static int s_PrevButton = 0; From c7750f3616586d5b68aae0f328741c68f1e44042 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Sun, 14 Oct 2018 08:18:32 +0200 Subject: [PATCH 8/9] Don't ignore CONNECT packets with data that we don't know This specifically affects 0.6.5. Just treat them the same way as those without any data. --- src/engine/shared/network_server.cpp | 55 ++++++++++++++++++---------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index d4e0abe65..705a19ad1 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -508,45 +508,38 @@ void CNetServer::OnConnCtrlMsg(NETADDR &Addr, int ClientID, int ControlMsg, cons void CNetServer::OnTokenCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketConstruct &Packet) { - if (ClientExists(Addr)) + if(ClientExists(Addr)) return; // silently ignore - if (Addr.type == NETTYPE_WEBSOCKET_IPV4) + if(Addr.type == NETTYPE_WEBSOCKET_IPV4) { // websocket client doesn't send token // direct accept SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC), NET_SECURITY_TOKEN_UNSUPPORTED); TryAcceptClient(Addr, NET_SECURITY_TOKEN_UNSUPPORTED); } - else if (ControlMsg == NET_CTRLMSG_CONNECT) + else if(ControlMsg == NET_CTRLMSG_CONNECT) { - bool SupportsToken = Packet.m_DataSize >= - (int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(SECURITY_TOKEN)) && - !mem_comp(&Packet.m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC)); - - if (SupportsToken) - { - // response connection request with token - SECURITY_TOKEN Token = GetToken(Addr); - SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC), Token); - } + // response connection request with token + SECURITY_TOKEN Token = GetToken(Addr); + SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC), Token); } - else if (ControlMsg == NET_CTRLMSG_ACCEPT && Packet.m_DataSize == 1 + sizeof(SECURITY_TOKEN)) + else if(ControlMsg == NET_CTRLMSG_ACCEPT) { SECURITY_TOKEN Token = ToSecurityToken(&Packet.m_aChunkData[1]); - if (Token == GetToken(Addr)) + if(Token == GetToken(Addr)) { // correct token // try to accept client - if (g_Config.m_Debug) + if(g_Config.m_Debug) dbg_msg("security", "new client (ddnet token)"); TryAcceptClient(Addr, Token); } else { // invalid token - if (g_Config.m_Debug) + if(g_Config.m_Debug) dbg_msg("security", "invalid token"); } } @@ -570,6 +563,29 @@ int CNetServer::GetClientSlot(const NETADDR &Addr) return Slot; } +static bool IsDDNetControlMsg(const CNetPacketConstruct *pPacket) +{ + if(!(pPacket->m_Flags&NET_PACKETFLAG_CONTROL) + || pPacket->m_DataSize < 1) + { + return false; + } + if(pPacket->m_aChunkData[0] == NET_CTRLMSG_CONNECT + && pPacket->m_DataSize >= (int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(SECURITY_TOKEN)) + && mem_comp(&pPacket->m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC)) == 0) + { + // DDNet CONNECT + return true; + } + if(pPacket->m_aChunkData[0] == NET_CTRLMSG_ACCEPT + && pPacket->m_DataSize >= 1 + (int)sizeof(SECURITY_TOKEN)) + { + // DDNet ACCEPT + return true; + } + return false; +} + /* TODO: chopp up this function into smaller working parts */ @@ -643,9 +659,8 @@ int CNetServer::Recv(CNetChunk *pChunk) { // not found, client that wants to connect - if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONTROL && - m_RecvUnpacker.m_Data.m_DataSize > 1) - // got control msg with extra size (should support token) + if(IsDDNetControlMsg(&m_RecvUnpacker.m_Data)) + // got ddnet control msg OnTokenCtrlMsg(Addr, m_RecvUnpacker.m_Data.m_aChunkData[0], m_RecvUnpacker.m_Data); else // got connection-less ctrl or sys msg From 657e86990147f4dad388692895ff78f4b7b1f956 Mon Sep 17 00:00:00 2001 From: Learath Date: Sun, 14 Oct 2018 16:53:14 +0300 Subject: [PATCH 9/9] Handle Tile and Sound layers --- src/game/editor/editor.cpp | 65 ++++++++++++++++++++++++++------------ src/game/editor/editor.h | 2 ++ 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 97a5872d8..3d7bac877 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -4558,6 +4558,47 @@ void CEditor::RenderUndoList(CUIRect View) } } +bool CEditor::IsEnvelopeUsed(int EnvelopeIndex) +{ + for(int i = 0; i < m_Map.m_lGroups.size(); i++) + { + for(int j = 0; j < m_Map.m_lGroups[i]->m_lLayers.size(); j++) + { + if(m_Map.m_lGroups[i]->m_lLayers[j]->m_Type == LAYERTYPE_QUADS) + { + CLayerQuads *pQuadLayer = (CLayerQuads *)m_Map.m_lGroups[i]->m_lLayers[j]; + for(int k = 0; k < pQuadLayer->m_lQuads.size(); k++) + { + if(pQuadLayer->m_lQuads[k].m_PosEnv == EnvelopeIndex + || pQuadLayer->m_lQuads[k].m_ColorEnv == EnvelopeIndex) + { + return true; + } + } + } + else if(m_Map.m_lGroups[i]->m_lLayers[j]->m_Type == LAYERTYPE_SOUNDS) + { + CLayerSounds *pSoundLayer = (CLayerSounds *)m_Map.m_lGroups[i]->m_lLayers[j]; + for(int k = 0; k < pSoundLayer->m_lSources.size(); k++) + { + if(pSoundLayer->m_lSources[k].m_PosEnv == EnvelopeIndex + || pSoundLayer->m_lSources[k].m_SoundEnv == EnvelopeIndex) + { + return true; + } + } + } + else if(m_Map.m_lGroups[i]->m_lLayers[j]->m_Type == LAYERTYPE_TILES) + { + CLayerTiles *pTileLayer = (CLayerTiles *)m_Map.m_lGroups[i]->m_lLayers[j]; + if(pTileLayer->m_ColorEnv == EnvelopeIndex) + return true; + } + } + } + return false; +} + void CEditor::RenderEnvelopeEditor(CUIRect View) { if(m_SelectedEnvelope < 0) m_SelectedEnvelope = 0; @@ -4651,27 +4692,9 @@ void CEditor::RenderEnvelopeEditor(CUIRect View) vec4 EnvColor = vec4(1, 1, 1, 0.5f); if(m_Map.m_lEnvelopes.size()) { - bool Found = false; - for(int i = 0; !Found && i < m_Map.m_lGroups.size(); ++i) - { - for(int j = 0; !Found && j < m_Map.m_lGroups[i]->m_lLayers.size(); ++j) - { - if(m_Map.m_lGroups[i]->m_lLayers[j]->m_Type == LAYERTYPE_QUADS) - { - CLayerQuads *pQuadLayer = (CLayerQuads *)m_Map.m_lGroups[i]->m_lLayers[j]; - for(int k = 0; !Found && k < pQuadLayer->m_lQuads.size(); k++) - { - if(pQuadLayer->m_lQuads[k].m_PosEnv == m_SelectedEnvelope - || pQuadLayer->m_lQuads[k].m_ColorEnv == m_SelectedEnvelope) - { - Found = true; - break; - } - } - } - } - } - EnvColor = Found ? vec4(0.7f, 1, 0.7f, 0.5f) : vec4(1, 0.7f, 0.7f, 0.5f); + EnvColor = IsEnvelopeUsed(m_SelectedEnvelope) ? + vec4(0.7f, 1, 0.7f, 0.5f) : + vec4(1, 0.7f, 0.7f, 0.5f); } RenderTools()->DrawUIRect(&Shifter, EnvColor, 0, 0.0f); diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 2fb11ec80..2adb839e1 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -1016,6 +1016,8 @@ public: static void AddImage(const char *pFilename, int StorageType, void *pUser); static void AddSound(const char *pFileName, int StorageType, void *pUser); + bool IsEnvelopeUsed(int EnvelopeIndex); + void RenderImages(CUIRect Toolbox, CUIRect View); void RenderLayers(CUIRect Toolbox, CUIRect View); void RenderSounds(CUIRect Toolbox, CUIRect View);