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