1/* (c) Shereef Marzouk. See "licence DDRace.txt" and the readme.txt in the root of the distribution for more information. */
2#include "door.h"
3
4#include "character.h"
5
6#include <generated/protocol.h>
7
8#include <game/mapitems.h>
9#include <game/server/gamecontext.h>
10#include <game/server/player.h>
11#include <game/teamscore.h>
12
13CDoor::CDoor(CGameWorld *pGameWorld, vec2 Pos, float Rotation, int Length,
14 int Number) :
15 CEntity(pGameWorld, CGameWorld::ENTTYPE_LASER)
16{
17 m_Number = Number;
18 m_Pos = Pos;
19 m_Length = Length;
20 m_Direction = vec2(std::sin(x: Rotation), std::cos(x: Rotation));
21 vec2 To = Pos + normalize(v: m_Direction) * m_Length;
22
23 GameServer()->Collision()->IntersectNoLaser(Pos0: Pos, Pos1: To, pOutCollision: &this->m_To, pOutBeforeCollision: nullptr);
24 ResetCollision();
25 GameWorld()->InsertEntity(pEntity: this);
26}
27
28void CDoor::ResetCollision()
29{
30 if(GameServer()->Collision()->GetTile(x: m_Pos.x, y: m_Pos.y) || GameServer()->Collision()->GetFrontTile(x: m_Pos.x, y: m_Pos.y))
31 return;
32
33 for(int i = 0; i < m_Length - 1; i++)
34 {
35 vec2 CurrentPos = m_Pos + m_Direction * i;
36 if(GameServer()->Collision()->CheckPoint(Pos: CurrentPos))
37 break;
38 else
39 GameServer()->Collision()->SetDoorCollisionAt(x: CurrentPos.x, y: CurrentPos.y, Type: TILE_STOPA, Flags: 0, Number: m_Number);
40 }
41}
42
43void CDoor::Reset()
44{
45 m_MarkedForDestroy = true;
46}
47
48void CDoor::Snap(int SnappingClient)
49{
50 if(NetworkClipped(SnappingClient, CheckPos: m_Pos) && NetworkClipped(SnappingClient, CheckPos: m_To))
51 return;
52
53 int SnappingClientVersion = GameServer()->GetClientVersion(ClientId: SnappingClient);
54
55 vec2 From;
56 int StartTick;
57
58 if(SnappingClientVersion >= VERSION_DDNET_ENTITY_NETOBJS)
59 {
60 From = m_To;
61 StartTick = -1;
62 }
63 else
64 {
65 CCharacter *pChr = GameServer()->GetPlayerChar(ClientId: SnappingClient);
66
67 if(SnappingClient != SERVER_DEMO_CLIENT && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == TEAM_SPECTATORS || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->SpectatorId() != SPEC_FREEVIEW)
68 pChr = GameServer()->GetPlayerChar(ClientId: GameServer()->m_apPlayers[SnappingClient]->SpectatorId());
69
70 if(pChr && pChr->Team() != TEAM_SUPER && pChr->IsAlive() && !Switchers().empty() && Switchers()[m_Number].m_aStatus[pChr->Team()])
71 {
72 From = m_To;
73 }
74 else
75 {
76 From = m_Pos;
77 }
78 StartTick = Server()->Tick();
79 }
80
81 GameServer()->SnapLaserObject(Context: CSnapContext(SnappingClientVersion, Server()->IsSixup(ClientId: SnappingClient), SnappingClient), SnapId: GetId(),
82 To: m_Pos, From, StartTick, Owner: -1, LaserType: LASERTYPE_DOOR, Subtype: 0, SwitchNumber: m_Number);
83}
84