From eb1bacb969b3edc121934991380d1d03718cd718 Mon Sep 17 00:00:00 2001 From: trml Date: Sun, 26 Apr 2020 01:12:34 +0200 Subject: [PATCH 1/4] Update prediction with latest server physics --- src/game/client/components/items.cpp | 6 +- .../client/prediction/entities/character.cpp | 84 ++++++++++++------- .../client/prediction/entities/character.h | 3 +- .../client/prediction/entities/pickup.cpp | 2 +- .../client/prediction/entities/projectile.cpp | 22 +++-- .../client/prediction/entities/projectile.h | 2 - 6 files changed, 69 insertions(+), 50 deletions(-) diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp index 7a5a448da..cd6b32182 100644 --- a/src/game/client/components/items.cpp +++ b/src/game/client/components/items.cpp @@ -285,7 +285,7 @@ void CItems::OnRender() for(auto *pProj = (CProjectile*) GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile*) pProj->NextEntity()) { CNetObj_Projectile Data; - if(pProj->m_Weapon != WEAPON_SHOTGUN || pProj->m_Explosive || pProj->m_Freeze) + if(pProj->m_Type != WEAPON_SHOTGUN || pProj->m_Explosive || pProj->m_Freeze) pProj->FillExtraInfo(&Data); else pProj->FillInfo(&Data); @@ -324,8 +324,8 @@ void CItems::OnRender() if(auto *pProj = (CProjectile*) GameClient()->m_GameWorld.FindMatch(Item.m_ID, Item.m_Type, pData)) { if(pProj->m_LastRenderTick <= 0 - && (pProj->m_Weapon != WEAPON_SHOTGUN || (!pProj->m_Freeze && !pProj->m_Explosive)) // skip ddrace shotgun bullets - && (pProj->m_Weapon == WEAPON_SHOTGUN || fabs(length(pProj->m_Direction) - 1.f) < 0.02) // workaround to skip grenades on ball mod + && (pProj->m_Type != WEAPON_SHOTGUN || (!pProj->m_Freeze && !pProj->m_Explosive)) // skip ddrace shotgun bullets + && (pProj->m_Type == WEAPON_SHOTGUN || fabs(length(pProj->m_Direction) - 1.f) < 0.02) // workaround to skip grenades on ball mod && (pProj->GetOwner() < 0 || !GameClient()->m_aClients[pProj->GetOwner()].m_IsPredictedLocal) // skip locally predicted projectiles && !Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_ID)) { diff --git a/src/game/client/prediction/entities/character.cpp b/src/game/client/prediction/entities/character.cpp index f5091666f..c56ad8c74 100644 --- a/src/game/client/prediction/entities/character.cpp +++ b/src/game/client/prediction/entities/character.cpp @@ -25,6 +25,7 @@ void CCharacter::SetWeapon(int W) void CCharacter::SetSolo(bool Solo) { + m_Core.m_Solo = Solo; TeamsCore()->SetSolo(GetCID(), Solo); } @@ -83,7 +84,7 @@ void CCharacter::HandleJetpack() float Strength = GetTuning(m_TuneZone)->m_JetpackStrength; if(!m_TuneZone) Strength = m_LastJetpackStrength; - TakeDamage(Direction * -1.0f * (Strength / 100.0f / 6.11f), g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage, GetCID(), m_Core.m_ActiveWeapon); + TakeDamage(Direction * -1.0f * (Strength / 100.0f / 6.11f), 0, GetCID(), m_Core.m_ActiveWeapon); } } } @@ -190,7 +191,7 @@ void CCharacter::HandleNinja() void CCharacter::DoWeaponSwitch() { // make sure we can switch - if(m_ReloadTimer != 0 || m_QueuedWeapon == -1 || m_aWeapons[WEAPON_NINJA].m_Got) + if(m_ReloadTimer != 0 || m_QueuedWeapon == -1 || m_aWeapons[WEAPON_NINJA].m_Got || !m_aWeapons[m_QueuedWeapon].m_Got) return; // switch Weapon @@ -264,7 +265,9 @@ void CCharacter::FireWeapon() bool FullAuto = false; if(m_Core.m_ActiveWeapon == WEAPON_GRENADE || m_Core.m_ActiveWeapon == WEAPON_SHOTGUN || m_Core.m_ActiveWeapon == WEAPON_LASER) FullAuto = true; - if (m_Jetpack && m_Core.m_ActiveWeapon == WEAPON_GUN) + if(m_Jetpack && m_Core.m_ActiveWeapon == WEAPON_GUN) + FullAuto = true; + if(m_FrozenLastTick) FullAuto = true; // don't fire hammer when player is deep and sv_deepfly is disabled @@ -322,7 +325,7 @@ void CCharacter::FireWeapon() float Strength = GetTuning(m_TuneZone)->m_HammerStrength; vec2 Temp = pTarget->m_Core.m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f; - Temp = pTarget->Core()->LimitVel(Temp); + Temp = ClampVel(pTarget->m_MoveRestrictions, Temp); Temp -= pTarget->m_Core.m_Vel; vec2 Force = vec2(0.f, -1.0f) + Temp; @@ -373,8 +376,7 @@ void CCharacter::FireWeapon() 0,//Freeze 0,//Explosive 0,//Force - -1,//SoundImpact - WEAPON_GUN//Weapon + -1//SoundImpact ); } } break; @@ -402,8 +404,7 @@ void CCharacter::FireWeapon() 0,//Freeze 0,//Explosive 0,//Force - -1,//SoundImpact - WEAPON_SHOTGUN//Weapon + -1//SoundImpact ); } } @@ -430,8 +431,7 @@ void CCharacter::FireWeapon() 0,//Freeze true,//Explosive 0,//Force - SOUND_GRENADE_EXPLODE,//SoundImpact - WEAPON_GRENADE//Weapon + SOUND_GRENADE_EXPLODE//SoundImpact );//SoundImpact } break; @@ -484,18 +484,6 @@ void CCharacter::HandleWeapons() return; } -bool CCharacter::GiveWeapon(int Weapon, int Ammo) -{ - if(m_aWeapons[Weapon].m_Ammo < g_pData->m_Weapons.m_aId[Weapon].m_Maxammo || !m_aWeapons[Weapon].m_Got) - { - m_aWeapons[Weapon].m_Got = true; - if(!m_FreezeTime) - m_aWeapons[Weapon].m_Ammo = minimum(g_pData->m_Weapons.m_aId[Weapon].m_Maxammo, Ammo); - return true; - } - return false; -} - void CCharacter::GiveNinja() { m_Ninja.m_ActivationTick = GameWorld()->GameTick(); @@ -510,13 +498,14 @@ void CCharacter::GiveNinja() void CCharacter::OnPredictedInput(CNetObj_PlayerInput *pNewInput) { // copy new input - mem_copy(&m_SavedInput, pNewInput, sizeof(m_SavedInput)); mem_copy(&m_Input, pNewInput, sizeof(m_Input)); //m_NumInputs++; // it is not allowed to aim in the center if(m_Input.m_TargetX == 0 && m_Input.m_TargetY == 0) m_Input.m_TargetY = -1; + + mem_copy(&m_SavedInput, &m_Input, sizeof(m_SavedInput)); } void CCharacter::OnDirectInput(CNetObj_PlayerInput *pNewInput) @@ -567,7 +556,8 @@ void CCharacter::TickDefered() bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon) { - m_Core.ApplyForce(Force); + vec2 Temp = m_Core.m_Vel + Force; + m_Core.m_Vel = ClampVel(m_MoveRestrictions, Temp); return true; } @@ -646,7 +636,7 @@ void CCharacter::HandleSkippableTiles(int Index) } else TempVel += Direction * Force; - m_Core.m_Vel = m_Core.LimitVel(TempVel); + m_Core.m_Vel = ClampVel(m_MoveRestrictions, TempVel); } } } @@ -666,12 +656,12 @@ void CCharacter::HandleTiles(int Index) m_MoveRestrictions = Collision()->GetMoveRestrictions(IsSwitchActiveCb, this, m_Pos); // stopper - m_Core.m_Vel = ClampVel(m_MoveRestrictions, m_Core.m_Vel); - if(m_MoveRestrictions&CANTMOVE_DOWN) + if(m_Core.m_Vel.y > 0 && (m_MoveRestrictions&CANTMOVE_DOWN)) { m_Core.m_Jumped = 0; m_Core.m_JumpedTotal = 0; } + m_Core.m_Vel = ClampVel(m_MoveRestrictions, m_Core.m_Vel); if(!GameWorld()->m_WorldConfig.m_PredictTiles) return; @@ -706,10 +696,12 @@ void CCharacter::HandleTiles(int Index) if(((m_TileIndex == TILE_EHOOK_START) || (m_TileFIndex == TILE_EHOOK_START)) && !m_EndlessHook) { m_EndlessHook = true; + m_Core.m_EndlessHook = true; } else if(((m_TileIndex == TILE_EHOOK_END) || (m_TileFIndex == TILE_EHOOK_END)) && m_EndlessHook) { m_EndlessHook = false; + m_Core.m_EndlessHook = false; } // collide with others @@ -736,10 +728,12 @@ void CCharacter::HandleTiles(int Index) if(((m_TileIndex == TILE_SUPER_START) || (m_TileFIndex == TILE_SUPER_START)) && !m_SuperJump) { m_SuperJump = true; + m_Core.m_EndlessJump = true; } else if(((m_TileIndex == TILE_SUPER_END) || (m_TileFIndex == TILE_SUPER_END)) && m_SuperJump) { m_SuperJump = false; + m_Core.m_EndlessJump = false; } // walljump @@ -757,10 +751,12 @@ void CCharacter::HandleTiles(int Index) if(((m_TileIndex == TILE_JETPACK_START) || (m_TileFIndex == TILE_JETPACK_START)) && !m_Jetpack) { m_Jetpack = true; + m_Core.m_Jetpack = true; } else if(((m_TileIndex == TILE_JETPACK_END) || (m_TileFIndex == TILE_JETPACK_END)) && m_Jetpack) { m_Jetpack = false; + m_Core.m_Jetpack = false; } // solo part @@ -872,6 +868,8 @@ void CCharacter::DDRacePostCoreTick() if (m_EndlessHook) m_Core.m_HookTick = 0; + m_FrozenLastTick = false; + if (m_DeepFreeze && !m_Super) Freeze(); @@ -934,20 +932,43 @@ bool CCharacter::UnFreeze() m_Core.m_ActiveWeapon = WEAPON_GUN; m_FreezeTime = 0; m_FreezeTick = 0; - if (m_Core.m_ActiveWeapon==WEAPON_HAMMER) m_ReloadTimer = 0; + m_FrozenLastTick = true; return true; } return false; } +void CCharacter::GiveWeapon(int Weapon, bool Remove) +{ + if(Weapon == WEAPON_NINJA) + { + if(Remove) + RemoveNinja(); + else + GiveNinja(); + return; + } + + if(Remove) + { + if(GetActiveWeapon() == Weapon) + SetActiveWeapon(WEAPON_GUN); + } + else + { + if(!m_FreezeTime) + m_aWeapons[Weapon].m_Ammo = -1; + } + + m_aWeapons[Weapon].m_Got = !Remove; +} + void CCharacter::GiveAllWeapons() { for(int i=WEAPON_GUN;i= 0 && m_Subtype < NUM_WEAPONS && (!pChr->GetWeaponGot(m_Subtype) || (pChr->GetWeaponAmmo(m_Subtype) != -1 && !pChr->m_FreezeTime))) - pChr->GiveWeapon(m_Subtype, -1); + pChr->GiveWeapon(m_Subtype); break; case POWERUP_NINJA: diff --git a/src/game/client/prediction/entities/projectile.cpp b/src/game/client/prediction/entities/projectile.cpp index b512431e6..3028ffc00 100644 --- a/src/game/client/prediction/entities/projectile.cpp +++ b/src/game/client/prediction/entities/projectile.cpp @@ -17,7 +17,6 @@ CProjectile::CProjectile bool Explosive, float Force, int SoundImpact, - int Weapon, int Layer, int Number ) @@ -30,7 +29,6 @@ CProjectile::CProjectile m_Owner = Owner; m_Force = Force; m_SoundImpact = SoundImpact; - m_Weapon = Weapon; m_StartTick = GameWorld()->GameTick(); m_Explosive = Explosive; @@ -84,7 +82,7 @@ void CProjectile::Tick() CCharacter *pTargetChr = GameWorld()->IntersectCharacter(PrevPos, ColPos, m_Freeze ? 1.0f : 6.0f, ColPos, pOwnerChar, m_Owner); - if(GameWorld()->m_WorldConfig.m_IsSolo && !(m_Weapon == WEAPON_SHOTGUN && GameWorld()->m_WorldConfig.m_IsDDRace)) + if(GameWorld()->m_WorldConfig.m_IsSolo && !(m_Type == WEAPON_SHOTGUN && GameWorld()->m_WorldConfig.m_IsDDRace)) pTargetChr = 0; if(m_LifeSpan > -1) @@ -106,9 +104,9 @@ void CProjectile::Tick() if( ((pTargetChr && (pOwnerChar ? !(pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_GRENADE) : g_Config.m_SvHit || m_Owner == -1 || pTargetChr == pOwnerChar)) || Collide || GameLayerClipped(CurPos)) && !isWeaponCollide) { - if(m_Explosive && (!pTargetChr || (pTargetChr && (!m_Freeze || (m_Weapon == WEAPON_SHOTGUN && Collide))))) + if(m_Explosive && (!pTargetChr || (pTargetChr && (!m_Freeze || (m_Type == WEAPON_SHOTGUN && Collide))))) { - GameWorld()->CreateExplosion(ColPos, m_Owner, m_Weapon, m_Owner == -1, (!pTargetChr ? -1 : pTargetChr->Team()), + GameWorld()->CreateExplosion(ColPos, m_Owner, m_Type, m_Owner == -1, (!pTargetChr ? -1 : pTargetChr->Team()), (m_Owner != -1)? TeamMask : -1LL); } else if(pTargetChr && m_Freeze && ((m_Layer == LAYER_SWITCH && Collision()->m_pSwitchers[m_Number].m_Status[pTargetChr->Team()]) || m_Layer != LAYER_SWITCH)) @@ -127,7 +125,7 @@ void CProjectile::Tick() m_Direction.y = 0; m_Pos += m_Direction; } - else if (m_Weapon == WEAPON_GUN) + else if (m_Type == WEAPON_GUN) { GameWorld()->DestroyEntity(this); } @@ -144,7 +142,7 @@ void CProjectile::Tick() int64_t TeamMask = -1LL; - GameWorld()->CreateExplosion(ColPos, m_Owner, m_Weapon, m_Owner == -1, (!pOwnerChar ? -1 : pOwnerChar->Team()), + GameWorld()->CreateExplosion(ColPos, m_Owner, m_Type, m_Owner == -1, (!pOwnerChar ? -1 : pOwnerChar->Team()), (m_Owner != -1)? TeamMask : -1LL); } GameWorld()->DestroyEntity(this); @@ -170,20 +168,20 @@ CProjectile::CProjectile(CGameWorld *pGameWorld, int ID, CNetObj_Projectile *pPr m_Bouncing = m_Freeze = 0; m_Explosive = (pProj->m_Type == WEAPON_GRENADE) && (fabs(1.0f - length(m_Direction)) < 0.015f); } - m_Type = m_Weapon = pProj->m_Type; + m_Type = m_Type = pProj->m_Type; m_StartTick = pProj->m_StartTick; m_TuneZone = GameWorld()->m_WorldConfig.m_PredictTiles ? Collision()->IsTune(Collision()->GetMapIndex(m_Pos)) : 0; int Lifetime = 20 * GameWorld()->GameTickSpeed(); m_SoundImpact = -1; - if(m_Weapon == WEAPON_GRENADE) + if(m_Type == WEAPON_GRENADE) { Lifetime = GetTuning(m_TuneZone)->m_GrenadeLifetime * GameWorld()->GameTickSpeed(); m_SoundImpact = SOUND_GRENADE_EXPLODE; } - else if(m_Weapon == WEAPON_GUN) + else if(m_Type == WEAPON_GUN) Lifetime = GetTuning(m_TuneZone)->m_GunLifetime * GameWorld()->GameTickSpeed(); - else if(m_Weapon == WEAPON_SHOTGUN && !GameWorld()->m_WorldConfig.m_IsDDRace) + else if(m_Type == WEAPON_SHOTGUN && !GameWorld()->m_WorldConfig.m_IsDDRace) Lifetime = GetTuning(m_TuneZone)->m_ShotgunLifetime * GameWorld()->GameTickSpeed(); m_LifeSpan = Lifetime - (pGameWorld->GameTick() - m_StartTick); m_ID = ID; @@ -232,7 +230,7 @@ void CProjectile::FillExtraInfo(CNetObj_Projectile *pProj) bool CProjectile::Match(CProjectile *pProj) { - if(pProj->m_Weapon != m_Weapon) + if(pProj->m_Type != m_Type) return false; if(pProj->m_StartTick != m_StartTick) return false; diff --git a/src/game/client/prediction/entities/projectile.h b/src/game/client/prediction/entities/projectile.h index 77a29ead9..9c3e0bc27 100644 --- a/src/game/client/prediction/entities/projectile.h +++ b/src/game/client/prediction/entities/projectile.h @@ -24,7 +24,6 @@ public: bool Explosive, float Force, int SoundImpact, - int Weapon, int Layer = 0, int Number = 0 ); @@ -50,7 +49,6 @@ private: int m_Owner; int m_Type; int m_SoundImpact; - int m_Weapon; float m_Force; int m_StartTick; bool m_Explosive; From 47cafe6d6bedb13395e921335d15bc1115492595 Mon Sep 17 00:00:00 2001 From: trml Date: Sun, 26 Apr 2020 01:20:57 +0200 Subject: [PATCH 2/4] Remove unused code --- src/game/client/gameclient.h | 40 ------------------------------------ src/game/gamecore.cpp | 10 --------- src/game/gamecore.h | 5 ----- 3 files changed, 55 deletions(-) diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 0720bf582..d90dd5edf 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -20,46 +20,6 @@ #include #include -class CGameClient; - -class CWeaponData -{ -public: - int m_Tick; - vec2 m_Pos; - vec2 m_Direction; - vec2 StartPos() { return m_Pos + m_Direction * 28.0f * 0.75f; } -}; - -class CLocalProjectile -{ -public: - int m_Active; - CGameClient *m_pGameClient; - CWorldCore *m_pWorld; - CCollision *m_pCollision; - - vec2 m_Direction; - vec2 m_Pos; - int m_StartTick; - int m_Type; - - int m_Owner; - int m_Weapon; - bool m_Explosive; - int m_Bouncing; - bool m_Freeze; - bool m_ExtraInfo; - - vec2 GetPos(float Time); - void CreateExplosion(vec2 Pos, int LocalClientID); - void Tick(int CurrentTick, int GameTickSpeed, int LocalClientID); - void Init(CGameClient *pGameClient, CWorldCore *pWorld, CCollision *pCollision, const CNetObj_Projectile *pProj); - void Init(CGameClient *pGameClient, CWorldCore *pWorld, CCollision *pCollision, vec2 Vel, vec2 Pos, int StartTick, int Type, int Owner, int Weapon, bool Explosive, int Bouncing, bool Freeze, bool ExtraInfo); - bool GameLayerClipped(vec2 CheckPos); - void Deactivate() { m_Active = 0; } -}; - class CGameInfo { public: diff --git a/src/game/gamecore.cpp b/src/game/gamecore.cpp index b3ffd5fe1..3142a704f 100644 --- a/src/game/gamecore.cpp +++ b/src/game/gamecore.cpp @@ -592,13 +592,3 @@ bool CCharacterCore::IsSwitchActiveCb(int Number, void *pUser) return pThis->Collision()->m_pSwitchers[Number].m_Status[pThis->m_pTeams->Team(pThis->m_Id)]; return false; } - -vec2 CCharacterCore::LimitVel(vec2 Vel) -{ - return ClampVel(m_MoveRestrictions, Vel); -} - -void CCharacterCore::ApplyForce(vec2 Force) -{ - m_Vel = LimitVel(m_Vel + Force); -} diff --git a/src/game/gamecore.h b/src/game/gamecore.h index 0289a5872..2aade3ba2 100644 --- a/src/game/gamecore.h +++ b/src/game/gamecore.h @@ -257,11 +257,6 @@ public: int m_FreezeEnd; bool m_DeepFrozen; - // Caps the given velocity according to the current set of stoppers - // that the character is affected by. - vec2 LimitVel(vec2 Vel); - void ApplyForce(vec2 Force); - private: CTeamsCore *m_pTeams; From cda99668c74dc765df713faadeba0f0496ec6c97 Mon Sep 17 00:00:00 2001 From: trml Date: Fri, 1 May 2020 16:29:06 +0200 Subject: [PATCH 3/4] Fix antiping smoketrails --- src/game/client/components/items.cpp | 5 ++--- src/game/client/components/items.h | 2 +- src/game/client/prediction/gameworld.cpp | 7 +++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp index cd6b32182..729d64d2d 100644 --- a/src/game/client/components/items.cpp +++ b/src/game/client/components/items.cpp @@ -329,7 +329,7 @@ void CItems::OnRender() && (pProj->GetOwner() < 0 || !GameClient()->m_aClients[pProj->GetOwner()].m_IsPredictedLocal) // skip locally predicted projectiles && !Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_ID)) { - ReconstructSmokeTrail((const CNetObj_Projectile *)pData, Item.m_ID, pProj->m_DestroyTick, pProj->m_LifeSpan); + ReconstructSmokeTrail((const CNetObj_Projectile *)pData, Item.m_ID, pProj->m_DestroyTick); } pProj->m_LastRenderTick = Client()->GameTick(g_Config.m_ClDummy); continue; @@ -442,7 +442,7 @@ void CItems::AddExtraProjectile(CNetObj_Projectile *pProj) } } -void CItems::ReconstructSmokeTrail(const CNetObj_Projectile *pCurrent, int ItemID, int DestroyTick, int LifeSpan) +void CItems::ReconstructSmokeTrail(const CNetObj_Projectile *pCurrent, int ItemID, int DestroyTick) { bool LocalPlayerInGame = false; @@ -495,7 +495,6 @@ void CItems::ReconstructSmokeTrail(const CNetObj_Projectile *pCurrent, int ItemI float T = Pt; if(DestroyTick >= 0) T = minimum(Pt, ((float)(DestroyTick - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy))/(float)SERVER_TICK_SPEED); - T = minimum(T, LifeSpan/(float)SERVER_TICK_SPEED); float MinTrailSpan = 0.4f * ((pCurrent->m_Type == WEAPON_GRENADE) ? 0.5f : 0.25f); float Step = maximum(Client()->FrameTimeAvg(), (pCurrent->m_Type == WEAPON_GRENADE) ? 0.02f : 0.01f); diff --git a/src/game/client/components/items.h b/src/game/client/components/items.h index b45478f73..c05aec8f4 100644 --- a/src/game/client/components/items.h +++ b/src/game/client/components/items.h @@ -27,7 +27,7 @@ public: void AddExtraProjectile(CNetObj_Projectile *pProj); - void ReconstructSmokeTrail(const CNetObj_Projectile *pCurrent, int ItemID, int DestroyTick, int LifeSpan); + void ReconstructSmokeTrail(const CNetObj_Projectile *pCurrent, int ItemID, int DestroyTick); }; #endif diff --git a/src/game/client/prediction/gameworld.cpp b/src/game/client/prediction/gameworld.cpp index 077a50a66..d85023e09 100644 --- a/src/game/client/prediction/gameworld.cpp +++ b/src/game/client/prediction/gameworld.cpp @@ -156,11 +156,10 @@ void CGameWorld::RemoveEntity(CEntity *pEnt) m_Core.m_apCharacters[ID] = 0; } } - pEnt->m_pParent = 0; - if(m_IsValidCopy && m_pParent && m_pParent->m_pChild == this) - if(pEnt->m_pParent) - pEnt->m_pParent->m_DestroyTick = GameTick(); + if(m_IsValidCopy && m_pParent && m_pParent->m_pChild == this && pEnt->m_pParent) + pEnt->m_pParent->m_DestroyTick = GameTick(); + pEnt->m_pParent = 0; } void CGameWorld::RemoveEntities() From f6c44468de0bed4e6d78d8b616246b78e5215d32 Mon Sep 17 00:00:00 2001 From: trml Date: Sun, 3 May 2020 00:00:27 +0200 Subject: [PATCH 4/4] Another update, fix typo --- src/game/client/prediction/entities/character.cpp | 14 +++----------- src/game/client/prediction/entities/pickup.cpp | 13 +++++-------- src/game/client/prediction/entities/projectile.cpp | 2 +- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/game/client/prediction/entities/character.cpp b/src/game/client/prediction/entities/character.cpp index c56ad8c74..fe8928779 100644 --- a/src/game/client/prediction/entities/character.cpp +++ b/src/game/client/prediction/entities/character.cpp @@ -70,7 +70,7 @@ void CCharacter::HandleJetpack() return; // check for ammo - if(!m_aWeapons[m_Core.m_ActiveWeapon].m_Ammo) + if(!m_aWeapons[m_Core.m_ActiveWeapon].m_Ammo || m_FreezeTime) { return; } @@ -286,7 +286,7 @@ void CCharacter::FireWeapon() return; // check for ammo - if(!m_aWeapons[m_Core.m_ActiveWeapon].m_Ammo) + if(!m_aWeapons[m_Core.m_ActiveWeapon].m_Ammo || m_FreezeTime) { return; } @@ -905,11 +905,6 @@ bool CCharacter::Freeze(int Seconds) return false; if (m_FreezeTick < GameWorld()->GameTick() - GameWorld()->GameTickSpeed() || Seconds == -1) { - for(int i = 0; i < NUM_WEAPONS; i++) - if(m_aWeapons[i].m_Got) - { - m_aWeapons[i].m_Ammo = 0; - } m_FreezeTime = Seconds == -1 ? Seconds : Seconds * GameWorld()->GameTickSpeed(); m_FreezeTick = GameWorld()->GameTick(); return true; @@ -926,8 +921,6 @@ bool CCharacter::UnFreeze() { if (m_FreezeTime > 0) { - for(int i=0;iGetWeaponGot(i)) { - if(!(pChr->m_FreezeTime && i == WEAPON_NINJA)) - { - pChr->SetWeaponGot(i, false); - pChr->SetWeaponAmmo(i, 0); - sound = true; - } + pChr->SetWeaponGot(i, false); + pChr->SetWeaponAmmo(i, 0); + sound = true; } } pChr->SetNinjaActivationDir(vec2(0,0)); @@ -47,12 +44,12 @@ void CPickup::Tick() pChr->SetNinjaCurrentMoveTime(0); if (sound) pChr->SetLastWeapon(WEAPON_GUN); - if(!pChr->m_FreezeTime && pChr->GetActiveWeapon() >= WEAPON_SHOTGUN) + if(pChr->GetActiveWeapon() >= WEAPON_SHOTGUN) pChr->SetActiveWeapon(WEAPON_HAMMER); break; case POWERUP_WEAPON: - if(m_Subtype >= 0 && m_Subtype < NUM_WEAPONS && (!pChr->GetWeaponGot(m_Subtype) || (pChr->GetWeaponAmmo(m_Subtype) != -1 && !pChr->m_FreezeTime))) + if(m_Subtype >= 0 && m_Subtype < NUM_WEAPONS && (!pChr->GetWeaponGot(m_Subtype) || pChr->GetWeaponAmmo(m_Subtype) != -1)) pChr->GiveWeapon(m_Subtype); break; diff --git a/src/game/client/prediction/entities/projectile.cpp b/src/game/client/prediction/entities/projectile.cpp index 3028ffc00..f2300a154 100644 --- a/src/game/client/prediction/entities/projectile.cpp +++ b/src/game/client/prediction/entities/projectile.cpp @@ -168,7 +168,7 @@ CProjectile::CProjectile(CGameWorld *pGameWorld, int ID, CNetObj_Projectile *pPr m_Bouncing = m_Freeze = 0; m_Explosive = (pProj->m_Type == WEAPON_GRENADE) && (fabs(1.0f - length(m_Direction)) < 0.015f); } - m_Type = m_Type = pProj->m_Type; + m_Type = pProj->m_Type; m_StartTick = pProj->m_StartTick; m_TuneZone = GameWorld()->m_WorldConfig.m_PredictTiles ? Collision()->IsTune(Collision()->GetMapIndex(m_Pos)) : 0;