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#include "character.h"
4
5#include <game/generated/protocol.h>
6#include <game/mapitems.h>
7#include <game/teamscore.h>
8
9#include <game/server/gamecontext.h>
10#include <game/server/player.h>
11
12CDoor::CDoor(CGameWorld *pGameWorld, vec2 Pos, float Rotation, int Length,
13 int Number) :
14 CEntity(pGameWorld, CGameWorld::ENTTYPE_LASER)
15{
16 m_Number = Number;
17 m_Pos = Pos;
18 m_Length = Length;
19 m_Direction = vec2(std::sin(x: Rotation), std::cos(x: Rotation));
20 vec2 To = Pos + normalize(v: m_Direction) * m_Length;
21
22 GameServer()->Collision()->IntersectNoLaser(Pos0: Pos, Pos1: To, pOutCollision: &this->m_To, pOutBeforeCollision: 0);
23 ResetCollision();
24 GameWorld()->InsertEntity(pEntity: this);
25}
26
27void CDoor::ResetCollision()
28{
29 for(int i = 0; i < m_Length - 1; i++)
30 {
31 vec2 CurrentPos(m_Pos.x + (m_Direction.x * i),
32 m_Pos.y + (m_Direction.y * i));
33 if(GameServer()->Collision()->CheckPoint(Pos: CurrentPos) || GameServer()->Collision()->GetTile(x: m_Pos.x, y: m_Pos.y) || GameServer()->Collision()->GetFTile(x: m_Pos.x, y: m_Pos.y))
34 break;
35 else
36 GameServer()->Collision()->SetDCollisionAt(
37 x: m_Pos.x + (m_Direction.x * i),
38 y: m_Pos.y + (m_Direction.y * i), Type: TILE_STOPA, Flags: 0 /*Flags*/,
39 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]->m_SpectatorId != SPEC_FREEVIEW)
68 pChr = GameServer()->GetPlayerChar(ClientId: GameServer()->m_apPlayers[SnappingClient]->m_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), SnapId: GetId(),
82 To: m_Pos, From, StartTick, Owner: -1, LaserType: LASERTYPE_DOOR, Subtype: 0, SwitchNumber: m_Number);
83}
84