mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Merge #2161
2161: Small prediction fixes/update r=def- a=trml I looked through the latest changes in the server code, and made some updates to the prediction with it. This includes the hammer-out-of-freeze server fix and a small fix for stopper prediction. Also cleaned up some code, and fixed predicted smoke-trails slightly so they don't go through walls in certain cases. Co-authored-by: trml <trml@users.noreply.github.com>
This commit is contained in:
commit
2649fb5234
|
@ -285,7 +285,7 @@ void CItems::OnRender()
|
||||||
for(auto *pProj = (CProjectile*) GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile*) pProj->NextEntity())
|
for(auto *pProj = (CProjectile*) GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile*) pProj->NextEntity())
|
||||||
{
|
{
|
||||||
CNetObj_Projectile Data;
|
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);
|
pProj->FillExtraInfo(&Data);
|
||||||
else
|
else
|
||||||
pProj->FillInfo(&Data);
|
pProj->FillInfo(&Data);
|
||||||
|
@ -324,12 +324,12 @@ void CItems::OnRender()
|
||||||
if(auto *pProj = (CProjectile*) GameClient()->m_GameWorld.FindMatch(Item.m_ID, Item.m_Type, pData))
|
if(auto *pProj = (CProjectile*) GameClient()->m_GameWorld.FindMatch(Item.m_ID, Item.m_Type, pData))
|
||||||
{
|
{
|
||||||
if(pProj->m_LastRenderTick <= 0
|
if(pProj->m_LastRenderTick <= 0
|
||||||
&& (pProj->m_Weapon != WEAPON_SHOTGUN || (!pProj->m_Freeze && !pProj->m_Explosive)) // skip ddrace shotgun bullets
|
&& (pProj->m_Type != 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 || 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
|
&& (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))
|
&& !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);
|
pProj->m_LastRenderTick = Client()->GameTick(g_Config.m_ClDummy);
|
||||||
continue;
|
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;
|
bool LocalPlayerInGame = false;
|
||||||
|
|
||||||
|
@ -495,7 +495,6 @@ void CItems::ReconstructSmokeTrail(const CNetObj_Projectile *pCurrent, int ItemI
|
||||||
float T = Pt;
|
float T = Pt;
|
||||||
if(DestroyTick >= 0)
|
if(DestroyTick >= 0)
|
||||||
T = minimum(Pt, ((float)(DestroyTick - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy))/(float)SERVER_TICK_SPEED);
|
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 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);
|
float Step = maximum(Client()->FrameTimeAvg(), (pCurrent->m_Type == WEAPON_GRENADE) ? 0.02f : 0.01f);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
|
|
||||||
void AddExtraProjectile(CNetObj_Projectile *pProj);
|
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
|
#endif
|
||||||
|
|
|
@ -20,46 +20,6 @@
|
||||||
#include <game/client/prediction/entities/laser.h>
|
#include <game/client/prediction/entities/laser.h>
|
||||||
#include <game/client/prediction/entities/pickup.h>
|
#include <game/client/prediction/entities/pickup.h>
|
||||||
|
|
||||||
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
|
class CGameInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -25,6 +25,7 @@ void CCharacter::SetWeapon(int W)
|
||||||
|
|
||||||
void CCharacter::SetSolo(bool Solo)
|
void CCharacter::SetSolo(bool Solo)
|
||||||
{
|
{
|
||||||
|
m_Core.m_Solo = Solo;
|
||||||
TeamsCore()->SetSolo(GetCID(), Solo);
|
TeamsCore()->SetSolo(GetCID(), Solo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ void CCharacter::HandleJetpack()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// check for ammo
|
// check for ammo
|
||||||
if(!m_aWeapons[m_Core.m_ActiveWeapon].m_Ammo)
|
if(!m_aWeapons[m_Core.m_ActiveWeapon].m_Ammo || m_FreezeTime)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -83,7 +84,7 @@ void CCharacter::HandleJetpack()
|
||||||
float Strength = GetTuning(m_TuneZone)->m_JetpackStrength;
|
float Strength = GetTuning(m_TuneZone)->m_JetpackStrength;
|
||||||
if(!m_TuneZone)
|
if(!m_TuneZone)
|
||||||
Strength = m_LastJetpackStrength;
|
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()
|
void CCharacter::DoWeaponSwitch()
|
||||||
{
|
{
|
||||||
// make sure we can switch
|
// 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;
|
return;
|
||||||
|
|
||||||
// switch Weapon
|
// switch Weapon
|
||||||
|
@ -264,7 +265,9 @@ void CCharacter::FireWeapon()
|
||||||
bool FullAuto = false;
|
bool FullAuto = false;
|
||||||
if(m_Core.m_ActiveWeapon == WEAPON_GRENADE || m_Core.m_ActiveWeapon == WEAPON_SHOTGUN || m_Core.m_ActiveWeapon == WEAPON_LASER)
|
if(m_Core.m_ActiveWeapon == WEAPON_GRENADE || m_Core.m_ActiveWeapon == WEAPON_SHOTGUN || m_Core.m_ActiveWeapon == WEAPON_LASER)
|
||||||
FullAuto = true;
|
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;
|
FullAuto = true;
|
||||||
|
|
||||||
// don't fire hammer when player is deep and sv_deepfly is disabled
|
// don't fire hammer when player is deep and sv_deepfly is disabled
|
||||||
|
@ -283,7 +286,7 @@ void CCharacter::FireWeapon()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// check for ammo
|
// check for ammo
|
||||||
if(!m_aWeapons[m_Core.m_ActiveWeapon].m_Ammo)
|
if(!m_aWeapons[m_Core.m_ActiveWeapon].m_Ammo || m_FreezeTime)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +325,7 @@ void CCharacter::FireWeapon()
|
||||||
float Strength = GetTuning(m_TuneZone)->m_HammerStrength;
|
float Strength = GetTuning(m_TuneZone)->m_HammerStrength;
|
||||||
|
|
||||||
vec2 Temp = pTarget->m_Core.m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f;
|
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;
|
Temp -= pTarget->m_Core.m_Vel;
|
||||||
|
|
||||||
vec2 Force = vec2(0.f, -1.0f) + Temp;
|
vec2 Force = vec2(0.f, -1.0f) + Temp;
|
||||||
|
@ -373,8 +376,7 @@ void CCharacter::FireWeapon()
|
||||||
0,//Freeze
|
0,//Freeze
|
||||||
0,//Explosive
|
0,//Explosive
|
||||||
0,//Force
|
0,//Force
|
||||||
-1,//SoundImpact
|
-1//SoundImpact
|
||||||
WEAPON_GUN//Weapon
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -402,8 +404,7 @@ void CCharacter::FireWeapon()
|
||||||
0,//Freeze
|
0,//Freeze
|
||||||
0,//Explosive
|
0,//Explosive
|
||||||
0,//Force
|
0,//Force
|
||||||
-1,//SoundImpact
|
-1//SoundImpact
|
||||||
WEAPON_SHOTGUN//Weapon
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,8 +431,7 @@ void CCharacter::FireWeapon()
|
||||||
0,//Freeze
|
0,//Freeze
|
||||||
true,//Explosive
|
true,//Explosive
|
||||||
0,//Force
|
0,//Force
|
||||||
SOUND_GRENADE_EXPLODE,//SoundImpact
|
SOUND_GRENADE_EXPLODE//SoundImpact
|
||||||
WEAPON_GRENADE//Weapon
|
|
||||||
);//SoundImpact
|
);//SoundImpact
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -484,18 +484,6 @@ void CCharacter::HandleWeapons()
|
||||||
return;
|
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()
|
void CCharacter::GiveNinja()
|
||||||
{
|
{
|
||||||
m_Ninja.m_ActivationTick = GameWorld()->GameTick();
|
m_Ninja.m_ActivationTick = GameWorld()->GameTick();
|
||||||
|
@ -510,13 +498,14 @@ void CCharacter::GiveNinja()
|
||||||
void CCharacter::OnPredictedInput(CNetObj_PlayerInput *pNewInput)
|
void CCharacter::OnPredictedInput(CNetObj_PlayerInput *pNewInput)
|
||||||
{
|
{
|
||||||
// copy new input
|
// copy new input
|
||||||
mem_copy(&m_SavedInput, pNewInput, sizeof(m_SavedInput));
|
|
||||||
mem_copy(&m_Input, pNewInput, sizeof(m_Input));
|
mem_copy(&m_Input, pNewInput, sizeof(m_Input));
|
||||||
//m_NumInputs++;
|
//m_NumInputs++;
|
||||||
|
|
||||||
// it is not allowed to aim in the center
|
// it is not allowed to aim in the center
|
||||||
if(m_Input.m_TargetX == 0 && m_Input.m_TargetY == 0)
|
if(m_Input.m_TargetX == 0 && m_Input.m_TargetY == 0)
|
||||||
m_Input.m_TargetY = -1;
|
m_Input.m_TargetY = -1;
|
||||||
|
|
||||||
|
mem_copy(&m_SavedInput, &m_Input, sizeof(m_SavedInput));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCharacter::OnDirectInput(CNetObj_PlayerInput *pNewInput)
|
void CCharacter::OnDirectInput(CNetObj_PlayerInput *pNewInput)
|
||||||
|
@ -567,7 +556,8 @@ void CCharacter::TickDefered()
|
||||||
|
|
||||||
bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,7 +636,7 @@ void CCharacter::HandleSkippableTiles(int Index)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TempVel += Direction * Force;
|
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);
|
m_MoveRestrictions = Collision()->GetMoveRestrictions(IsSwitchActiveCb, this, m_Pos);
|
||||||
|
|
||||||
// stopper
|
// stopper
|
||||||
m_Core.m_Vel = ClampVel(m_MoveRestrictions, m_Core.m_Vel);
|
if(m_Core.m_Vel.y > 0 && (m_MoveRestrictions&CANTMOVE_DOWN))
|
||||||
if(m_MoveRestrictions&CANTMOVE_DOWN)
|
|
||||||
{
|
{
|
||||||
m_Core.m_Jumped = 0;
|
m_Core.m_Jumped = 0;
|
||||||
m_Core.m_JumpedTotal = 0;
|
m_Core.m_JumpedTotal = 0;
|
||||||
}
|
}
|
||||||
|
m_Core.m_Vel = ClampVel(m_MoveRestrictions, m_Core.m_Vel);
|
||||||
|
|
||||||
if(!GameWorld()->m_WorldConfig.m_PredictTiles)
|
if(!GameWorld()->m_WorldConfig.m_PredictTiles)
|
||||||
return;
|
return;
|
||||||
|
@ -706,10 +696,12 @@ void CCharacter::HandleTiles(int Index)
|
||||||
if(((m_TileIndex == TILE_EHOOK_START) || (m_TileFIndex == TILE_EHOOK_START)) && !m_EndlessHook)
|
if(((m_TileIndex == TILE_EHOOK_START) || (m_TileFIndex == TILE_EHOOK_START)) && !m_EndlessHook)
|
||||||
{
|
{
|
||||||
m_EndlessHook = true;
|
m_EndlessHook = true;
|
||||||
|
m_Core.m_EndlessHook = true;
|
||||||
}
|
}
|
||||||
else if(((m_TileIndex == TILE_EHOOK_END) || (m_TileFIndex == TILE_EHOOK_END)) && m_EndlessHook)
|
else if(((m_TileIndex == TILE_EHOOK_END) || (m_TileFIndex == TILE_EHOOK_END)) && m_EndlessHook)
|
||||||
{
|
{
|
||||||
m_EndlessHook = false;
|
m_EndlessHook = false;
|
||||||
|
m_Core.m_EndlessHook = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// collide with others
|
// 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)
|
if(((m_TileIndex == TILE_SUPER_START) || (m_TileFIndex == TILE_SUPER_START)) && !m_SuperJump)
|
||||||
{
|
{
|
||||||
m_SuperJump = true;
|
m_SuperJump = true;
|
||||||
|
m_Core.m_EndlessJump = true;
|
||||||
}
|
}
|
||||||
else if(((m_TileIndex == TILE_SUPER_END) || (m_TileFIndex == TILE_SUPER_END)) && m_SuperJump)
|
else if(((m_TileIndex == TILE_SUPER_END) || (m_TileFIndex == TILE_SUPER_END)) && m_SuperJump)
|
||||||
{
|
{
|
||||||
m_SuperJump = false;
|
m_SuperJump = false;
|
||||||
|
m_Core.m_EndlessJump = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// walljump
|
// walljump
|
||||||
|
@ -757,10 +751,12 @@ void CCharacter::HandleTiles(int Index)
|
||||||
if(((m_TileIndex == TILE_JETPACK_START) || (m_TileFIndex == TILE_JETPACK_START)) && !m_Jetpack)
|
if(((m_TileIndex == TILE_JETPACK_START) || (m_TileFIndex == TILE_JETPACK_START)) && !m_Jetpack)
|
||||||
{
|
{
|
||||||
m_Jetpack = true;
|
m_Jetpack = true;
|
||||||
|
m_Core.m_Jetpack = true;
|
||||||
}
|
}
|
||||||
else if(((m_TileIndex == TILE_JETPACK_END) || (m_TileFIndex == TILE_JETPACK_END)) && m_Jetpack)
|
else if(((m_TileIndex == TILE_JETPACK_END) || (m_TileFIndex == TILE_JETPACK_END)) && m_Jetpack)
|
||||||
{
|
{
|
||||||
m_Jetpack = false;
|
m_Jetpack = false;
|
||||||
|
m_Core.m_Jetpack = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// solo part
|
// solo part
|
||||||
|
@ -872,6 +868,8 @@ void CCharacter::DDRacePostCoreTick()
|
||||||
if (m_EndlessHook)
|
if (m_EndlessHook)
|
||||||
m_Core.m_HookTick = 0;
|
m_Core.m_HookTick = 0;
|
||||||
|
|
||||||
|
m_FrozenLastTick = false;
|
||||||
|
|
||||||
if (m_DeepFreeze && !m_Super)
|
if (m_DeepFreeze && !m_Super)
|
||||||
Freeze();
|
Freeze();
|
||||||
|
|
||||||
|
@ -907,11 +905,6 @@ bool CCharacter::Freeze(int Seconds)
|
||||||
return false;
|
return false;
|
||||||
if (m_FreezeTick < GameWorld()->GameTick() - GameWorld()->GameTickSpeed() || Seconds == -1)
|
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_FreezeTime = Seconds == -1 ? Seconds : Seconds * GameWorld()->GameTickSpeed();
|
||||||
m_FreezeTick = GameWorld()->GameTick();
|
m_FreezeTick = GameWorld()->GameTick();
|
||||||
return true;
|
return true;
|
||||||
|
@ -928,26 +921,46 @@ bool CCharacter::UnFreeze()
|
||||||
{
|
{
|
||||||
if (m_FreezeTime > 0)
|
if (m_FreezeTime > 0)
|
||||||
{
|
{
|
||||||
for(int i=0;i<NUM_WEAPONS;i++)
|
|
||||||
m_aWeapons[i].m_Ammo = -1;
|
|
||||||
if(!m_aWeapons[m_Core.m_ActiveWeapon].m_Got)
|
if(!m_aWeapons[m_Core.m_ActiveWeapon].m_Got)
|
||||||
m_Core.m_ActiveWeapon = WEAPON_GUN;
|
m_Core.m_ActiveWeapon = WEAPON_GUN;
|
||||||
m_FreezeTime = 0;
|
m_FreezeTime = 0;
|
||||||
m_FreezeTick = 0;
|
m_FreezeTick = 0;
|
||||||
if (m_Core.m_ActiveWeapon==WEAPON_HAMMER) m_ReloadTimer = 0;
|
m_FrozenLastTick = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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
|
||||||
|
{
|
||||||
|
m_aWeapons[Weapon].m_Ammo = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_aWeapons[Weapon].m_Got = !Remove;
|
||||||
|
}
|
||||||
|
|
||||||
void CCharacter::GiveAllWeapons()
|
void CCharacter::GiveAllWeapons()
|
||||||
{
|
{
|
||||||
for(int i=WEAPON_GUN;i<NUM_WEAPONS-1;i++)
|
for(int i=WEAPON_GUN;i<NUM_WEAPONS-1;i++)
|
||||||
{
|
{
|
||||||
m_aWeapons[i].m_Got = true;
|
GiveWeapon(i);
|
||||||
if(!m_FreezeTime) m_aWeapons[i].m_Ammo = -1;
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CTeamsCore* CCharacter::TeamsCore()
|
CTeamsCore* CCharacter::TeamsCore()
|
||||||
|
@ -1001,6 +1014,7 @@ void CCharacter::ResetPrediction()
|
||||||
m_FreezeTime = 0;
|
m_FreezeTime = 0;
|
||||||
m_FreezeTick = 0;
|
m_FreezeTick = 0;
|
||||||
m_DeepFreeze = 0;
|
m_DeepFreeze = 0;
|
||||||
|
m_FrozenLastTick = false;
|
||||||
m_Super = false;
|
m_Super = false;
|
||||||
for(int w = 0; w < NUM_WEAPONS; w++)
|
for(int w = 0; w < NUM_WEAPONS; w++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
|
|
||||||
bool TakeDamage(vec2 Force, int Dmg, int From, int Weapon);
|
bool TakeDamage(vec2 Force, int Dmg, int From, int Weapon);
|
||||||
|
|
||||||
bool GiveWeapon(int Weapon, int Ammo);
|
void GiveWeapon(int Weapon, bool Remove = false);
|
||||||
void GiveNinja();
|
void GiveNinja();
|
||||||
void RemoveNinja();
|
void RemoveNinja();
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ public:
|
||||||
bool m_NinjaJetpack;
|
bool m_NinjaJetpack;
|
||||||
int m_FreezeTime;
|
int m_FreezeTime;
|
||||||
int m_FreezeTick;
|
int m_FreezeTick;
|
||||||
|
bool m_FrozenLastTick;
|
||||||
bool m_DeepFreeze;
|
bool m_DeepFreeze;
|
||||||
bool m_EndlessHook;
|
bool m_EndlessHook;
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -34,12 +34,9 @@ void CPickup::Tick()
|
||||||
{
|
{
|
||||||
if(pChr->GetWeaponGot(i))
|
if(pChr->GetWeaponGot(i))
|
||||||
{
|
{
|
||||||
if(!(pChr->m_FreezeTime && i == WEAPON_NINJA))
|
pChr->SetWeaponGot(i, false);
|
||||||
{
|
pChr->SetWeaponAmmo(i, 0);
|
||||||
pChr->SetWeaponGot(i, false);
|
sound = true;
|
||||||
pChr->SetWeaponAmmo(i, 0);
|
|
||||||
sound = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pChr->SetNinjaActivationDir(vec2(0,0));
|
pChr->SetNinjaActivationDir(vec2(0,0));
|
||||||
|
@ -47,13 +44,13 @@ void CPickup::Tick()
|
||||||
pChr->SetNinjaCurrentMoveTime(0);
|
pChr->SetNinjaCurrentMoveTime(0);
|
||||||
if (sound)
|
if (sound)
|
||||||
pChr->SetLastWeapon(WEAPON_GUN);
|
pChr->SetLastWeapon(WEAPON_GUN);
|
||||||
if(!pChr->m_FreezeTime && pChr->GetActiveWeapon() >= WEAPON_SHOTGUN)
|
if(pChr->GetActiveWeapon() >= WEAPON_SHOTGUN)
|
||||||
pChr->SetActiveWeapon(WEAPON_HAMMER);
|
pChr->SetActiveWeapon(WEAPON_HAMMER);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POWERUP_WEAPON:
|
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, -1);
|
pChr->GiveWeapon(m_Subtype);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POWERUP_NINJA:
|
case POWERUP_NINJA:
|
||||||
|
|
|
@ -17,7 +17,6 @@ CProjectile::CProjectile
|
||||||
bool Explosive,
|
bool Explosive,
|
||||||
float Force,
|
float Force,
|
||||||
int SoundImpact,
|
int SoundImpact,
|
||||||
int Weapon,
|
|
||||||
int Layer,
|
int Layer,
|
||||||
int Number
|
int Number
|
||||||
)
|
)
|
||||||
|
@ -30,7 +29,6 @@ CProjectile::CProjectile
|
||||||
m_Owner = Owner;
|
m_Owner = Owner;
|
||||||
m_Force = Force;
|
m_Force = Force;
|
||||||
m_SoundImpact = SoundImpact;
|
m_SoundImpact = SoundImpact;
|
||||||
m_Weapon = Weapon;
|
|
||||||
m_StartTick = GameWorld()->GameTick();
|
m_StartTick = GameWorld()->GameTick();
|
||||||
m_Explosive = Explosive;
|
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);
|
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;
|
pTargetChr = 0;
|
||||||
|
|
||||||
if(m_LifeSpan > -1)
|
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( ((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);
|
(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))
|
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_Direction.y = 0;
|
||||||
m_Pos += m_Direction;
|
m_Pos += m_Direction;
|
||||||
}
|
}
|
||||||
else if (m_Weapon == WEAPON_GUN)
|
else if (m_Type == WEAPON_GUN)
|
||||||
{
|
{
|
||||||
GameWorld()->DestroyEntity(this);
|
GameWorld()->DestroyEntity(this);
|
||||||
}
|
}
|
||||||
|
@ -144,7 +142,7 @@ void CProjectile::Tick()
|
||||||
|
|
||||||
int64_t TeamMask = -1LL;
|
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);
|
(m_Owner != -1)? TeamMask : -1LL);
|
||||||
}
|
}
|
||||||
GameWorld()->DestroyEntity(this);
|
GameWorld()->DestroyEntity(this);
|
||||||
|
@ -170,20 +168,20 @@ CProjectile::CProjectile(CGameWorld *pGameWorld, int ID, CNetObj_Projectile *pPr
|
||||||
m_Bouncing = m_Freeze = 0;
|
m_Bouncing = m_Freeze = 0;
|
||||||
m_Explosive = (pProj->m_Type == WEAPON_GRENADE) && (fabs(1.0f - length(m_Direction)) < 0.015f);
|
m_Explosive = (pProj->m_Type == WEAPON_GRENADE) && (fabs(1.0f - length(m_Direction)) < 0.015f);
|
||||||
}
|
}
|
||||||
m_Type = m_Weapon = pProj->m_Type;
|
m_Type = pProj->m_Type;
|
||||||
m_StartTick = pProj->m_StartTick;
|
m_StartTick = pProj->m_StartTick;
|
||||||
m_TuneZone = GameWorld()->m_WorldConfig.m_PredictTiles ? Collision()->IsTune(Collision()->GetMapIndex(m_Pos)) : 0;
|
m_TuneZone = GameWorld()->m_WorldConfig.m_PredictTiles ? Collision()->IsTune(Collision()->GetMapIndex(m_Pos)) : 0;
|
||||||
|
|
||||||
int Lifetime = 20 * GameWorld()->GameTickSpeed();
|
int Lifetime = 20 * GameWorld()->GameTickSpeed();
|
||||||
m_SoundImpact = -1;
|
m_SoundImpact = -1;
|
||||||
if(m_Weapon == WEAPON_GRENADE)
|
if(m_Type == WEAPON_GRENADE)
|
||||||
{
|
{
|
||||||
Lifetime = GetTuning(m_TuneZone)->m_GrenadeLifetime * GameWorld()->GameTickSpeed();
|
Lifetime = GetTuning(m_TuneZone)->m_GrenadeLifetime * GameWorld()->GameTickSpeed();
|
||||||
m_SoundImpact = SOUND_GRENADE_EXPLODE;
|
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();
|
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();
|
Lifetime = GetTuning(m_TuneZone)->m_ShotgunLifetime * GameWorld()->GameTickSpeed();
|
||||||
m_LifeSpan = Lifetime - (pGameWorld->GameTick() - m_StartTick);
|
m_LifeSpan = Lifetime - (pGameWorld->GameTick() - m_StartTick);
|
||||||
m_ID = ID;
|
m_ID = ID;
|
||||||
|
@ -232,7 +230,7 @@ void CProjectile::FillExtraInfo(CNetObj_Projectile *pProj)
|
||||||
|
|
||||||
bool CProjectile::Match(CProjectile *pProj)
|
bool CProjectile::Match(CProjectile *pProj)
|
||||||
{
|
{
|
||||||
if(pProj->m_Weapon != m_Weapon)
|
if(pProj->m_Type != m_Type)
|
||||||
return false;
|
return false;
|
||||||
if(pProj->m_StartTick != m_StartTick)
|
if(pProj->m_StartTick != m_StartTick)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -24,7 +24,6 @@ public:
|
||||||
bool Explosive,
|
bool Explosive,
|
||||||
float Force,
|
float Force,
|
||||||
int SoundImpact,
|
int SoundImpact,
|
||||||
int Weapon,
|
|
||||||
int Layer = 0,
|
int Layer = 0,
|
||||||
int Number = 0
|
int Number = 0
|
||||||
);
|
);
|
||||||
|
@ -50,7 +49,6 @@ private:
|
||||||
int m_Owner;
|
int m_Owner;
|
||||||
int m_Type;
|
int m_Type;
|
||||||
int m_SoundImpact;
|
int m_SoundImpact;
|
||||||
int m_Weapon;
|
|
||||||
float m_Force;
|
float m_Force;
|
||||||
int m_StartTick;
|
int m_StartTick;
|
||||||
bool m_Explosive;
|
bool m_Explosive;
|
||||||
|
|
|
@ -156,11 +156,10 @@ void CGameWorld::RemoveEntity(CEntity *pEnt)
|
||||||
m_Core.m_apCharacters[ID] = 0;
|
m_Core.m_apCharacters[ID] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pEnt->m_pParent = 0;
|
|
||||||
|
|
||||||
if(m_IsValidCopy && m_pParent && m_pParent->m_pChild == this)
|
if(m_IsValidCopy && m_pParent && m_pParent->m_pChild == this && pEnt->m_pParent)
|
||||||
if(pEnt->m_pParent)
|
pEnt->m_pParent->m_DestroyTick = GameTick();
|
||||||
pEnt->m_pParent->m_DestroyTick = GameTick();
|
pEnt->m_pParent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameWorld::RemoveEntities()
|
void CGameWorld::RemoveEntities()
|
||||||
|
|
|
@ -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 pThis->Collision()->m_pSwitchers[Number].m_Status[pThis->m_pTeams->Team(pThis->m_Id)];
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 CCharacterCore::LimitVel(vec2 Vel)
|
|
||||||
{
|
|
||||||
return ClampVel(m_MoveRestrictions, Vel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCharacterCore::ApplyForce(vec2 Force)
|
|
||||||
{
|
|
||||||
m_Vel = LimitVel(m_Vel + Force);
|
|
||||||
}
|
|
||||||
|
|
|
@ -257,11 +257,6 @@ public:
|
||||||
int m_FreezeEnd;
|
int m_FreezeEnd;
|
||||||
bool m_DeepFrozen;
|
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:
|
private:
|
||||||
|
|
||||||
CTeamsCore *m_pTeams;
|
CTeamsCore *m_pTeams;
|
||||||
|
|
Loading…
Reference in a new issue