mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 22:48:18 +00:00
Character: Incapsulate m_MoveRestrictions and m_Core
Instead of leaking the m_MoveRestrictions to all classes which needs to adjust the Character velocity, add a setter which takes into account those restrictions. The shotgun bug replication requires an access to the Velocity without the restrictions applied (so we have to have this dirty setter). Expose only *const* CCharacterCore to force the setters usage and prevent incorrect write.
This commit is contained in:
parent
432b4319f6
commit
386935f5cf
|
@ -546,6 +546,19 @@ void CCharacter::OnDirectInput(CNetObj_PlayerInput *pNewInput)
|
|||
mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
|
||||
}
|
||||
|
||||
void CCharacter::ReleaseHook()
|
||||
{
|
||||
m_Core.SetHookedPlayer(-1);
|
||||
m_Core.m_HookState = HOOK_RETRACTED;
|
||||
m_Core.m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
||||
}
|
||||
|
||||
void CCharacter::ResetHook()
|
||||
{
|
||||
ReleaseHook();
|
||||
m_Core.m_HookPos = m_Core.m_Pos;
|
||||
}
|
||||
|
||||
void CCharacter::ResetInput()
|
||||
{
|
||||
m_Input.m_Direction = 0;
|
||||
|
@ -1105,6 +1118,33 @@ void CCharacter::GiveAllWeapons()
|
|||
}
|
||||
}
|
||||
|
||||
void CCharacter::ResetVelocity()
|
||||
{
|
||||
m_Core.m_Vel = vec2(0, 0);
|
||||
}
|
||||
|
||||
// The method is needed only to reproduce 'shotgun bug' ddnet#5258
|
||||
// Use SetVelocity() instead.
|
||||
void CCharacter::SetVelocity(const vec2 NewVelocity)
|
||||
{
|
||||
m_Core.m_Vel = ClampVel(m_MoveRestrictions, NewVelocity);
|
||||
}
|
||||
|
||||
void CCharacter::SetRawVelocity(const vec2 NewVelocity)
|
||||
{
|
||||
m_Core.m_Vel = NewVelocity;
|
||||
}
|
||||
|
||||
void CCharacter::AddVelocity(const vec2 Addition)
|
||||
{
|
||||
SetVelocity(m_Core.m_Vel + Addition);
|
||||
}
|
||||
|
||||
void CCharacter::ApplyMoveRestrictions()
|
||||
{
|
||||
m_Core.m_Vel = ClampVel(m_MoveRestrictions, m_Core.m_Vel);
|
||||
}
|
||||
|
||||
CTeamsCore *CCharacter::TeamsCore()
|
||||
{
|
||||
return GameWorld()->Teams();
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
|
||||
void OnPredictedInput(CNetObj_PlayerInput *pNewInput);
|
||||
void OnDirectInput(CNetObj_PlayerInput *pNewInput);
|
||||
void ReleaseHook();
|
||||
void ResetHook();
|
||||
void ResetInput();
|
||||
void FireWeapon();
|
||||
|
||||
|
@ -60,6 +62,12 @@ public:
|
|||
void GiveNinja();
|
||||
void RemoveNinja();
|
||||
|
||||
void ResetVelocity();
|
||||
void SetVelocity(vec2 NewVelocity);
|
||||
void SetRawVelocity(vec2 NewVelocity);
|
||||
void AddVelocity(vec2 Addition);
|
||||
void ApplyMoveRestrictions();
|
||||
|
||||
bool m_IsLocal;
|
||||
|
||||
CTeamsCore *TeamsCore();
|
||||
|
@ -81,7 +89,6 @@ public:
|
|||
int m_TileIndex;
|
||||
int m_TileFIndex;
|
||||
|
||||
int m_MoveRestrictions;
|
||||
bool m_LastRefillJumps;
|
||||
|
||||
// Setters/Getters because i don't want to modify vanilla vars access modifiers
|
||||
|
@ -91,7 +98,7 @@ public:
|
|||
void SetActiveWeapon(int ActiveWeap);
|
||||
CCharacterCore GetCore() { return m_Core; }
|
||||
void SetCore(CCharacterCore Core) { m_Core = Core; }
|
||||
CCharacterCore *Core() { return &m_Core; }
|
||||
const CCharacterCore *Core() const { return &m_Core; }
|
||||
bool GetWeaponGot(int Type) { return m_Core.m_aWeapons[Type].m_Got; }
|
||||
void SetWeaponGot(int Type, bool Value) { m_Core.m_aWeapons[Type].m_Got = Value; }
|
||||
int GetWeaponAmmo(int Type) { return m_Core.m_aWeapons[Type].m_Ammo; }
|
||||
|
@ -145,6 +152,8 @@ private:
|
|||
int m_ReloadTimer;
|
||||
int m_AttackTick;
|
||||
|
||||
int m_MoveRestrictions;
|
||||
|
||||
// these are non-heldback inputs
|
||||
CNetObj_PlayerInput m_LatestPrevInput;
|
||||
CNetObj_PlayerInput m_LatestInput;
|
||||
|
|
|
@ -124,8 +124,7 @@ void CDragger::DraggerBeamTick()
|
|||
// In the center of the dragger a tee does not experience speed-up
|
||||
else if(distance(pTarget->m_Pos, m_Pos) > 28)
|
||||
{
|
||||
vec2 Temp = pTarget->Core()->m_Vel + (normalize(m_Pos - pTarget->m_Pos) * m_Strength);
|
||||
pTarget->Core()->m_Vel = ClampVel(pTarget->m_MoveRestrictions, Temp);
|
||||
pTarget->AddVelocity(normalize(m_Pos - pTarget->m_Pos) * m_Strength);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,36 +47,39 @@ bool CLaser::HitCharacter(vec2 From, vec2 To)
|
|||
m_Energy = -1;
|
||||
if(m_Type == WEAPON_SHOTGUN)
|
||||
{
|
||||
vec2 Temp;
|
||||
float Strength = GetTuning(m_TuneZone)->m_ShotgunStrength;
|
||||
float Strength;
|
||||
if(!m_TuneZone)
|
||||
Strength = Tuning()->m_ShotgunStrength;
|
||||
else
|
||||
Strength = TuningList()[m_TuneZone].m_ShotgunStrength;
|
||||
|
||||
const vec2 &HitPos = pHit->Core()->m_Pos;
|
||||
if(!g_Config.m_SvOldLaser)
|
||||
{
|
||||
if(m_PrevPos != HitPos)
|
||||
{
|
||||
Temp = pHit->Core()->m_Vel + normalize(m_PrevPos - HitPos) * Strength;
|
||||
pHit->Core()->m_Vel = ClampVel(pHit->m_MoveRestrictions, Temp);
|
||||
pHit->AddVelocity(normalize(m_PrevPos - HitPos) * Strength);
|
||||
}
|
||||
else
|
||||
{
|
||||
pHit->Core()->m_Vel = StackedLaserShotgunBugSpeed;
|
||||
pHit->SetRawVelocity(StackedLaserShotgunBugSpeed);
|
||||
}
|
||||
}
|
||||
else if(g_Config.m_SvOldLaser && pOwnerChar)
|
||||
{
|
||||
if(pOwnerChar->Core()->m_Pos != HitPos)
|
||||
{
|
||||
Temp = pHit->Core()->m_Vel + normalize(pOwnerChar->Core()->m_Pos - HitPos) * Strength;
|
||||
pHit->Core()->m_Vel = ClampVel(pHit->m_MoveRestrictions, Temp);
|
||||
pHit->AddVelocity(normalize(pOwnerChar->Core()->m_Pos - HitPos) * Strength);
|
||||
}
|
||||
else
|
||||
{
|
||||
pHit->Core()->m_Vel = StackedLaserShotgunBugSpeed;
|
||||
pHit->SetRawVelocity(StackedLaserShotgunBugSpeed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pHit->Core()->m_Vel = ClampVel(pHit->m_MoveRestrictions, pHit->Core()->m_Vel);
|
||||
// Re-apply move restrictions as a part of 'shotgun bug' reproduction
|
||||
pHit->ApplyMoveRestrictions();
|
||||
}
|
||||
}
|
||||
else if(m_Type == WEAPON_LASER)
|
||||
|
|
|
@ -116,7 +116,7 @@ void CGameWorld::InsertEntity(CEntity *pEnt, bool Last)
|
|||
if(ID >= 0 && ID < MAX_CLIENTS)
|
||||
{
|
||||
m_apCharacters[ID] = pChar;
|
||||
m_Core.m_apCharacters[ID] = pChar->Core();
|
||||
m_Core.m_apCharacters[ID] = &pChar->m_Core;
|
||||
}
|
||||
pChar->SetCoreWorld(this);
|
||||
}
|
||||
|
@ -309,12 +309,9 @@ void CGameWorld::ReleaseHooked(int ClientID)
|
|||
CCharacter *pChr = (CCharacter *)CGameWorld::FindFirst(CGameWorld::ENTTYPE_CHARACTER);
|
||||
for(; pChr; pChr = (CCharacter *)pChr->TypeNext())
|
||||
{
|
||||
CCharacterCore *pCore = pChr->Core();
|
||||
if(pCore->HookedPlayer() == ClientID)
|
||||
if(pChr->Core()->HookedPlayer() == ClientID && !pChr->IsSuper())
|
||||
{
|
||||
pCore->SetHookedPlayer(-1);
|
||||
pCore->m_HookState = HOOK_RETRACTED;
|
||||
pCore->m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
||||
pChr->ReleaseHook();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -557,7 +554,7 @@ void CGameWorld::NetObjEnd()
|
|||
if(pHookedChar->m_MarkedForDestroy)
|
||||
{
|
||||
pHookedChar->m_Pos = pHookedChar->m_Core.m_Pos = pChar->m_Core.m_HookPos;
|
||||
pHookedChar->m_Core.m_Vel = vec2(0, 0);
|
||||
pHookedChar->ResetVelocity();
|
||||
mem_zero(&pHookedChar->m_SavedInput, sizeof(pHookedChar->m_SavedInput));
|
||||
pHookedChar->m_SavedInput.m_TargetY = -1;
|
||||
pHookedChar->m_KeepHooked = true;
|
||||
|
@ -577,7 +574,7 @@ void CGameWorld::NetObjEnd()
|
|||
if(ID >= 0 && ID < MAX_CLIENTS)
|
||||
{
|
||||
m_apCharacters[ID] = pChar;
|
||||
m_Core.m_apCharacters[ID] = pChar->Core();
|
||||
m_Core.m_apCharacters[ID] = &pChar->m_Core;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1593,7 +1593,7 @@ void CGameContext::ConTeleTo(IConsole::IResult *pResult, void *pUserData)
|
|||
// Teleport tee
|
||||
pSelf->Teleport(pCallingCharacter, Pos);
|
||||
pCallingCharacter->UnFreeze();
|
||||
pCallingCharacter->Core()->m_Vel = vec2(0, 0);
|
||||
pCallingCharacter->ResetVelocity();
|
||||
pCallingPlayer->m_LastTeleTee.Save(pCallingCharacter);
|
||||
}
|
||||
|
||||
|
@ -1670,7 +1670,7 @@ void CGameContext::ConTeleXY(IConsole::IResult *pResult, void *pUserData)
|
|||
// Teleport tee
|
||||
pSelf->Teleport(pCallingCharacter, Pos);
|
||||
pCallingCharacter->UnFreeze();
|
||||
pCallingCharacter->Core()->m_Vel = vec2(0, 0);
|
||||
pCallingCharacter->ResetVelocity();
|
||||
pCallingPlayer->m_LastTeleTee.Save(pCallingCharacter);
|
||||
}
|
||||
|
||||
|
@ -1722,7 +1722,7 @@ void CGameContext::ConTeleCursor(IConsole::IResult *pResult, void *pUserData)
|
|||
}
|
||||
pSelf->Teleport(pChr, Pos);
|
||||
pChr->UnFreeze();
|
||||
pChr->Core()->m_Vel = vec2(0, 0);
|
||||
pChr->ResetVelocity();
|
||||
pPlayer->m_LastTeleTee.Save(pChr);
|
||||
}
|
||||
|
||||
|
|
|
@ -77,8 +77,7 @@ void CGameContext::MoveCharacter(int ClientID, int X, int Y, bool Raw)
|
|||
if(!pChr)
|
||||
return;
|
||||
|
||||
pChr->Core()->m_Pos.x += ((Raw) ? 1 : 32) * X;
|
||||
pChr->Core()->m_Pos.y += ((Raw) ? 1 : 32) * Y;
|
||||
pChr->Move(vec2((Raw ? 1 : 32) * X, Raw ? 1 : 32) * Y);
|
||||
pChr->m_DDRaceState = DDRACE_CHEAT;
|
||||
}
|
||||
|
||||
|
@ -348,7 +347,7 @@ void CGameContext::ModifyWeapons(IConsole::IResult *pResult, void *pUserData,
|
|||
|
||||
void CGameContext::Teleport(CCharacter *pChr, vec2 Pos)
|
||||
{
|
||||
pChr->Core()->m_Pos = Pos;
|
||||
pChr->SetPosition(Pos);
|
||||
pChr->m_Pos = Pos;
|
||||
pChr->m_PrevPos = Pos;
|
||||
pChr->m_DDRaceState = DDRACE_CHEAT;
|
||||
|
@ -412,7 +411,7 @@ void CGameContext::ConTeleport(IConsole::IResult *pResult, void *pUserData)
|
|||
}
|
||||
pSelf->Teleport(pChr, Pos);
|
||||
pChr->UnFreeze();
|
||||
pChr->Core()->m_Vel = vec2(0, 0);
|
||||
pChr->SetVelocity(vec2(0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ void CCharacter::HandleNinja()
|
|||
Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(GetProximityRadius(), GetProximityRadius()), GroundElasticity);
|
||||
|
||||
// reset velocity so the client doesn't predict stuff
|
||||
m_Core.m_Vel = vec2(0.f, 0.f);
|
||||
ResetVelocity();
|
||||
|
||||
// check if we Hit anything along the way
|
||||
{
|
||||
|
@ -698,11 +698,16 @@ void CCharacter::OnDirectInput(CNetObj_PlayerInput *pNewInput)
|
|||
mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
|
||||
}
|
||||
|
||||
void CCharacter::ResetHook()
|
||||
void CCharacter::ReleaseHook()
|
||||
{
|
||||
m_Core.SetHookedPlayer(-1);
|
||||
m_Core.m_HookState = HOOK_RETRACTED;
|
||||
m_Core.m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
||||
}
|
||||
|
||||
void CCharacter::ResetHook()
|
||||
{
|
||||
ReleaseHook();
|
||||
m_Core.m_HookPos = m_Core.m_Pos;
|
||||
}
|
||||
|
||||
|
@ -1640,7 +1645,7 @@ void CCharacter::HandleTiles(int Index)
|
|||
m_Core.m_Jumped = 0;
|
||||
m_Core.m_JumpedTotal = 0;
|
||||
}
|
||||
m_Core.m_Vel = ClampVel(m_MoveRestrictions, m_Core.m_Vel);
|
||||
ApplyMoveRestrictions();
|
||||
|
||||
// handle switch tiles
|
||||
if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHOPEN && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
|
||||
|
@ -2357,6 +2362,43 @@ CClientMask CCharacter::TeamMask()
|
|||
return Teams()->TeamMask(Team(), -1, GetPlayer()->GetCID());
|
||||
}
|
||||
|
||||
void CCharacter::SetPosition(const vec2 &Position)
|
||||
{
|
||||
m_Core.m_Pos = Position;
|
||||
}
|
||||
|
||||
void CCharacter::Move(vec2 RelPos)
|
||||
{
|
||||
m_Core.m_Pos += RelPos;
|
||||
}
|
||||
|
||||
void CCharacter::ResetVelocity()
|
||||
{
|
||||
m_Core.m_Vel = vec2(0, 0);
|
||||
}
|
||||
|
||||
void CCharacter::SetVelocity(vec2 NewVelocity)
|
||||
{
|
||||
m_Core.m_Vel = ClampVel(m_MoveRestrictions, NewVelocity);
|
||||
}
|
||||
|
||||
// The method is needed only to reproduce 'shotgun bug' ddnet#5258
|
||||
// Use SetVelocity() instead.
|
||||
void CCharacter::SetRawVelocity(vec2 NewVelocity)
|
||||
{
|
||||
m_Core.m_Vel = NewVelocity;
|
||||
}
|
||||
|
||||
void CCharacter::AddVelocity(vec2 Addition)
|
||||
{
|
||||
SetVelocity(m_Core.m_Vel + Addition);
|
||||
}
|
||||
|
||||
void CCharacter::ApplyMoveRestrictions()
|
||||
{
|
||||
m_Core.m_Vel = ClampVel(m_MoveRestrictions, m_Core.m_Vel);
|
||||
}
|
||||
|
||||
void CCharacter::SwapClients(int Client1, int Client2)
|
||||
{
|
||||
const int HookedPlayer = m_Core.HookedPlayer();
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
|
||||
void OnPredictedInput(CNetObj_PlayerInput *pNewInput);
|
||||
void OnDirectInput(CNetObj_PlayerInput *pNewInput);
|
||||
void ReleaseHook();
|
||||
void ResetHook();
|
||||
void ResetInput();
|
||||
void FireWeapon();
|
||||
|
@ -88,6 +89,15 @@ public:
|
|||
class CPlayer *GetPlayer() { return m_pPlayer; }
|
||||
CClientMask TeamMask();
|
||||
|
||||
void SetPosition(const vec2 &Position);
|
||||
void Move(vec2 RelPos);
|
||||
|
||||
void ResetVelocity();
|
||||
void SetVelocity(vec2 NewVelocity);
|
||||
void SetRawVelocity(vec2 NewVelocity);
|
||||
void AddVelocity(vec2 Addition);
|
||||
void ApplyMoveRestrictions();
|
||||
|
||||
private:
|
||||
// player controlling this character
|
||||
class CPlayer *m_pPlayer;
|
||||
|
@ -106,6 +116,8 @@ private:
|
|||
int m_ReloadTimer;
|
||||
int m_AttackTick;
|
||||
|
||||
int m_MoveRestrictions;
|
||||
|
||||
int m_DamageTaken;
|
||||
|
||||
int m_EmoteType;
|
||||
|
@ -201,8 +213,6 @@ public:
|
|||
int m_TileIndex;
|
||||
int m_TileFIndex;
|
||||
|
||||
int m_MoveRestrictions;
|
||||
|
||||
int64_t m_LastStartWarning;
|
||||
int64_t m_LastRescue;
|
||||
bool m_LastRefillJumps;
|
||||
|
@ -226,7 +236,7 @@ public:
|
|||
void SetArmor(int Armor) { m_Armor = Armor; }
|
||||
CCharacterCore GetCore() { return m_Core; }
|
||||
void SetCore(CCharacterCore Core) { m_Core = Core; }
|
||||
CCharacterCore *Core() { return &m_Core; }
|
||||
const CCharacterCore *Core() const { return &m_Core; }
|
||||
bool GetWeaponGot(int Type) { return m_Core.m_aWeapons[Type].m_Got; }
|
||||
void SetWeaponGot(int Type, bool Value) { m_Core.m_aWeapons[Type].m_Got = Value; }
|
||||
int GetWeaponAmmo(int Type) { return m_Core.m_aWeapons[Type].m_Ammo; }
|
||||
|
|
|
@ -71,8 +71,7 @@ void CDraggerBeam::Tick()
|
|||
// In the center of the dragger a tee does not experience speed-up
|
||||
else if(distance(pTarget->m_Pos, m_Pos) > 28)
|
||||
{
|
||||
vec2 Temp = pTarget->Core()->m_Vel + (normalize(m_Pos - pTarget->m_Pos) * m_Strength);
|
||||
pTarget->Core()->m_Vel = ClampVel(pTarget->m_MoveRestrictions, Temp);
|
||||
pTarget->AddVelocity(normalize(m_Pos - pTarget->m_Pos) * m_Strength);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,9 +44,9 @@ bool CLaser::HitCharacter(vec2 From, vec2 To)
|
|||
bool pDontHitSelf = g_Config.m_SvOldLaser || (m_Bounces == 0 && !m_WasTele);
|
||||
|
||||
if(pOwnerChar ? (!pOwnerChar->LaserHitDisabled() && m_Type == WEAPON_LASER) || (!pOwnerChar->ShotgunHitDisabled() && m_Type == WEAPON_SHOTGUN) : g_Config.m_SvHit)
|
||||
pHit = GameServer()->m_World.IntersectCharacter(m_Pos, To, 0.f, At, pDontHitSelf ? pOwnerChar : 0, m_Owner);
|
||||
pHit = GameWorld()->IntersectCharacter(m_Pos, To, 0.f, At, pDontHitSelf ? pOwnerChar : 0, m_Owner);
|
||||
else
|
||||
pHit = GameServer()->m_World.IntersectCharacter(m_Pos, To, 0.f, At, pDontHitSelf ? pOwnerChar : 0, m_Owner, pOwnerChar);
|
||||
pHit = GameWorld()->IntersectCharacter(m_Pos, To, 0.f, At, pDontHitSelf ? pOwnerChar : 0, m_Owner, pOwnerChar);
|
||||
|
||||
if(!pHit || (pHit == pOwnerChar && g_Config.m_SvOldLaser) || (pHit != pOwnerChar && pOwnerChar ? (pOwnerChar->LaserHitDisabled() && m_Type == WEAPON_LASER) || (pOwnerChar->ShotgunHitDisabled() && m_Type == WEAPON_SHOTGUN) : !g_Config.m_SvHit))
|
||||
return false;
|
||||
|
@ -55,42 +55,39 @@ bool CLaser::HitCharacter(vec2 From, vec2 To)
|
|||
m_Energy = -1;
|
||||
if(m_Type == WEAPON_SHOTGUN)
|
||||
{
|
||||
vec2 Temp;
|
||||
|
||||
float Strength;
|
||||
if(!m_TuneZone)
|
||||
Strength = Tuning()->m_ShotgunStrength;
|
||||
else
|
||||
Strength = TuningList()[m_TuneZone].m_ShotgunStrength;
|
||||
|
||||
vec2 &HitPos = pHit->Core()->m_Pos;
|
||||
const vec2 &HitPos = pHit->Core()->m_Pos;
|
||||
if(!g_Config.m_SvOldLaser)
|
||||
{
|
||||
if(m_PrevPos != HitPos)
|
||||
{
|
||||
Temp = pHit->Core()->m_Vel + normalize(m_PrevPos - HitPos) * Strength;
|
||||
pHit->Core()->m_Vel = ClampVel(pHit->m_MoveRestrictions, Temp);
|
||||
pHit->AddVelocity(normalize(m_PrevPos - HitPos) * Strength);
|
||||
}
|
||||
else
|
||||
{
|
||||
pHit->Core()->m_Vel = StackedLaserShotgunBugSpeed;
|
||||
pHit->SetRawVelocity(StackedLaserShotgunBugSpeed);
|
||||
}
|
||||
}
|
||||
else if(g_Config.m_SvOldLaser && pOwnerChar)
|
||||
{
|
||||
if(pOwnerChar->Core()->m_Pos != HitPos)
|
||||
{
|
||||
Temp = pHit->Core()->m_Vel + normalize(pOwnerChar->Core()->m_Pos - HitPos) * Strength;
|
||||
pHit->Core()->m_Vel = ClampVel(pHit->m_MoveRestrictions, Temp);
|
||||
pHit->AddVelocity(normalize(pOwnerChar->Core()->m_Pos - HitPos) * Strength);
|
||||
}
|
||||
else
|
||||
{
|
||||
pHit->Core()->m_Vel = StackedLaserShotgunBugSpeed;
|
||||
pHit->SetRawVelocity(StackedLaserShotgunBugSpeed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pHit->Core()->m_Vel = ClampVel(pHit->m_MoveRestrictions, pHit->Core()->m_Vel);
|
||||
// Re-apply move restrictions as a part of 'shotgun bug' reproduction
|
||||
pHit->ApplyMoveRestrictions();
|
||||
}
|
||||
}
|
||||
else if(m_Type == WEAPON_LASER)
|
||||
|
|
|
@ -361,12 +361,9 @@ void CGameWorld::ReleaseHooked(int ClientID)
|
|||
CCharacter *pChr = (CCharacter *)CGameWorld::FindFirst(CGameWorld::ENTTYPE_CHARACTER);
|
||||
for(; pChr; pChr = (CCharacter *)pChr->TypeNext())
|
||||
{
|
||||
CCharacterCore *pCore = pChr->Core();
|
||||
if(pCore->HookedPlayer() == ClientID && !pChr->IsSuper())
|
||||
if(pChr->Core()->HookedPlayer() == ClientID && !pChr->IsSuper())
|
||||
{
|
||||
pCore->SetHookedPlayer(-1);
|
||||
pCore->m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
||||
pCore->m_HookState = HOOK_RETRACTED;
|
||||
pChr->ReleaseHook();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue