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 | |
12 | CDoor::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 | |
27 | void 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 | |
43 | void CDoor::Reset() |
44 | { |
45 | m_MarkedForDestroy = true; |
46 | } |
47 | |
48 | void 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 | |