1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
3 | #ifndef GAME_CLIENT_PREDICTION_GAMEWORLD_H |
4 | #define GAME_CLIENT_PREDICTION_GAMEWORLD_H |
5 | |
6 | #include <game/gamecore.h> |
7 | #include <game/teamscore.h> |
8 | |
9 | #include <list> |
10 | #include <vector> |
11 | |
12 | class CCollision; |
13 | class CCharacter; |
14 | class CEntity; |
15 | |
16 | class CGameWorld |
17 | { |
18 | public: |
19 | enum |
20 | { |
21 | ENTTYPE_PROJECTILE = 0, |
22 | ENTTYPE_LASER, |
23 | ENTTYPE_DOOR, |
24 | ENTTYPE_DRAGGER, |
25 | ENTTYPE_LIGHT, |
26 | ENTTYPE_GUN, |
27 | ENTTYPE_PLASMA, |
28 | ENTTYPE_PICKUP, |
29 | ENTTYPE_FLAG, |
30 | ENTTYPE_CHARACTER, |
31 | NUM_ENTTYPES |
32 | }; |
33 | |
34 | CWorldCore m_Core; |
35 | CTeamsCore m_Teams; |
36 | |
37 | CGameWorld(); |
38 | ~CGameWorld(); |
39 | |
40 | CEntity *FindFirst(int Type); |
41 | CEntity *FindLast(int Type); |
42 | int FindEntities(vec2 Pos, float Radius, CEntity **ppEnts, int Max, int Type); |
43 | CCharacter *IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, const CCharacter *pNotThis = nullptr, int CollideWith = -1, const CCharacter *pThisOnly = nullptr); |
44 | void InsertEntity(CEntity *pEntity, bool Last = false); |
45 | void RemoveEntity(CEntity *pEntity); |
46 | void RemoveCharacter(CCharacter *pChar); |
47 | void Tick(); |
48 | |
49 | // DDRace |
50 | void ReleaseHooked(int ClientId); |
51 | std::vector<CCharacter *> IntersectedCharacters(vec2 Pos0, vec2 Pos1, float Radius, const CEntity *pNotThis = nullptr); |
52 | |
53 | int m_GameTick; |
54 | CCollision *m_pCollision; |
55 | |
56 | // getter for server variables |
57 | int GameTick() { return m_GameTick; } |
58 | int GameTickSpeed() { return SERVER_TICK_SPEED; } |
59 | CCollision *Collision() { return m_pCollision; } |
60 | CTeamsCore *Teams() { return &m_Teams; } |
61 | std::vector<SSwitchers> &Switchers() { return m_Core.m_vSwitchers; } |
62 | CTuningParams *Tuning(); |
63 | CEntity *GetEntity(int Id, int EntityType); |
64 | CCharacter *GetCharacterById(int Id) { return (Id >= 0 && Id < MAX_CLIENTS) ? m_apCharacters[Id] : nullptr; } |
65 | |
66 | // from gamecontext |
67 | void CreateExplosion(vec2 Pos, int Owner, int Weapon, bool NoDamage, int ActivatedTeam, CClientMask Mask); |
68 | |
69 | // for client side prediction |
70 | struct |
71 | { |
72 | bool m_IsDDRace; |
73 | bool m_IsVanilla; |
74 | bool m_IsFNG; |
75 | bool m_InfiniteAmmo; |
76 | bool m_PredictTiles; |
77 | int m_PredictFreeze; |
78 | bool m_PredictWeapons; |
79 | bool m_PredictDDRace; |
80 | bool m_IsSolo; |
81 | bool m_UseTuneZones; |
82 | bool m_BugDDRaceInput; |
83 | bool m_NoWeakHookAndBounce; |
84 | } m_WorldConfig; |
85 | |
86 | bool m_IsValidCopy; |
87 | CGameWorld *m_pParent; |
88 | CGameWorld *m_pChild; |
89 | |
90 | int m_LocalClientId; |
91 | |
92 | bool IsLocalTeam(int OwnerId) const; |
93 | void OnModified() const; |
94 | void NetObjBegin(CTeamsCore Teams, int LocalClientId); |
95 | void NetCharAdd(int ObjId, CNetObj_Character *pChar, CNetObj_DDNetCharacter *pExtended, int GameTeam, bool IsLocal); |
96 | void NetObjAdd(int ObjId, int ObjType, const void *pObjData, const CNetObj_EntityEx *pDataEx); |
97 | void NetObjEnd(); |
98 | void CopyWorld(CGameWorld *pFrom); |
99 | CEntity *FindMatch(int ObjId, int ObjType, const void *pObjData); |
100 | void Clear(); |
101 | |
102 | CTuningParams *m_pTuningList; |
103 | CTuningParams *TuningList() { return m_pTuningList; } |
104 | CTuningParams *GetTuning(int i) { return &TuningList()[i]; } |
105 | |
106 | private: |
107 | void RemoveEntities(); |
108 | |
109 | CEntity *m_pNextTraverseEntity = nullptr; |
110 | CEntity *m_apFirstEntityTypes[NUM_ENTTYPES]; |
111 | |
112 | CCharacter *m_apCharacters[MAX_CLIENTS]; |
113 | }; |
114 | |
115 | class CCharOrder |
116 | { |
117 | public: |
118 | std::list<int> m_Ids; // reverse of the order in the gameworld, since entities will be inserted in reverse |
119 | CCharOrder() |
120 | { |
121 | Reset(); |
122 | } |
123 | void Reset() |
124 | { |
125 | m_Ids.clear(); |
126 | for(int i = 0; i < MAX_CLIENTS; i++) |
127 | m_Ids.push_back(x: i); |
128 | } |
129 | void GiveStrong(int c) |
130 | { |
131 | if(0 <= c && c < MAX_CLIENTS) |
132 | { |
133 | m_Ids.remove(value: c); |
134 | m_Ids.push_front(x: c); |
135 | } |
136 | } |
137 | void GiveWeak(int c) |
138 | { |
139 | if(0 <= c && c < MAX_CLIENTS) |
140 | { |
141 | m_Ids.remove(value: c); |
142 | m_Ids.push_back(x: c); |
143 | } |
144 | } |
145 | bool HasStrongAgainst(int From, int To) |
146 | { |
147 | for(int i : m_Ids) |
148 | { |
149 | if(i == To) |
150 | return false; |
151 | else if(i == From) |
152 | return true; |
153 | } |
154 | return false; |
155 | } |
156 | }; |
157 | |
158 | #endif |
159 | |