1 /**
2  * @file
3  * @brief Local definitions for game module
4  */
5 
6 /*
7 All original material Copyright (C) 2002-2013 UFO: Alien Invasion.
8 
9 Original file from Quake 2 v3.21: quake2-2.31/game/g_local.h
10 Copyright (C) 1997-2001 Id Software, Inc.
11 
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 as published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
16 
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 
21 See the GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26 
27 */
28 
29 #pragma once
30 
31 #include "q_shared.h"
32 #include "inventory.h"				/* for InventoryInterface in game_locals_t */
33 #include "../shared/infostring.h"
34 #include "lua/lua.h"
35 
36 /** no gettext support for game lib - but we must be able to mark the strings */
37 #define _(String) String
38 #define ngettext(x, y, cnt) x
39 
40 /** @note define GAME_INCLUDE so that game.h does not define the
41  * short, server-visible player_t and Edict structures,
42  * because we define the full size ones in this file */
43 #define	GAME_INCLUDE
44 #include "game.h"
45 
46 /** the "gameversion" client command will print this plus compile date */
47 #define	GAMEVERSION	"baseufo"
48 
49 #define MAX_SPOT_DIST_CAMERA	768
50 #define MAX_SPOT_DIST	4096
51 
52 /** server is running at 10 fps */
53 #define	SERVER_FRAME_SECONDS		0.1
54 
55 /** memory tags to allow dynamic memory to be cleaned up */
56 #define	TAG_GAME	765			/* clear when unloading the game library */
57 #define	TAG_LEVEL	766			/* clear when loading a new level */
58 
59 #define INVDEF(containerID) (&gi.csi->ids[(containerID)])
60 
61 #define G_FreeTags(tag) gi.FreeTags((tag), __FILE__, __LINE__)
62 #define G_TagMalloc(size, tag) gi.TagMalloc((size), (tag), __FILE__, __LINE__)
63 #define G_MemFree(ptr) gi.TagFree((ptr), __FILE__, __LINE__)
64 
65 /** @brief this structure is left intact through an entire game
66  * it should be initialized at game library load time */
67 typedef struct game_locals_s {
68 	Player *players;			/* [maxplayers] */
69 
70 	/* store latched cvars here that we want to get at often */
71 	int sv_maxplayersperteam;
72 	int sv_maxentities;
73 
74 	InventoryInterface i;
75 } game_locals_t;
76 
77 /** @brief this structure is cleared as each map is entered */
78 typedef struct level_locals_s {
79 	int framenum;		/**< the current frame (10fps) */
80 	float time;			/**< seconds the game is running already
81 						 * calculated through framenum * SERVER_FRAME_SECONDS */
82 
83 	char mapname[MAX_QPATH];	/**< the server name (base1, etc) */
84 	char* mapEndCommand;
85 	bool routed;
86 	bool day;
87 	bool hurtAliens;
88 	bool nextMapSwitch;			/**< trigger the nextmap command when ending the match */
89 
90 	/* intermission state */
91 	float intermissionTime;		/**< the seconds to wait until the game will be closed.
92 								 * This value is relative to @c level.time
93 								 * @sa G_MatchDoEnd */
94 	int winningTeam;			/**< the team that won this match */
95 	float roundstartTime;		/**< the time the team started the turn */
96 
97 	/* turn statistics */
98 	int numplayers;
99 	int activeTeam;
100 	int teamOfs;
101 	int nextEndRound;
102 	int actualRound;		/**< the current running round counter */
103 
104 	pathing_t* pathingMap;	/**< This is where the data for TUS used to move and actor locations go */
105 
106 	int noRandomSpawn;		/**< can be set via worldspawn to force random spawn point order for each team */
107 	int noEquipment;		/**< can be set via worldspawn to force the players to collect their equipment in the map */
108 
109 	int initialAlienActorsSpawned;
110 	byte num_alive[MAX_TEAMS];				/**< the number of alive actors per team */
111 	byte num_spawned[MAX_TEAMS];			/**< the number of spawned actors per team */
112 	byte num_spawnpoints[MAX_TEAMS];		/**< the number of spawn points in the map per team */
113 	byte num_2x2spawnpoints[MAX_TEAMS]; 	/**< the number of spawn points for 2x2 units in the map per team */
114 	byte num_kills[MAX_TEAMS + 1][MAX_TEAMS];	/**< the amount of kills per team, the first dimension contains the attacker team, the second the victim team */
115 	byte num_stuns[MAX_TEAMS + 1][MAX_TEAMS];	/**< the amount of stuns per team, the first dimension contains the attacker team, the second the victim team */
116 	Edict* ai_waypointList;
117 } level_locals_t;
118 
119 
120 extern game_locals_t game;
121 extern level_locals_t level;
122 extern game_import_t gi;
123 extern game_export_t globals;
124 
125 #define G_IsActor(ent)			((ent)->type == ET_ACTOR || (ent)->type == ET_ACTOR2x2)
126 #define G_IsActive(ent)			((ent)->active)
127 #define G_IsCamera(ent)			((ent)->type == ET_CAMERA)
128 #define G_IsActiveCamera(ent)	(G_IsCamera(ent) && G_IsActive(ent))
129 #define G_IsSmoke(ent)			((ent)->type == ET_SMOKE)
130 #define G_IsFire(ent)			((ent)->type == ET_FIRE)
131 #define G_IsTriggerNextMap(ent)	((ent)->type == ET_TRIGGER_NEXTMAP)
132 #define G_IsItem(ent)			((ent)->type == ET_ITEM)
133 #define G_IsDoor(ent)			((ent)->type == ET_DOOR || (ent)->type == ET_DOOR_SLIDING)
134 
135 #define G_IsBreakable(ent)		((ent)->flags & FL_DESTROYABLE)
136 #define G_IsBrushModel(ent)		((ent)->type == ET_BREAKABLE || G_IsDoor(ent) || (ent)->type == ET_ROTATING)
137 /** @note Every none solid (none-bmodel) edict that is visible for the client */
138 #define G_IsVisibleOnBattlefield(ent)	(G_IsActor((ent)) || G_IsItem(ent) || G_IsCamera(ent) || (ent)->type == ET_PARTICLE)
139 #define G_IsAI(ent)				((ent)->getPlayer().pers.ai)
140 #define G_IsAIPlayer(player)	((player)->pers.ai)
141 #define G_TeamToVisMask(team)	(1 << (team))
142 #define G_IsVisibleForTeam(ent, team) ((ent)->visflags & G_TeamToVisMask(team))
143 #define G_IsMultiPlayer()		(sv_maxclients->integer > 1)
144 #define G_IsSinglePlayer()		(!G_IsMultiPlayer())
145 /** @note check for actor first */
146 #define G_IsCivilian(ent)		((ent)->team == TEAM_CIVILIAN)
147 #define G_IsAlien(ent)			((ent)->team == TEAM_ALIEN)
148 #define G_IsBlockingMovementActor(ent)	(((ent)->type == ET_ACTOR && !G_IsDead(ent)) || ent->type == ET_ACTOR2x2)
149 
150 extern cvar_t* sv_maxentities;
151 extern cvar_t* password;
152 extern cvar_t* sv_needpass;
153 extern cvar_t* sv_dedicated;
154 extern cvar_t* developer;
155 
156 extern cvar_t* logstats;
157 extern FILE *logstatsfile;
158 
159 extern cvar_t* sv_filterban;
160 
161 extern cvar_t* sv_maxvelocity;
162 
163 extern cvar_t* sv_maxclients;
164 extern cvar_t* sv_shot_origin;
165 extern cvar_t* sv_hurtaliens;
166 extern cvar_t* sv_maxplayersperteam;
167 extern cvar_t* sv_maxsoldiersperteam;
168 extern cvar_t* sv_maxsoldiersperplayer;
169 extern cvar_t* sv_enablemorale;
170 extern cvar_t* sv_roundtimelimit;
171 
172 extern cvar_t* sv_maxteams;
173 
174 extern cvar_t* sv_ai;
175 extern cvar_t* sv_teamplay;
176 
177 extern cvar_t* ai_alienteam;
178 extern cvar_t* ai_civilianteam;
179 extern cvar_t* ai_equipment;
180 extern cvar_t* ai_singleplayeraliens;
181 extern cvar_t* ai_numcivilians;
182 extern cvar_t* ai_multiplayeraliens;
183 
184 extern cvar_t* mob_death;
185 extern cvar_t* mob_wound;
186 extern cvar_t* mof_watching;
187 extern cvar_t* mof_teamkill;
188 extern cvar_t* mof_civilian;
189 extern cvar_t* mof_enemy;
190 extern cvar_t* mor_pain;
191 
192 /*everyone gets this times morale damage */
193 extern cvar_t* mor_default;
194 
195 /* at this distance the following two get halfed (exponential scale) */
196 extern cvar_t* mor_distance;
197 
198 /* at this distance the following two get halfed (exponential scale) */
199 extern cvar_t* mor_victim;
200 
201 /* at this distance the following two get halfed (exponential scale) */
202 extern cvar_t* mor_attacker;
203 
204 /* how much the morale depends on the size of the damaged team */
205 extern cvar_t* mon_teamfactor;
206 
207 extern cvar_t* mor_regeneration;
208 extern cvar_t* mor_shaken;
209 extern cvar_t* mor_panic;
210 extern cvar_t* mor_brave;
211 
212 extern cvar_t* m_sanity;
213 extern cvar_t* m_rage;
214 extern cvar_t* m_rage_stop;
215 extern cvar_t* m_panic_stop;
216 
217 extern cvar_t* g_endlessaliens;
218 extern cvar_t* g_ailua;
219 extern cvar_t* g_aihumans;
220 extern cvar_t* g_aidebug;
221 extern cvar_t* g_drawtraces;
222 extern cvar_t* g_nodamage;
223 extern cvar_t* g_notu;
224 extern cvar_t* g_nospawn;
225 extern cvar_t* g_actorspeed;
226 extern cvar_t* g_lastseen;
227 
228 extern cvar_t* flood_msgs;
229 extern cvar_t* flood_persecond;
230 extern cvar_t* flood_waitdelay;
231 
232 extern cvar_t* g_difficulty;
233 
234 /* g_camera */
235 void G_InitCamera(Edict* ent, camera_type_t cameraType, float angle, bool rotate);
236 Edict* G_SpawnCamera(const vec3_t origin, int team, camera_type_t cameraType);
237 
238 /* g_cmds.c */
239 void G_ClientCommand(Player &player);
240 #ifdef DEBUG
241 void G_InvList_f(const Player &player);
242 #endif
243 
244 /* g_morale */
245 void G_MoraleBehaviour(int team);
246 #define MORALE_RANDOM( mod )	( (mod) * (1.0 + 0.3*crand()) )
247 
248 /* g_round */
249 void G_CheckForceEndRound(void);
250 void G_ClientEndRound(Player &player);
251 
252 /* g_stats */
253 void G_SendStats(Edict &ent);
254 void G_SendPlayerStats(const Player &player);
255 
256 /* g_svcmds.c */
257 void G_ServerCommand(void);
258 bool SV_FilterPacket(const char* from);
259 
260 /** Functions to handle single edicts, trying to encapsulate edict->pos in the first place. */
261 void G_EdictCalcOrigin(Edict* ent);
262 void G_EdictSetOrigin(Edict* ent, const pos3_t newPos);
263 bool G_EdictPosIsSameAs(const Edict* ent, const pos3_t cmpPos);
264 
265 #include "g_events.h"
266 
267 /*============================================================================ */
268 
269 /** @brief e.g. used for breakable objects */
270 typedef enum {
271 	MAT_GLASS,		/* default */
272 	MAT_METAL,
273 	MAT_ELECTRICAL,
274 	MAT_WOOD,
275 
276 	MAT_MAX
277 } edictMaterial_t;
278 
279 /** @brief actor movement */
280 typedef struct moveinfo_s {
281 	byte		steps;
282 } moveinfo_t;
283 
284 /**
285  * @brief If an edict is destroyable (like ET_BREAKABLE, ET_DOOR [if health set]
286  * or maybe a ET_MISSION [if health set])
287  * @note e.g. misc_mission, func_breakable, func_door
288  * @note If you mark an edict as breakable, you have to provide a destroy callback, too
289  */
290 #define FL_DESTROYABLE	0x00000004
291 /**
292  * @brief not the first on the team
293  * @sa groupMaster and groupChain
294  */
295 #define FL_GROUPSLAVE	0x00000008
296 /**
297  * @brief Edict flag to indicate, that the edict can be used in the context of a client action
298  */
299 #define FL_CLIENTACTION	0x00000010
300 /**
301  * @brief Trigger the edict at spawn.
302  */
303 #define FL_TRIGGERED	0x00000100
304 
305 /** @brief Artificial intelligence of a character */
306 typedef struct AI_s {
307 	char type[MAX_QPATH];	/**< Lua file used by the AI. */
308 	char subtype[MAX_VAR];	/**< Subtype to be used by AI. */
309 	lua_State* L;			/**< The lua state used by the AI. */
310 } AI_t;
311 
312 typedef struct camera_edict_data_s {
313 	camera_type_t cameraType;
314 	bool rotate;
315 } camera_edict_data_t;
316 
317 #include "g_edict.h"
318