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
12class CCollision;
13class CCharacter;
14class CEntity;
15
16class CGameWorld
17{
18public:
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
106private:
107 void RemoveEntities();
108
109 CEntity *m_pNextTraverseEntity = nullptr;
110 CEntity *m_apFirstEntityTypes[NUM_ENTTYPES];
111
112 CCharacter *m_apCharacters[MAX_CLIENTS];
113};
114
115class CCharOrder
116{
117public:
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