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_SERVER_GAMECONTROLLER_H
4#define GAME_SERVER_GAMECONTROLLER_H
5
6#include <base/vmath.h>
7
8#include <engine/map.h>
9#include <engine/shared/protocol.h>
10
11#include <game/server/teams.h>
12
13struct CScoreLoadBestTimeResult;
14
15/*
16 Class: Game Controller
17 Controls the main game logic. Keeping track of team and player score,
18 winning conditions and specific game logic.
19*/
20class IGameController
21{
22 friend class CSaveTeam; // need access to GameServer() and Server()
23
24protected:
25 enum ESpawnType
26 {
27 SPAWNTYPE_DEFAULT = 0,
28 SPAWNTYPE_RED,
29 SPAWNTYPE_BLUE,
30
31 NUM_SPAWNTYPES
32 };
33
34private:
35 std::vector<vec2> m_avSpawnPoints[NUM_SPAWNTYPES];
36
37 class CGameContext *m_pGameServer;
38 class CConfig *m_pConfig;
39 class IServer *m_pServer;
40
41 CGameTeams m_Teams;
42
43protected:
44 CGameContext *GameServer() const { return m_pGameServer; }
45 CConfig *Config() { return m_pConfig; }
46 IServer *Server() const { return m_pServer; }
47
48 void DoActivityCheck();
49
50 struct CSpawnEval
51 {
52 CSpawnEval()
53 {
54 m_Got = false;
55 m_FriendlyTeam = -1;
56 m_Pos = vec2(100, 100);
57 }
58
59 vec2 m_Pos;
60 bool m_Got;
61 int m_FriendlyTeam;
62 float m_Score;
63 };
64
65 float EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos, int ClientId);
66 void EvaluateSpawnType(CSpawnEval *pEval, ESpawnType SpawnType, int ClientId);
67
68 void ResetGame();
69
70 char m_aMapWish[MAX_MAP_LENGTH];
71
72 int m_RoundStartTick;
73 int m_GameOverTick;
74 int m_SuddenDeath;
75
76 int m_Warmup;
77 int m_RoundCount;
78
79 int m_GameFlags;
80
81public:
82 const char *m_pGameType;
83
84 IGameController(class CGameContext *pGameServer);
85 virtual ~IGameController();
86
87 // event
88 /*
89 Function: OnCharacterDeath
90 Called when a CCharacter in the world dies.
91
92 Arguments:
93 victim - The CCharacter that died.
94 killer - The player that killed it.
95 weapon - What weapon that killed it. Can be -1 for undefined
96 weapon when switching team or player suicides.
97 */
98 virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
99 /*
100 Function: OnCharacterSpawn
101 Called when a CCharacter spawns into the game world.
102
103 Arguments:
104 chr - The CCharacter that was spawned.
105 */
106 virtual void OnCharacterSpawn(class CCharacter *pChr);
107
108 virtual void HandleCharacterTiles(class CCharacter *pChr, int MapIndex);
109 virtual void SetArmorProgress(CCharacter *pCharacter, int Progress) {}
110
111 /*
112 Function: OnEntity
113 Called when the map is loaded to process an entity
114 in the map.
115
116 Arguments:
117 index - Entity index.
118 pos - Where the entity is located in the world.
119
120 Returns:
121 bool?
122 */
123 virtual bool OnEntity(int Index, int x, int y, int Layer, int Flags, bool Initial, int Number = 0);
124
125 virtual void OnPlayerConnect(class CPlayer *pPlayer);
126 virtual void OnPlayerDisconnect(class CPlayer *pPlayer, const char *pReason);
127
128 virtual void OnReset();
129
130 // game
131 virtual void DoWarmup(int Seconds);
132
133 void StartRound();
134 void EndRound();
135 void ChangeMap(const char *pToMap);
136
137 /*
138
139 */
140 virtual void Tick();
141
142 virtual void Snap(int SnappingClient);
143
144 //spawn
145 virtual bool CanSpawn(int Team, vec2 *pOutPos, int ClientId);
146
147 virtual void DoTeamChange(class CPlayer *pPlayer, int Team, bool DoChatMsg = true);
148
149 int TileFlagsToPickupFlags(int TileFlags) const;
150
151 /*
152
153 */
154 virtual bool IsValidTeam(int Team);
155 virtual const char *GetTeamName(int Team);
156 virtual int GetAutoTeam(int NotThisId);
157 virtual bool CanJoinTeam(int Team, int NotThisId, char *pErrorReason, int ErrorReasonSize);
158
159 CClientMask GetMaskForPlayerWorldEvent(int Asker, int ExceptID = -1);
160
161 bool IsTeamPlay() const { return m_GameFlags & GAMEFLAG_TEAMS; }
162 // DDRace
163
164 std::optional<float> m_CurrentRecord;
165 CGameTeams &Teams() { return m_Teams; }
166 std::shared_ptr<CScoreLoadBestTimeResult> m_pLoadBestTimeResult;
167};
168
169#endif
170