5269: Introduce and use constexpr CCharacterCore::PhysicalSize r=def- a=Kaffeine

Add `Collision()` getter to server CEntity to make it easier to sync the server and prediction implementations (e.g. `IsGrounded()` imps are now identical).

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: Alexander Akulich <akulichalexander@gmail.com>
This commit is contained in:
bors[bot] 2022-05-28 22:23:20 +00:00 committed by GitHub
commit 9e6ee21545
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 128 additions and 127 deletions

View file

@ -22,12 +22,12 @@ public:
T y, v; T y, v;
}; };
vector2_base() : constexpr vector2_base() :
x(T()), y(T()) x(T()), y(T())
{ {
} }
vector2_base(T nx, T ny) : constexpr vector2_base(T nx, T ny) :
x(nx), y(ny) x(nx), y(ny)
{ {
} }

View file

@ -835,13 +835,13 @@ void CHud::RenderPlayerState(const int ClientID)
if(m_pClient->m_Snap.m_aCharacters[ClientID].m_HasExtendedDisplayInfo) if(m_pClient->m_Snap.m_aCharacters[ClientID].m_HasExtendedDisplayInfo)
{ {
bool Grounded = false; bool Grounded = false;
if(Collision()->CheckPoint(pCharacter->m_Pos.x + CCharacter::ms_PhysSize / 2, if(Collision()->CheckPoint(pCharacter->m_Pos.x + CCharacterCore::PhysicalSize() / 2,
pCharacter->m_Pos.y + CCharacter::ms_PhysSize / 2 + 5)) pCharacter->m_Pos.y + CCharacterCore::PhysicalSize() / 2 + 5))
{ {
Grounded = true; Grounded = true;
} }
if(Collision()->CheckPoint(pCharacter->m_Pos.x - CCharacter::ms_PhysSize / 2, if(Collision()->CheckPoint(pCharacter->m_Pos.x - CCharacterCore::PhysicalSize() / 2,
pCharacter->m_Pos.y + CCharacter::ms_PhysSize / 2 + 5)) pCharacter->m_Pos.y + CCharacterCore::PhysicalSize() / 2 + 5))
{ {
Grounded = true; Grounded = true;
} }

View file

@ -190,9 +190,7 @@ void CPlayers::RenderHookCollLine(
ColorRGBA HookCollColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClHookCollColorNoColl)); ColorRGBA HookCollColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClHookCollColorNoColl));
float PhysSize = 28.0f; vec2 OldPos = InitPos + ExDirection * CCharacterCore::PhysicalSize() * 1.5f;
vec2 OldPos = InitPos + ExDirection * PhysSize * 1.5f;
vec2 NewPos = OldPos; vec2 NewPos = OldPos;
bool DoBreak = false; bool DoBreak = false;

View file

@ -2190,7 +2190,6 @@ IGameClient *CreateGameClient()
int CGameClient::IntersectCharacter(vec2 HookPos, vec2 NewPos, vec2 &NewPos2, int ownID) int CGameClient::IntersectCharacter(vec2 HookPos, vec2 NewPos, vec2 &NewPos2, int ownID)
{ {
float PhysSize = 28.0f;
float Distance = 0.0f; float Distance = 0.0f;
int ClosestID = -1; int ClosestID = -1;
@ -2220,7 +2219,7 @@ int CGameClient::IntersectCharacter(vec2 HookPos, vec2 NewPos, vec2 &NewPos2, in
vec2 ClosestPoint; vec2 ClosestPoint;
if(closest_point_on_line(HookPos, NewPos, Position, ClosestPoint)) if(closest_point_on_line(HookPos, NewPos, Position, ClosestPoint))
{ {
if(distance(Position, ClosestPoint) < PhysSize + 2.0f) if(distance(Position, ClosestPoint) < CCharacterCore::PhysicalSize() + 2.0f)
{ {
if(ClosestID == -1 || distance(HookPos, Position) < Distance) if(ClosestID == -1 || distance(HookPos, Position) < Distance)
{ {

View file

@ -31,12 +31,12 @@ void CCharacter::SetSolo(bool Solo)
bool CCharacter::IsGrounded() bool CCharacter::IsGrounded()
{ {
if(Collision()->CheckPoint(m_Pos.x + m_ProximityRadius / 2, m_Pos.y + m_ProximityRadius / 2 + 5)) if(Collision()->CheckPoint(m_Pos.x + GetProximityRadius() / 2, m_Pos.y + GetProximityRadius() / 2 + 5))
return true; return true;
if(Collision()->CheckPoint(m_Pos.x - m_ProximityRadius / 2, m_Pos.y + m_ProximityRadius / 2 + 5)) if(Collision()->CheckPoint(m_Pos.x - GetProximityRadius() / 2, m_Pos.y + GetProximityRadius() / 2 + 5))
return true; return true;
int MoveRestrictionsBelow = Collision()->GetMoveRestrictions(m_Pos + vec2(0, m_ProximityRadius / 2 + 4), 0.0f); int MoveRestrictionsBelow = Collision()->GetMoveRestrictions(m_Pos + vec2(0, GetProximityRadius() / 2 + 4), 0.0f);
return (MoveRestrictionsBelow & CANTMOVE_DOWN) != 0; return (MoveRestrictionsBelow & CANTMOVE_DOWN) != 0;
} }
@ -1087,7 +1087,7 @@ CTeamsCore *CCharacter::TeamsCore()
} }
CCharacter::CCharacter(CGameWorld *pGameWorld, int ID, CNetObj_Character *pChar, CNetObj_DDNetCharacter *pExtended, CNetObj_DDNetCharacterDisplayInfo *pExtendedDisplayInfo) : CCharacter::CCharacter(CGameWorld *pGameWorld, int ID, CNetObj_Character *pChar, CNetObj_DDNetCharacter *pExtended, CNetObj_DDNetCharacterDisplayInfo *pExtendedDisplayInfo) :
CEntity(pGameWorld, CGameWorld::ENTTYPE_CHARACTER) CEntity(pGameWorld, CGameWorld::ENTTYPE_CHARACTER, vec2(0, 0), CCharacterCore::PhysicalSize())
{ {
m_ID = ID; m_ID = ID;
m_IsLocal = false; m_IsLocal = false;
@ -1102,7 +1102,6 @@ CCharacter::CCharacter(CGameWorld *pGameWorld, int ID, CNetObj_Character *pChar,
mem_zero(&m_Core.m_Ninja, sizeof(m_Core.m_Ninja)); mem_zero(&m_Core.m_Ninja, sizeof(m_Core.m_Ninja));
mem_zero(&m_SavedInput, sizeof(m_SavedInput)); mem_zero(&m_SavedInput, sizeof(m_SavedInput));
m_LatestInput = m_LatestPrevInput = m_PrevInput = m_Input = m_SavedInput; m_LatestInput = m_LatestPrevInput = m_PrevInput = m_Input = m_SavedInput;
m_ProximityRadius = ms_PhysSize;
m_Core.m_LeftWall = true; m_Core.m_LeftWall = true;
m_ReloadTimer = 0; m_ReloadTimer = 0;
m_NumObjectsHit = 0; m_NumObjectsHit = 0;

View file

@ -6,12 +6,13 @@
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Entity // Entity
////////////////////////////////////////////////// //////////////////////////////////////////////////
CEntity::CEntity(CGameWorld *pGameWorld, int ObjType) CEntity::CEntity(CGameWorld *pGameWorld, int ObjType, vec2 Pos, int ProximityRadius)
{ {
m_pGameWorld = pGameWorld; m_pGameWorld = pGameWorld;
m_ObjType = ObjType; m_ObjType = ObjType;
m_ProximityRadius = 0; m_Pos = Pos;
m_ProximityRadius = ProximityRadius;
m_MarkedForDestroy = false; m_MarkedForDestroy = false;
m_ID = -1; m_ID = -1;

View file

@ -38,7 +38,7 @@ protected:
int m_ObjType; int m_ObjType;
public: public:
CEntity(CGameWorld *pGameWorld, int Objtype); CEntity(CGameWorld *pGameWorld, int Objtype, vec2 Pos = vec2(0, 0), int ProximityRadius = 0);
virtual ~CEntity(); virtual ~CEntity();
class CGameWorld *GameWorld() { return m_pGameWorld; } class CGameWorld *GameWorld() { return m_pGameWorld; }
@ -48,6 +48,7 @@ public:
class CCollision *Collision() { return GameWorld()->Collision(); } class CCollision *Collision() { return GameWorld()->Collision(); }
CEntity *TypeNext() { return m_pNextTypeEntity; } CEntity *TypeNext() { return m_pNextTypeEntity; }
CEntity *TypePrev() { return m_pPrevTypeEntity; } CEntity *TypePrev() { return m_pPrevTypeEntity; }
float GetProximityRadius() const { return m_ProximityRadius; }
void Destroy() { delete this; } void Destroy() { delete this; }
virtual void Tick() {} virtual void Tick() {}

View file

@ -405,7 +405,7 @@ void CGameWorld::NetObjAdd(int ObjID, int ObjType, const void *pObjData, const C
// otherwise try to determine its owner by checking if there is only one player nearby // otherwise try to determine its owner by checking if there is only one player nearby
if(NetProj.m_StartTick >= GameTick() - 4) if(NetProj.m_StartTick >= GameTick() - 4)
{ {
const vec2 NetPos = NetProj.m_Pos - normalize(NetProj.m_Direction) * 28.0 * 0.75; const vec2 NetPos = NetProj.m_Pos - normalize(NetProj.m_Direction) * CCharacterCore::PhysicalSize() * 0.75;
const bool Prev = (GameTick() - NetProj.m_StartTick) > 1; const bool Prev = (GameTick() - NetProj.m_StartTick) > 1;
float First = 200.0f, Second = 200.0f; float First = 200.0f, Second = 200.0f;
CCharacter *pClosest = 0; CCharacter *pClosest = 0;

View file

@ -116,15 +116,14 @@ void CCharacterCore::Reset()
void CCharacterCore::Tick(bool UseInput) void CCharacterCore::Tick(bool UseInput)
{ {
float PhysSize = 28.0f;
m_MoveRestrictions = m_pCollision->GetMoveRestrictions(UseInput ? IsSwitchActiveCb : 0, this, m_Pos); m_MoveRestrictions = m_pCollision->GetMoveRestrictions(UseInput ? IsSwitchActiveCb : 0, this, m_Pos);
m_TriggeredEvents = 0; m_TriggeredEvents = 0;
// get ground state // get ground state
bool Grounded = false; bool Grounded = false;
if(m_pCollision->CheckPoint(m_Pos.x + PhysSize / 2, m_Pos.y + PhysSize / 2 + 5)) if(m_pCollision->CheckPoint(m_Pos.x + PhysicalSize() / 2, m_Pos.y + PhysicalSize() / 2 + 5))
Grounded = true; Grounded = true;
if(m_pCollision->CheckPoint(m_Pos.x - PhysSize / 2, m_Pos.y + PhysSize / 2 + 5)) if(m_pCollision->CheckPoint(m_Pos.x - PhysicalSize() / 2, m_Pos.y + PhysicalSize() / 2 + 5))
Grounded = true; Grounded = true;
vec2 TargetDirection = normalize(vec2(m_Input.m_TargetX, m_Input.m_TargetY)); vec2 TargetDirection = normalize(vec2(m_Input.m_TargetX, m_Input.m_TargetY));
@ -196,7 +195,7 @@ void CCharacterCore::Tick(bool UseInput)
if(m_HookState == HOOK_IDLE) if(m_HookState == HOOK_IDLE)
{ {
m_HookState = HOOK_FLYING; m_HookState = HOOK_FLYING;
m_HookPos = m_Pos + TargetDirection * PhysSize * 1.5f; m_HookPos = m_Pos + TargetDirection * PhysicalSize() * 1.5f;
m_HookDir = TargetDirection; m_HookDir = TargetDirection;
SetHookedPlayer(-1); SetHookedPlayer(-1);
m_HookTick = (float)SERVER_TICK_SPEED * (1.25f - m_Tuning.m_HookDuration); m_HookTick = (float)SERVER_TICK_SPEED * (1.25f - m_Tuning.m_HookDuration);
@ -287,7 +286,7 @@ void CCharacterCore::Tick(bool UseInput)
vec2 ClosestPoint; vec2 ClosestPoint;
if(closest_point_on_line(m_HookPos, NewPos, pCharCore->m_Pos, ClosestPoint)) if(closest_point_on_line(m_HookPos, NewPos, pCharCore->m_Pos, ClosestPoint))
{ {
if(distance(pCharCore->m_Pos, ClosestPoint) < PhysSize + 2.0f) if(distance(pCharCore->m_Pos, ClosestPoint) < PhysicalSize() + 2.0f)
{ {
if(m_HookedPlayer == -1 || distance(m_HookPos, pCharCore->m_Pos) < Distance) if(m_HookedPlayer == -1 || distance(m_HookPos, pCharCore->m_Pos) < Distance)
{ {
@ -322,7 +321,7 @@ void CCharacterCore::Tick(bool UseInput)
m_NewHook = true; m_NewHook = true;
int RandomOut = m_pWorld->RandomOr0((*m_pTeleOuts)[teleNr - 1].size()); int RandomOut = m_pWorld->RandomOr0((*m_pTeleOuts)[teleNr - 1].size());
m_HookPos = (*m_pTeleOuts)[teleNr - 1][RandomOut] + TargetDirection * PhysSize * 1.5f; m_HookPos = (*m_pTeleOuts)[teleNr - 1][RandomOut] + TargetDirection * PhysicalSize() * 1.5f;
m_HookDir = TargetDirection; m_HookDir = TargetDirection;
m_HookTeleBase = m_HookPos; m_HookTeleBase = m_HookPos;
} }
@ -411,9 +410,9 @@ void CCharacterCore::Tick(bool UseInput)
bool CanCollide = (m_Super || pCharCore->m_Super) || (pCharCore->m_Collision && m_Collision && !m_NoCollision && !pCharCore->m_NoCollision && m_Tuning.m_PlayerCollision); bool CanCollide = (m_Super || pCharCore->m_Super) || (pCharCore->m_Collision && m_Collision && !m_NoCollision && !pCharCore->m_NoCollision && m_Tuning.m_PlayerCollision);
if(CanCollide && Distance < PhysSize * 1.25f && Distance > 0.0f) if(CanCollide && Distance < PhysicalSize() * 1.25f && Distance > 0.0f)
{ {
float a = (PhysSize * 1.45f - Distance); float a = (PhysicalSize() * 1.45f - Distance);
float Velocity = 0.5f; float Velocity = 0.5f;
// make sure that we don't add excess force by checking the // make sure that we don't add excess force by checking the
@ -428,7 +427,7 @@ void CCharacterCore::Tick(bool UseInput)
// handle hook influence // handle hook influence
if(m_Hook && m_HookedPlayer == i && m_Tuning.m_PlayerHooking) if(m_Hook && m_HookedPlayer == i && m_Tuning.m_PlayerHooking)
{ {
if(Distance > PhysSize * 1.50f) // TODO: fix tweakable variable if(Distance > PhysicalSize() * 1.50f) // TODO: fix tweakable variable
{ {
float HookAccel = m_Tuning.m_HookDragAccel * (Distance / m_Tuning.m_HookLength); float HookAccel = m_Tuning.m_HookDragAccel * (Distance / m_Tuning.m_HookLength);
float DragSpeed = m_Tuning.m_HookDragSpeed; float DragSpeed = m_Tuning.m_HookDragSpeed;
@ -467,7 +466,7 @@ void CCharacterCore::Move()
vec2 NewPos = m_Pos; vec2 NewPos = m_Pos;
vec2 OldVel = m_Vel; vec2 OldVel = m_Vel;
m_pCollision->MoveBox(&NewPos, &m_Vel, vec2(28.0f, 28.0f), 0); m_pCollision->MoveBox(&NewPos, &m_Vel, PhysicalSizeVec2(), 0);
m_Colliding = 0; m_Colliding = 0;
if(m_Vel.x < 0.001f && m_Vel.x > -0.001f) if(m_Vel.x < 0.001f && m_Vel.x > -0.001f)
@ -502,7 +501,7 @@ void CCharacterCore::Move()
if((!(pCharCore->m_Super || m_Super) && (m_Solo || pCharCore->m_Solo || !pCharCore->m_Collision || pCharCore->m_NoCollision || (m_Id != -1 && !m_pTeams->CanCollide(m_Id, p))))) if((!(pCharCore->m_Super || m_Super) && (m_Solo || pCharCore->m_Solo || !pCharCore->m_Collision || pCharCore->m_NoCollision || (m_Id != -1 && !m_pTeams->CanCollide(m_Id, p)))))
continue; continue;
float D = distance(Pos, pCharCore->m_Pos); float D = distance(Pos, pCharCore->m_Pos);
if(D < 28.0f && D >= 0.0f) if(D < PhysicalSize() && D >= 0.0f)
{ {
if(a > 0.0f) if(a > 0.0f)
m_Pos = LastPos; m_Pos = LastPos;

View file

@ -211,6 +211,8 @@ class CCharacterCore
std::map<int, std::vector<vec2>> *m_pTeleOuts; std::map<int, std::vector<vec2>> *m_pTeleOuts;
public: public:
static constexpr float PhysicalSize() { return 28.0f; };
static constexpr vec2 PhysicalSizeVec2() { return vec2(28.0f, 28.0f); };
vec2 m_Pos; vec2 m_Pos;
vec2 m_Vel; vec2 m_Vel;
bool m_Hook; bool m_Hook;

View file

@ -20,7 +20,7 @@ MACRO_ALLOC_POOL_ID_IMPL(CCharacter, MAX_CLIENTS)
// Character, "physical" player's part // Character, "physical" player's part
CCharacter::CCharacter(CGameWorld *pWorld, CNetObj_PlayerInput LastInput) : CCharacter::CCharacter(CGameWorld *pWorld, CNetObj_PlayerInput LastInput) :
CEntity(pWorld, CGameWorld::ENTTYPE_CHARACTER, vec2(0, 0), ms_PhysSize) CEntity(pWorld, CGameWorld::ENTTYPE_CHARACTER, vec2(0, 0), CCharacterCore::PhysicalSize())
{ {
m_Health = 0; m_Health = 0;
m_Armor = 0; m_Armor = 0;
@ -65,7 +65,7 @@ bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
Antibot()->OnSpawn(m_pPlayer->GetCID()); Antibot()->OnSpawn(m_pPlayer->GetCID());
m_Core.Reset(); m_Core.Reset();
m_Core.Init(&GameServer()->m_World.m_Core, GameServer()->Collision()); m_Core.Init(&GameServer()->m_World.m_Core, Collision());
m_Core.m_ActiveWeapon = WEAPON_GUN; m_Core.m_ActiveWeapon = WEAPON_GUN;
m_Core.m_Pos = m_Pos; m_Core.m_Pos = m_Pos;
m_Core.m_Id = m_pPlayer->GetCID(); m_Core.m_Id = m_pPlayer->GetCID();
@ -82,7 +82,7 @@ bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
DDRaceInit(); DDRaceInit();
m_TuneZone = GameServer()->Collision()->IsTune(GameServer()->Collision()->GetMapIndex(Pos)); m_TuneZone = Collision()->IsTune(Collision()->GetMapIndex(Pos));
m_TuneZoneOld = -1; // no zone leave msg on spawn m_TuneZoneOld = -1; // no zone leave msg on spawn
m_NeededFaketuning = 0; // reset fake tunings on respawn and send the client m_NeededFaketuning = 0; // reset fake tunings on respawn and send the client
SendZoneMsgs(); // we want a entermessage also on spawn SendZoneMsgs(); // we want a entermessage also on spawn
@ -136,12 +136,12 @@ void CCharacter::SetLiveFrozen(bool Active)
bool CCharacter::IsGrounded() bool CCharacter::IsGrounded()
{ {
if(GameServer()->Collision()->CheckPoint(m_Pos.x + GetProximityRadius() / 2, m_Pos.y + GetProximityRadius() / 2 + 5)) if(Collision()->CheckPoint(m_Pos.x + GetProximityRadius() / 2, m_Pos.y + GetProximityRadius() / 2 + 5))
return true; return true;
if(GameServer()->Collision()->CheckPoint(m_Pos.x - GetProximityRadius() / 2, m_Pos.y + GetProximityRadius() / 2 + 5)) if(Collision()->CheckPoint(m_Pos.x - GetProximityRadius() / 2, m_Pos.y + GetProximityRadius() / 2 + 5))
return true; return true;
int MoveRestrictionsBelow = GameServer()->Collision()->GetMoveRestrictions(m_Pos + vec2(0, GetProximityRadius() / 2 + 4), 0.0f); int MoveRestrictionsBelow = Collision()->GetMoveRestrictions(m_Pos + vec2(0, GetProximityRadius() / 2 + 4), 0.0f);
return (MoveRestrictionsBelow & CANTMOVE_DOWN) != 0; return (MoveRestrictionsBelow & CANTMOVE_DOWN) != 0;
} }
@ -226,7 +226,7 @@ void CCharacter::HandleNinja()
// Set velocity // Set velocity
m_Core.m_Vel = m_Core.m_Ninja.m_ActivationDir * g_pData->m_Weapons.m_Ninja.m_Velocity; m_Core.m_Vel = m_Core.m_Ninja.m_ActivationDir * g_pData->m_Weapons.m_Ninja.m_Velocity;
vec2 OldPos = m_Pos; vec2 OldPos = m_Pos;
GameServer()->Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(GetProximityRadius(), GetProximityRadius()), 0.f); Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(GetProximityRadius(), GetProximityRadius()), 0.f);
// reset velocity so the client doesn't predict stuff // reset velocity so the client doesn't predict stuff
m_Core.m_Vel = vec2(0.f, 0.f); m_Core.m_Vel = vec2(0.f, 0.f);
@ -424,7 +424,7 @@ void CCharacter::FireWeapon()
{ {
CCharacter *pTarget = apEnts[i]; CCharacter *pTarget = apEnts[i];
//if ((pTarget == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, pTarget->m_Pos, NULL, NULL)) //if ((pTarget == this) || Collision()->IntersectLine(ProjStartPos, pTarget->m_Pos, NULL, NULL))
if((pTarget == this || (pTarget->IsAlive() && !CanCollide(pTarget->GetPlayer()->GetCID())))) if((pTarget == this || (pTarget->IsAlive() && !CanCollide(pTarget->GetPlayer()->GetCID()))))
continue; continue;
@ -766,7 +766,7 @@ void CCharacter::TickDefered()
// advance the dummy // advance the dummy
{ {
CWorldCore TempWorld; CWorldCore TempWorld;
m_ReckoningCore.Init(&TempWorld, GameServer()->Collision(), &Teams()->m_Core, m_pTeleOuts); m_ReckoningCore.Init(&TempWorld, Collision(), &Teams()->m_Core, m_pTeleOuts);
m_ReckoningCore.m_Id = m_pPlayer->GetCID(); m_ReckoningCore.m_Id = m_pPlayer->GetCID();
m_ReckoningCore.Tick(false); m_ReckoningCore.Tick(false);
m_ReckoningCore.Move(); m_ReckoningCore.Move();
@ -776,13 +776,13 @@ void CCharacter::TickDefered()
//lastsentcore //lastsentcore
vec2 StartPos = m_Core.m_Pos; vec2 StartPos = m_Core.m_Pos;
vec2 StartVel = m_Core.m_Vel; vec2 StartVel = m_Core.m_Vel;
bool StuckBefore = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f)); bool StuckBefore = Collision()->TestBox(m_Core.m_Pos, CCharacterCore::PhysicalSizeVec2());
m_Core.m_Id = m_pPlayer->GetCID(); m_Core.m_Id = m_pPlayer->GetCID();
m_Core.Move(); m_Core.Move();
bool StuckAfterMove = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f)); bool StuckAfterMove = Collision()->TestBox(m_Core.m_Pos, CCharacterCore::PhysicalSizeVec2());
m_Core.Quantize(); m_Core.Quantize();
bool StuckAfterQuant = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f)); bool StuckAfterQuant = Collision()->TestBox(m_Core.m_Pos, CCharacterCore::PhysicalSizeVec2());
m_Pos = m_Core.m_Pos; m_Pos = m_Core.m_Pos;
if(!StuckBefore && (StuckAfterMove || StuckAfterQuant)) if(!StuckBefore && (StuckAfterMove || StuckAfterQuant))
@ -1358,14 +1358,14 @@ void CCharacter::HandleBroadcast()
void CCharacter::HandleSkippableTiles(int Index) void CCharacter::HandleSkippableTiles(int Index)
{ {
// handle death-tiles and leaving gamelayer // handle death-tiles and leaving gamelayer
if((GameServer()->Collision()->GetCollisionAt(m_Pos.x + GetProximityRadius() / 3.f, m_Pos.y - GetProximityRadius() / 3.f) == TILE_DEATH || if((Collision()->GetCollisionAt(m_Pos.x + GetProximityRadius() / 3.f, m_Pos.y - GetProximityRadius() / 3.f) == TILE_DEATH ||
GameServer()->Collision()->GetCollisionAt(m_Pos.x + GetProximityRadius() / 3.f, m_Pos.y + GetProximityRadius() / 3.f) == TILE_DEATH || Collision()->GetCollisionAt(m_Pos.x + GetProximityRadius() / 3.f, m_Pos.y + GetProximityRadius() / 3.f) == TILE_DEATH ||
GameServer()->Collision()->GetCollisionAt(m_Pos.x - GetProximityRadius() / 3.f, m_Pos.y - GetProximityRadius() / 3.f) == TILE_DEATH || Collision()->GetCollisionAt(m_Pos.x - GetProximityRadius() / 3.f, m_Pos.y - GetProximityRadius() / 3.f) == TILE_DEATH ||
GameServer()->Collision()->GetCollisionAt(m_Pos.x - GetProximityRadius() / 3.f, m_Pos.y + GetProximityRadius() / 3.f) == TILE_DEATH || Collision()->GetCollisionAt(m_Pos.x - GetProximityRadius() / 3.f, m_Pos.y + GetProximityRadius() / 3.f) == TILE_DEATH ||
GameServer()->Collision()->GetFCollisionAt(m_Pos.x + GetProximityRadius() / 3.f, m_Pos.y - GetProximityRadius() / 3.f) == TILE_DEATH || Collision()->GetFCollisionAt(m_Pos.x + GetProximityRadius() / 3.f, m_Pos.y - GetProximityRadius() / 3.f) == TILE_DEATH ||
GameServer()->Collision()->GetFCollisionAt(m_Pos.x + GetProximityRadius() / 3.f, m_Pos.y + GetProximityRadius() / 3.f) == TILE_DEATH || Collision()->GetFCollisionAt(m_Pos.x + GetProximityRadius() / 3.f, m_Pos.y + GetProximityRadius() / 3.f) == TILE_DEATH ||
GameServer()->Collision()->GetFCollisionAt(m_Pos.x - GetProximityRadius() / 3.f, m_Pos.y - GetProximityRadius() / 3.f) == TILE_DEATH || Collision()->GetFCollisionAt(m_Pos.x - GetProximityRadius() / 3.f, m_Pos.y - GetProximityRadius() / 3.f) == TILE_DEATH ||
GameServer()->Collision()->GetFCollisionAt(m_Pos.x - GetProximityRadius() / 3.f, m_Pos.y + GetProximityRadius() / 3.f) == TILE_DEATH) && Collision()->GetFCollisionAt(m_Pos.x - GetProximityRadius() / 3.f, m_Pos.y + GetProximityRadius() / 3.f) == TILE_DEATH) &&
!m_Super && !(Team() && Teams()->TeeFinished(m_pPlayer->GetCID()))) !m_Super && !(Team() && Teams()->TeeFinished(m_pPlayer->GetCID())))
{ {
Die(m_pPlayer->GetCID(), WEAPON_WORLD); Die(m_pPlayer->GetCID(), WEAPON_WORLD);
@ -1382,12 +1382,12 @@ void CCharacter::HandleSkippableTiles(int Index)
return; return;
// handle speedup tiles // handle speedup tiles
if(GameServer()->Collision()->IsSpeedup(Index)) if(Collision()->IsSpeedup(Index))
{ {
vec2 Direction, TempVel = m_Core.m_Vel; vec2 Direction, TempVel = m_Core.m_Vel;
int Force, MaxSpeed = 0; int Force, MaxSpeed = 0;
float TeeAngle, SpeederAngle, DiffAngle, SpeedLeft, TeeSpeed; float TeeAngle, SpeederAngle, DiffAngle, SpeedLeft, TeeSpeed;
GameServer()->Collision()->GetSpeedup(Index, &Direction, &Force, &MaxSpeed); Collision()->GetSpeedup(Index, &Direction, &Force, &MaxSpeed);
if(Force == 255 && MaxSpeed) if(Force == 255 && MaxSpeed)
{ {
m_Core.m_Vel = Direction * (MaxSpeed / 5); m_Core.m_Vel = Direction * (MaxSpeed / 5);
@ -1444,17 +1444,17 @@ void CCharacter::HandleSkippableTiles(int Index)
bool CCharacter::IsSwitchActiveCb(int Number, void *pUser) bool CCharacter::IsSwitchActiveCb(int Number, void *pUser)
{ {
CCharacter *pThis = (CCharacter *)pUser; CCharacter *pThis = (CCharacter *)pUser;
CCollision *pCollision = pThis->GameServer()->Collision(); CCollision *pCollision = pThis->Collision();
return pCollision->m_pSwitchers && pThis->Team() != TEAM_SUPER && pCollision->m_pSwitchers[Number].m_Status[pThis->Team()]; return pCollision->m_pSwitchers && pThis->Team() != TEAM_SUPER && pCollision->m_pSwitchers[Number].m_Status[pThis->Team()];
} }
void CCharacter::HandleTiles(int Index) void CCharacter::HandleTiles(int Index)
{ {
int MapIndex = Index; int MapIndex = Index;
//int PureMapIndex = GameServer()->Collision()->GetPureMapIndex(m_Pos); //int PureMapIndex = Collision()->GetPureMapIndex(m_Pos);
m_TileIndex = GameServer()->Collision()->GetTileIndex(MapIndex); m_TileIndex = Collision()->GetTileIndex(MapIndex);
m_TileFIndex = GameServer()->Collision()->GetFTileIndex(MapIndex); m_TileFIndex = Collision()->GetFTileIndex(MapIndex);
m_MoveRestrictions = GameServer()->Collision()->GetMoveRestrictions(IsSwitchActiveCb, this, m_Pos, 18.0f, MapIndex); m_MoveRestrictions = Collision()->GetMoveRestrictions(IsSwitchActiveCb, this, m_Pos, 18.0f, MapIndex);
if(Index < 0) if(Index < 0)
{ {
m_LastRefillJumps = false; m_LastRefillJumps = false;
@ -1462,7 +1462,7 @@ void CCharacter::HandleTiles(int Index)
m_LastBonus = false; m_LastBonus = false;
return; return;
} }
int cp = GameServer()->Collision()->IsCheckpoint(MapIndex); int cp = Collision()->IsCheckpoint(MapIndex);
if(cp != -1 && m_DDRaceState == DDRACE_STARTED && cp > m_CpActive) if(cp != -1 && m_DDRaceState == DDRACE_STARTED && cp > m_CpActive)
{ {
m_CpActive = cp; m_CpActive = cp;
@ -1488,7 +1488,7 @@ void CCharacter::HandleTiles(int Index)
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID()); Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID());
} }
} }
int cpf = GameServer()->Collision()->IsFCheckpoint(MapIndex); int cpf = Collision()->IsFCheckpoint(MapIndex);
if(cpf != -1 && m_DDRaceState == DDRACE_STARTED && cpf > m_CpActive) if(cpf != -1 && m_DDRaceState == DDRACE_STARTED && cpf > m_CpActive)
{ {
m_CpActive = cpf; m_CpActive = cpf;
@ -1514,7 +1514,7 @@ void CCharacter::HandleTiles(int Index)
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID()); Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID());
} }
} }
int tcp = GameServer()->Collision()->IsTCheckpoint(MapIndex); int tcp = Collision()->IsTCheckpoint(MapIndex);
if(tcp) if(tcp)
m_TeleCheckpoint = tcp; m_TeleCheckpoint = tcp;
@ -1718,64 +1718,64 @@ void CCharacter::HandleTiles(int Index)
m_Core.m_Vel = ClampVel(m_MoveRestrictions, m_Core.m_Vel); m_Core.m_Vel = ClampVel(m_MoveRestrictions, m_Core.m_Vel);
// handle switch tiles // handle switch tiles
if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_SWITCHOPEN && Team() != TEAM_SUPER && GameServer()->Collision()->GetSwitchNumber(MapIndex) > 0) if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHOPEN && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{ {
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true; Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0; Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHOPEN; Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHOPEN;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_SWITCHTIMEDOPEN && Team() != TEAM_SUPER && GameServer()->Collision()->GetSwitchNumber(MapIndex) > 0) else if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHTIMEDOPEN && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{ {
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true; Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + GameServer()->Collision()->GetSwitchDelay(MapIndex) * Server()->TickSpeed(); Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + Collision()->GetSwitchDelay(MapIndex) * Server()->TickSpeed();
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDOPEN; Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDOPEN;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_SWITCHTIMEDCLOSE && Team() != TEAM_SUPER && GameServer()->Collision()->GetSwitchNumber(MapIndex) > 0) else if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHTIMEDCLOSE && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{ {
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false; Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + GameServer()->Collision()->GetSwitchDelay(MapIndex) * Server()->TickSpeed(); Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + Collision()->GetSwitchDelay(MapIndex) * Server()->TickSpeed();
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDCLOSE; Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDCLOSE;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_SWITCHCLOSE && Team() != TEAM_SUPER && GameServer()->Collision()->GetSwitchNumber(MapIndex) > 0) else if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHCLOSE && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{ {
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false; Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0; Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHCLOSE; Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHCLOSE;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER) else if(Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER)
{ {
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()]) if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
{ {
Freeze(GameServer()->Collision()->GetSwitchDelay(MapIndex)); Freeze(Collision()->GetSwitchDelay(MapIndex));
} }
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER) else if(Collision()->GetSwitchType(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER)
{ {
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()]) if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
m_DeepFreeze = true; m_DeepFreeze = true;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_DUNFREEZE && Team() != TEAM_SUPER) else if(Collision()->GetSwitchType(MapIndex) == TILE_DUNFREEZE && Team() != TEAM_SUPER)
{ {
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()]) if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
m_DeepFreeze = false; m_DeepFreeze = false;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_LFREEZE && Team() != TEAM_SUPER) else if(Collision()->GetSwitchType(MapIndex) == TILE_LFREEZE && Team() != TEAM_SUPER)
{ {
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()]) if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
{ {
m_LiveFreeze = true; m_LiveFreeze = true;
m_Core.m_LiveFrozen = true; m_Core.m_LiveFrozen = true;
} }
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_LUNFREEZE && Team() != TEAM_SUPER) else if(Collision()->GetSwitchType(MapIndex) == TILE_LUNFREEZE && Team() != TEAM_SUPER)
{ {
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || GameServer()->Collision()->m_pSwitchers[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()]) if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
{ {
m_LiveFreeze = false; m_LiveFreeze = false;
m_Core.m_LiveFrozen = false; m_Core.m_LiveFrozen = false;
} }
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_HAMMER && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_HAMMER) else if(Collision()->GetSwitchType(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_HAMMER && Collision()->GetSwitchDelay(MapIndex) == WEAPON_HAMMER)
{ {
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can hammer hit others"); GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can hammer hit others");
m_Hit &= ~DISABLE_HIT_HAMMER; m_Hit &= ~DISABLE_HIT_HAMMER;
@ -1783,7 +1783,7 @@ void CCharacter::HandleTiles(int Index)
m_Core.m_NoHammerHit = false; m_Core.m_NoHammerHit = false;
GameServer()->SendTuningParams(m_pPlayer->GetCID(), m_TuneZone); // update tunings GameServer()->SendTuningParams(m_pPlayer->GetCID(), m_TuneZone); // update tunings
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_HAMMER) && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_HAMMER) else if(Collision()->GetSwitchType(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_HAMMER) && Collision()->GetSwitchDelay(MapIndex) == WEAPON_HAMMER)
{ {
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can't hammer hit others"); GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can't hammer hit others");
m_Hit |= DISABLE_HIT_HAMMER; m_Hit |= DISABLE_HIT_HAMMER;
@ -1791,45 +1791,45 @@ void CCharacter::HandleTiles(int Index)
m_Core.m_NoHammerHit = true; m_Core.m_NoHammerHit = true;
GameServer()->SendTuningParams(m_pPlayer->GetCID(), m_TuneZone); // update tunings GameServer()->SendTuningParams(m_pPlayer->GetCID(), m_TuneZone); // update tunings
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_SHOTGUN && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_SHOTGUN) else if(Collision()->GetSwitchType(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_SHOTGUN && Collision()->GetSwitchDelay(MapIndex) == WEAPON_SHOTGUN)
{ {
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can shoot others with shotgun"); GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can shoot others with shotgun");
m_Hit &= ~DISABLE_HIT_SHOTGUN; m_Hit &= ~DISABLE_HIT_SHOTGUN;
m_Core.m_NoShotgunHit = false; m_Core.m_NoShotgunHit = false;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_SHOTGUN) && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_SHOTGUN) else if(Collision()->GetSwitchType(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_SHOTGUN) && Collision()->GetSwitchDelay(MapIndex) == WEAPON_SHOTGUN)
{ {
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can't shoot others with shotgun"); GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can't shoot others with shotgun");
m_Hit |= DISABLE_HIT_SHOTGUN; m_Hit |= DISABLE_HIT_SHOTGUN;
m_Core.m_NoShotgunHit = true; m_Core.m_NoShotgunHit = true;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_GRENADE && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_GRENADE) else if(Collision()->GetSwitchType(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_GRENADE && Collision()->GetSwitchDelay(MapIndex) == WEAPON_GRENADE)
{ {
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can shoot others with grenade"); GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can shoot others with grenade");
m_Hit &= ~DISABLE_HIT_GRENADE; m_Hit &= ~DISABLE_HIT_GRENADE;
m_Core.m_NoGrenadeHit = false; m_Core.m_NoGrenadeHit = false;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_GRENADE) && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_GRENADE) else if(Collision()->GetSwitchType(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_GRENADE) && Collision()->GetSwitchDelay(MapIndex) == WEAPON_GRENADE)
{ {
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can't shoot others with grenade"); GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can't shoot others with grenade");
m_Hit |= DISABLE_HIT_GRENADE; m_Hit |= DISABLE_HIT_GRENADE;
m_Core.m_NoGrenadeHit = true; m_Core.m_NoGrenadeHit = true;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_LASER && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_LASER) else if(Collision()->GetSwitchType(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_LASER && Collision()->GetSwitchDelay(MapIndex) == WEAPON_LASER)
{ {
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can shoot others with laser"); GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can shoot others with laser");
m_Hit &= ~DISABLE_HIT_LASER; m_Hit &= ~DISABLE_HIT_LASER;
m_Core.m_NoLaserHit = false; m_Core.m_NoLaserHit = false;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_LASER) && GameServer()->Collision()->GetSwitchDelay(MapIndex) == WEAPON_LASER) else if(Collision()->GetSwitchType(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_LASER) && Collision()->GetSwitchDelay(MapIndex) == WEAPON_LASER)
{ {
GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can't shoot others with laser"); GameServer()->SendChatTarget(GetPlayer()->GetCID(), "You can't shoot others with laser");
m_Hit |= DISABLE_HIT_LASER; m_Hit |= DISABLE_HIT_LASER;
m_Core.m_NoLaserHit = true; m_Core.m_NoLaserHit = true;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_JUMP) else if(Collision()->GetSwitchType(MapIndex) == TILE_JUMP)
{ {
int NewJumps = GameServer()->Collision()->GetSwitchDelay(MapIndex); int NewJumps = Collision()->GetSwitchDelay(MapIndex);
if(NewJumps == 255) if(NewJumps == 255)
{ {
NewJumps = -1; NewJumps = -1;
@ -1860,10 +1860,10 @@ void CCharacter::HandleTiles(int Index)
m_Core.m_Jumps = NewJumps; m_Core.m_Jumps = NewJumps;
} }
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_ADD_TIME && !m_LastPenalty) else if(Collision()->GetSwitchType(MapIndex) == TILE_ADD_TIME && !m_LastPenalty)
{ {
int min = GameServer()->Collision()->GetSwitchDelay(MapIndex); int min = Collision()->GetSwitchDelay(MapIndex);
int sec = GameServer()->Collision()->GetSwitchNumber(MapIndex); int sec = Collision()->GetSwitchNumber(MapIndex);
int Team = Teams()->m_Core.Team(m_Core.m_Id); int Team = Teams()->m_Core.Team(m_Core.m_Id);
m_StartTime -= (min * 60 + sec) * Server()->TickSpeed(); m_StartTime -= (min * 60 + sec) * Server()->TickSpeed();
@ -1884,10 +1884,10 @@ void CCharacter::HandleTiles(int Index)
m_LastPenalty = true; m_LastPenalty = true;
} }
else if(GameServer()->Collision()->GetSwitchType(MapIndex) == TILE_SUBTRACT_TIME && !m_LastBonus) else if(Collision()->GetSwitchType(MapIndex) == TILE_SUBTRACT_TIME && !m_LastBonus)
{ {
int min = GameServer()->Collision()->GetSwitchDelay(MapIndex); int min = Collision()->GetSwitchDelay(MapIndex);
int sec = GameServer()->Collision()->GetSwitchNumber(MapIndex); int sec = Collision()->GetSwitchNumber(MapIndex);
int Team = Teams()->m_Core.Team(m_Core.m_Id); int Team = Teams()->m_Core.Team(m_Core.m_Id);
m_StartTime += (min * 60 + sec) * Server()->TickSpeed(); m_StartTime += (min * 60 + sec) * Server()->TickSpeed();
@ -1911,17 +1911,17 @@ void CCharacter::HandleTiles(int Index)
m_LastBonus = true; m_LastBonus = true;
} }
if(GameServer()->Collision()->GetSwitchType(MapIndex) != TILE_ADD_TIME) if(Collision()->GetSwitchType(MapIndex) != TILE_ADD_TIME)
{ {
m_LastPenalty = false; m_LastPenalty = false;
} }
if(GameServer()->Collision()->GetSwitchType(MapIndex) != TILE_SUBTRACT_TIME) if(Collision()->GetSwitchType(MapIndex) != TILE_SUBTRACT_TIME)
{ {
m_LastBonus = false; m_LastBonus = false;
} }
int z = GameServer()->Collision()->IsTeleport(MapIndex); int z = Collision()->IsTeleport(MapIndex);
if(!g_Config.m_SvOldTeleportHook && !g_Config.m_SvOldTeleportWeapons && z && !(*m_pTeleOuts)[z - 1].empty()) if(!g_Config.m_SvOldTeleportHook && !g_Config.m_SvOldTeleportWeapons && z && !(*m_pTeleOuts)[z - 1].empty())
{ {
if(m_Super) if(m_Super)
@ -1936,7 +1936,7 @@ void CCharacter::HandleTiles(int Index)
ResetPickups(); ResetPickups();
return; return;
} }
int evilz = GameServer()->Collision()->IsEvilTeleport(MapIndex); int evilz = Collision()->IsEvilTeleport(MapIndex);
if(evilz && !(*m_pTeleOuts)[evilz - 1].empty()) if(evilz && !(*m_pTeleOuts)[evilz - 1].empty())
{ {
if(m_Super) if(m_Super)
@ -1959,7 +1959,7 @@ void CCharacter::HandleTiles(int Index)
} }
return; return;
} }
if(GameServer()->Collision()->IsCheckEvilTeleport(MapIndex)) if(Collision()->IsCheckEvilTeleport(MapIndex))
{ {
if(m_Super) if(m_Super)
return; return;
@ -1996,7 +1996,7 @@ void CCharacter::HandleTiles(int Index)
} }
return; return;
} }
if(GameServer()->Collision()->IsCheckTeleport(MapIndex)) if(Collision()->IsCheckTeleport(MapIndex))
{ {
if(m_Super) if(m_Super)
return; return;
@ -2034,8 +2034,8 @@ void CCharacter::HandleTiles(int Index)
void CCharacter::HandleTuneLayer() void CCharacter::HandleTuneLayer()
{ {
m_TuneZoneOld = m_TuneZone; m_TuneZoneOld = m_TuneZone;
int CurrentIndex = GameServer()->Collision()->GetMapIndex(m_Pos); int CurrentIndex = Collision()->GetMapIndex(m_Pos);
m_TuneZone = GameServer()->Collision()->IsTune(CurrentIndex); m_TuneZone = Collision()->IsTune(CurrentIndex);
if(m_TuneZone) if(m_TuneZone)
m_Core.m_Tuning = GameServer()->TuningList()[m_TuneZone]; // throw tunings from specific zone into gamecore m_Core.m_Tuning = GameServer()->TuningList()[m_TuneZone]; // throw tunings from specific zone into gamecore
@ -2134,11 +2134,11 @@ void CCharacter::DDRaceTick()
HandleTuneLayer(); // need this before coretick HandleTuneLayer(); // need this before coretick
// check if the tee is in any type of freeze // check if the tee is in any type of freeze
int Index = GameServer()->Collision()->GetPureMapIndex(m_Pos); int Index = Collision()->GetPureMapIndex(m_Pos);
const int aTiles[] = { const int aTiles[] = {
GameServer()->Collision()->GetTileIndex(Index), Collision()->GetTileIndex(Index),
GameServer()->Collision()->GetFTileIndex(Index), Collision()->GetFTileIndex(Index),
GameServer()->Collision()->GetSwitchType(Index)}; Collision()->GetSwitchType(Index)};
m_Core.m_IsInFreeze = false; m_Core.m_IsInFreeze = false;
for(const int Tile : aTiles) for(const int Tile : aTiles)
{ {
@ -2201,13 +2201,13 @@ void CCharacter::DDRacePostCoreTick()
m_Core.m_Jumped = 1; m_Core.m_Jumped = 1;
} }
int CurrentIndex = GameServer()->Collision()->GetMapIndex(m_Pos); int CurrentIndex = Collision()->GetMapIndex(m_Pos);
HandleSkippableTiles(CurrentIndex); HandleSkippableTiles(CurrentIndex);
if(!m_Alive) if(!m_Alive)
return; return;
// handle Anti-Skip tiles // handle Anti-Skip tiles
std::list<int> Indices = GameServer()->Collision()->GetMapIndices(m_PrevPos, m_Pos); std::list<int> Indices = Collision()->GetMapIndices(m_PrevPos, m_Pos);
if(!Indices.empty()) if(!Indices.empty())
{ {
for(int &Index : Indices) for(int &Index : Indices)

View file

@ -29,9 +29,6 @@ class CCharacter : public CEntity
friend class CSaveTee; // need to use core friend class CSaveTee; // need to use core
public: public:
//character's size
static const int ms_PhysSize = 28;
CCharacter(CGameWorld *pWorld, CNetObj_PlayerInput LastInput); CCharacter(CGameWorld *pWorld, CNetObj_PlayerInput LastInput);
void Reset() override; void Reset() override;

View file

@ -64,7 +64,7 @@ void CDragger::LookForPlayersToDrag()
mem_zero(pPlayersInRange, sizeof(pPlayersInRange)); mem_zero(pPlayersInRange, sizeof(pPlayersInRange));
int NumPlayersInRange = GameServer()->m_World.FindEntities(m_Pos, int NumPlayersInRange = GameServer()->m_World.FindEntities(m_Pos,
g_Config.m_SvDraggerRange - CCharacter::ms_PhysSize, g_Config.m_SvDraggerRange - CCharacterCore::PhysicalSize(),
(CEntity **)pPlayersInRange, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER); (CEntity **)pPlayersInRange, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
// The closest player (within range) in a team is selected as the target // The closest player (within range) in a team is selected as the target

View file

@ -11,6 +11,7 @@
CEntity::CEntity(CGameWorld *pGameWorld, int ObjType, vec2 Pos, int ProximityRadius) CEntity::CEntity(CGameWorld *pGameWorld, int ObjType, vec2 Pos, int ProximityRadius)
{ {
m_pGameWorld = pGameWorld; m_pGameWorld = pGameWorld;
m_pCCollision = GameServer()->Collision();
m_ObjType = ObjType; m_ObjType = ObjType;
m_Pos = Pos; m_Pos = Pos;
@ -61,16 +62,16 @@ bool CEntity::GetNearestAirPos(vec2 Pos, vec2 PrevPos, vec2 *pOutPos)
vec2 BlockCenter = vec2(round_to_int(Pos.x), round_to_int(Pos.y)) - PosInBlock + vec2(16.0f, 16.0f); vec2 BlockCenter = vec2(round_to_int(Pos.x), round_to_int(Pos.y)) - PosInBlock + vec2(16.0f, 16.0f);
*pOutPos = vec2(BlockCenter.x + (PosInBlock.x < 16 ? -2.0f : 1.0f), Pos.y); *pOutPos = vec2(BlockCenter.x + (PosInBlock.x < 16 ? -2.0f : 1.0f), Pos.y);
if(!GameServer()->Collision()->TestBox(*pOutPos, vec2(28.0f, 28.0f))) if(!GameServer()->Collision()->TestBox(*pOutPos, CCharacterCore::PhysicalSizeVec2()))
return true; return true;
*pOutPos = vec2(Pos.x, BlockCenter.y + (PosInBlock.y < 16 ? -2.0f : 1.0f)); *pOutPos = vec2(Pos.x, BlockCenter.y + (PosInBlock.y < 16 ? -2.0f : 1.0f));
if(!GameServer()->Collision()->TestBox(*pOutPos, vec2(28.0f, 28.0f))) if(!GameServer()->Collision()->TestBox(*pOutPos, CCharacterCore::PhysicalSizeVec2()))
return true; return true;
*pOutPos = vec2(BlockCenter.x + (PosInBlock.x < 16 ? -2.0f : 1.0f), *pOutPos = vec2(BlockCenter.x + (PosInBlock.x < 16 ? -2.0f : 1.0f),
BlockCenter.y + (PosInBlock.y < 16 ? -2.0f : 1.0f)); BlockCenter.y + (PosInBlock.y < 16 ? -2.0f : 1.0f));
return !GameServer()->Collision()->TestBox(*pOutPos, vec2(28.0f, 28.0f)); return !GameServer()->Collision()->TestBox(*pOutPos, CCharacterCore::PhysicalSizeVec2());
} }
bool CEntity::GetNearestAirPosPlayer(vec2 PlayerPos, vec2 *OutPos) bool CEntity::GetNearestAirPosPlayer(vec2 PlayerPos, vec2 *OutPos)
@ -78,7 +79,7 @@ bool CEntity::GetNearestAirPosPlayer(vec2 PlayerPos, vec2 *OutPos)
for(int dist = 5; dist >= -1; dist--) for(int dist = 5; dist >= -1; dist--)
{ {
*OutPos = vec2(PlayerPos.x, PlayerPos.y - dist); *OutPos = vec2(PlayerPos.x, PlayerPos.y - dist);
if(!GameServer()->Collision()->TestBox(*OutPos, vec2(28.0f, 28.0f))) if(!GameServer()->Collision()->TestBox(*OutPos, CCharacterCore::PhysicalSizeVec2()))
{ {
return true; return true;
} }
@ -119,4 +120,4 @@ bool NetworkClippedLine(const CGameContext *pGameServer, int SnappingClient, vec
} }
float ClippDistance = maximum(ShowDistance.x, ShowDistance.y); float ClippDistance = maximum(ShowDistance.x, ShowDistance.y);
return (absolute(DistanceToLine.x) > ClippDistance || absolute(DistanceToLine.y) > ClippDistance); return (absolute(DistanceToLine.x) > ClippDistance || absolute(DistanceToLine.y) > ClippDistance);
} }

View file

@ -9,6 +9,8 @@
#include "gamecontext.h" #include "gamecontext.h"
#include "gameworld.h" #include "gameworld.h"
class CCollision;
/* /*
Class: Entity Class: Entity
Basic entity class. Basic entity class.
@ -24,6 +26,7 @@ private:
/* Identity */ /* Identity */
class CGameWorld *m_pGameWorld; class CGameWorld *m_pGameWorld;
CCollision *m_pCCollision;
int m_ID; int m_ID;
int m_ObjType; int m_ObjType;
@ -59,6 +62,7 @@ public: // TODO: Maybe make protected
class CConfig *Config() { return m_pGameWorld->Config(); } class CConfig *Config() { return m_pGameWorld->Config(); }
class CGameContext *GameServer() { return m_pGameWorld->GameServer(); } class CGameContext *GameServer() { return m_pGameWorld->GameServer(); }
class IServer *Server() { return m_pGameWorld->Server(); } class IServer *Server() { return m_pGameWorld->Server(); }
CCollision *Collision() { return m_pCCollision; }
/* Getters */ /* Getters */
CEntity *TypeNext() { return m_pNextTypeEntity; } CEntity *TypeNext() { return m_pNextTypeEntity; }