|
|
1.1 root 1:
2: #include "g_local.h"
3:
4: game_locals_t game;
5: level_locals_t level;
6: game_import_t gi;
7: game_export_t globals;
8: spawn_temp_t st;
9:
10: int sm_meat_index;
11: int snd_fry;
12: int meansOfDeath;
13:
14: edict_t *g_edicts;
15:
16: cvar_t *deathmatch;
17: cvar_t *coop;
18: cvar_t *dmflags;
19: cvar_t *skill;
20: cvar_t *fraglimit;
21: cvar_t *timelimit;
22: cvar_t *password;
23: cvar_t *maxclients;
24: cvar_t *maxentities;
25: cvar_t *g_select_empty;
26: cvar_t *dedicated;
27:
1.1.1.2 ! root 28: cvar_t *filterban;
! 29:
1.1 root 30: cvar_t *sv_maxvelocity;
31: cvar_t *sv_gravity;
32:
33: cvar_t *sv_rollspeed;
34: cvar_t *sv_rollangle;
35: cvar_t *gun_x;
36: cvar_t *gun_y;
37: cvar_t *gun_z;
38:
39: cvar_t *run_pitch;
40: cvar_t *run_roll;
41: cvar_t *bob_up;
42: cvar_t *bob_pitch;
43: cvar_t *bob_roll;
44:
45: cvar_t *sv_cheats;
46:
1.1.1.2 ! root 47: cvar_t *flood_msgs;
! 48: cvar_t *flood_persecond;
! 49: cvar_t *flood_waitdelay;
! 50:
1.1 root 51: void SpawnEntities (char *mapname, char *entities, char *spawnpoint);
52: void ClientThink (edict_t *ent, usercmd_t *cmd);
53: qboolean ClientConnect (edict_t *ent, char *userinfo);
54: void ClientUserinfoChanged (edict_t *ent, char *userinfo);
55: void ClientDisconnect (edict_t *ent);
56: void ClientBegin (edict_t *ent);
57: void ClientCommand (edict_t *ent);
58: void RunEntity (edict_t *ent);
59: void WriteGame (char *filename, qboolean autosave);
60: void ReadGame (char *filename);
61: void WriteLevel (char *filename);
62: void ReadLevel (char *filename);
63: void InitGame (void);
64: void G_RunFrame (void);
65:
66:
67: //===================================================================
68:
69:
70: void ShutdownGame (void)
71: {
72: gi.dprintf ("==== ShutdownGame ====\n");
73:
74: gi.FreeTags (TAG_LEVEL);
75: gi.FreeTags (TAG_GAME);
76: }
77:
78:
79: /*
80: =================
81: GetGameAPI
82:
83: Returns a pointer to the structure with all entry points
84: and global variables
85: =================
86: */
87: game_export_t *GetGameAPI (game_import_t *import)
88: {
89: gi = *import;
90:
91: globals.apiversion = GAME_API_VERSION;
92: globals.Init = InitGame;
93: globals.Shutdown = ShutdownGame;
94: globals.SpawnEntities = SpawnEntities;
95:
96: globals.WriteGame = WriteGame;
97: globals.ReadGame = ReadGame;
98: globals.WriteLevel = WriteLevel;
99: globals.ReadLevel = ReadLevel;
100:
101: globals.ClientThink = ClientThink;
102: globals.ClientConnect = ClientConnect;
103: globals.ClientUserinfoChanged = ClientUserinfoChanged;
104: globals.ClientDisconnect = ClientDisconnect;
105: globals.ClientBegin = ClientBegin;
106: globals.ClientCommand = ClientCommand;
107:
108: globals.RunFrame = G_RunFrame;
109:
110: globals.ServerCommand = ServerCommand;
111:
112: globals.edict_size = sizeof(edict_t);
113:
114: return &globals;
115: }
116:
117: #ifndef GAME_HARD_LINKED
118: // this is only here so the functions in q_shared.c and q_shwin.c can link
119: void Sys_Error (char *error, ...)
120: {
121: va_list argptr;
122: char text[1024];
123:
124: va_start (argptr, error);
125: vsprintf (text, error, argptr);
126: va_end (argptr);
127:
128: gi.error (ERR_FATAL, "%s", text);
129: }
130:
131: void Com_Printf (char *msg, ...)
132: {
133: va_list argptr;
134: char text[1024];
135:
136: va_start (argptr, msg);
137: vsprintf (text, msg, argptr);
138: va_end (argptr);
139:
140: gi.dprintf ("%s", text);
141: }
142:
143: #endif
144:
145: //======================================================================
146:
147:
148: /*
149: =================
150: ClientEndServerFrames
151: =================
152: */
153: void ClientEndServerFrames (void)
154: {
155: int i;
156: edict_t *ent;
157:
158: // calc the player views now that all pushing
159: // and damage has been added
160: for (i=0 ; i<maxclients->value ; i++)
161: {
162: ent = g_edicts + 1 + i;
163: if (!ent->inuse || !ent->client)
164: continue;
165: ClientEndServerFrame (ent);
166: }
167:
168: }
169:
170: /*
171: =================
172: EndDMLevel
173:
174: The timelimit or fraglimit has been exceeded
175: =================
176: */
177: void EndDMLevel (void)
178: {
179: edict_t *ent;
180:
181: // stay on same level flag
182: if ((int)dmflags->value & DF_SAME_LEVEL)
183: {
184: ent = G_Spawn ();
185: ent->classname = "target_changelevel";
186: ent->map = level.mapname;
187: }
188: else if (level.nextmap[0])
189: { // go to a specific map
190: ent = G_Spawn ();
191: ent->classname = "target_changelevel";
192: ent->map = level.nextmap;
193: }
194: else
195: { // search for a changeleve
196: ent = G_Find (NULL, FOFS(classname), "target_changelevel");
197: if (!ent)
198: { // the map designer didn't include a changelevel,
199: // so create a fake ent that goes back to the same level
200: ent = G_Spawn ();
201: ent->classname = "target_changelevel";
202: ent->map = level.mapname;
203: }
204: }
205:
206: BeginIntermission (ent);
207: }
208:
209: /*
210: =================
211: CheckDMRules
212: =================
213: */
214: void CheckDMRules (void)
215: {
216: int i;
217: gclient_t *cl;
218:
219: if (level.intermissiontime)
220: return;
221:
222: if (!deathmatch->value)
223: return;
224:
225: if (timelimit->value)
226: {
227: if (level.time >= timelimit->value*60)
228: {
229: gi.bprintf (PRINT_HIGH, "Timelimit hit.\n");
230: EndDMLevel ();
231: return;
232: }
233: }
234:
235: if (fraglimit->value)
236: {
237: for (i=0 ; i<maxclients->value ; i++)
238: {
239: cl = game.clients + i;
240: if (!g_edicts[i+1].inuse)
241: continue;
242:
243: if (cl->resp.score >= fraglimit->value)
244: {
245: gi.bprintf (PRINT_HIGH, "Fraglimit hit.\n");
246: EndDMLevel ();
247: return;
248: }
249: }
250: }
251: }
252:
253:
254: /*
255: =============
256: ExitLevel
257: =============
258: */
259: void ExitLevel (void)
260: {
261: int i;
262: edict_t *ent;
263: char command [256];
264:
265: Com_sprintf (command, sizeof(command), "gamemap \"%s\"\n", level.changemap);
266: gi.AddCommandString (command);
267: level.changemap = NULL;
268: level.exitintermission = 0;
269: level.intermissiontime = 0;
270: ClientEndServerFrames ();
271:
272: // clear some things before going to next level
273: for (i=0 ; i<maxclients->value ; i++)
274: {
275: ent = g_edicts + 1 + i;
276: if (!ent->inuse)
277: continue;
278: if (ent->health > ent->client->pers.max_health)
279: ent->health = ent->client->pers.max_health;
280: }
281:
282: }
283:
284: /*
285: ================
286: G_RunFrame
287:
288: Advances the world by 0.1 seconds
289: ================
290: */
291: void G_RunFrame (void)
292: {
293: int i;
294: edict_t *ent;
295:
296: level.framenum++;
297: level.time = level.framenum*FRAMETIME;
298:
299: // choose a client for monsters to target this frame
300: AI_SetSightClient ();
301:
302: // exit intermissions
303:
304: if (level.exitintermission)
305: {
306: ExitLevel ();
307: return;
308: }
309:
310: //
311: // treat each object in turn
312: // even the world gets a chance to think
313: //
314: ent = &g_edicts[0];
315: for (i=0 ; i<globals.num_edicts ; i++, ent++)
316: {
317: if (!ent->inuse)
318: continue;
319:
320: level.current_entity = ent;
321:
322: VectorCopy (ent->s.origin, ent->s.old_origin);
323:
324: // if the ground entity moved, make sure we are still on it
325: if ((ent->groundentity) && (ent->groundentity->linkcount != ent->groundentity_linkcount))
326: {
327: ent->groundentity = NULL;
328: if ( !(ent->flags & (FL_SWIM|FL_FLY)) && (ent->svflags & SVF_MONSTER) )
329: {
330: M_CheckGround (ent);
331: }
332: }
333:
334: if (i > 0 && i <= maxclients->value)
335: {
336: ClientBeginServerFrame (ent);
337: continue;
338: }
339:
340: G_RunEntity (ent);
341: }
342:
343: // see if it is time to end a deathmatch
344: CheckDMRules ();
345:
346: // build the playerstate_t structures for all players
347: ClientEndServerFrames ();
348: }
349:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.