1
2 #include "g_local.h"
3 #include "bot.h"
4
5 game_locals_t game;
6 level_locals_t level;
7 game_import_t gi;
8 game_export_t globals;
9 spawn_temp_t st;
10
11 int sm_meat_index;
12 int snd_fry;
13 int meansOfDeath;
14
15 edict_t *g_edicts;
16
17 cvar_t *deathmatch;
18 cvar_t *coop;
19 cvar_t *dmflags;
20 cvar_t *skill;
21 cvar_t *fraglimit;
22 cvar_t *timelimit;
23
24 cvar_t *filterban;
25
26 //ZOID
27 cvar_t *capturelimit;
28 //ZOID
29 cvar_t *password;
30 cvar_t *spectator_password;
31 cvar_t *maxclients;
32 cvar_t *maxspectators;
33 cvar_t *maxentities;
34 cvar_t *g_select_empty;
35 cvar_t *dedicated;
36
37 cvar_t *sv_maxvelocity;
38 cvar_t *sv_gravity;
39
40 cvar_t *sv_rollspeed;
41 cvar_t *sv_rollangle;
42 cvar_t *gun_x;
43 cvar_t *gun_y;
44 cvar_t *gun_z;
45
46 cvar_t *run_pitch;
47 cvar_t *run_roll;
48 cvar_t *bob_up;
49 cvar_t *bob_pitch;
50 cvar_t *bob_roll;
51
52 cvar_t *sv_cheats;
53
54 //ponpoko
55 cvar_t *gamepath;
56 cvar_t *chedit;
57 cvar_t *vwep;
58 cvar_t *maplist;
59 cvar_t *botlist;
60 cvar_t *autospawn;
61 cvar_t *zigmode;
62 float spawncycle;
63 float ctfjob_update;
64 //ponpoko
65 cvar_t *botchat;
66
67 void SpawnEntities (char *mapname, char *entities, char *spawnpoint);
68 void ClientThink (edict_t *ent, usercmd_t *cmd);
69 qboolean ClientConnect (edict_t *ent, char *userinfo, qboolean loadgame);
70 void ClientUserinfoChanged (edict_t *ent, char *userinfo);
71 void ClientDisconnect (edict_t *ent);
72 void ClientBegin (edict_t *ent, qboolean loadgame);
73 void ClientCommand (edict_t *ent);
74 void RunEntity (edict_t *ent);
75 void WriteGame (char *filename);
76 void ReadGame (char *filename);
77 void WriteLevel (char *filename);
78 void ReadLevel (char *filename);
79 void InitGame (void);
80 void G_RunFrame (void);
81
82 void SetBotFlag1(edict_t *ent); //�`�[��1�̊�
83 void SetBotFlag2(edict_t *ent); //�`�[��2�̊�
84
85 //===================================================================
86
87
88 /*
89 =================
90 GetGameAPI
91
92 Returns a pointer to the structure with all entry points
93 and global variables
94 =================
95 */
ShutdownGame(void)96 void ShutdownGame (void)
97 {
98 gi.dprintf ("==== ShutdownGame ====\n");
99
100 // Bot_LevelChange();
101
102 gi.FreeTags (TAG_LEVEL);
103 gi.FreeTags (TAG_GAME);
104 SetBotFlag1(NULL);
105 SetBotFlag2(NULL);
106 }
107
108 //void Dummy (void) {};
109
GetGameAPI(game_import_t * import)110 game_export_t *GetGameAPI (game_import_t *import)
111 {
112 gi = *import;
113
114 globals.apiversion = GAME_API_VERSION;
115 globals.Init = InitGame;
116 globals.Shutdown = ShutdownGame;
117 globals.SpawnEntities = SpawnEntities;
118
119 globals.WriteGame = WriteGame;
120 globals.ReadGame = ReadGame;
121 globals.WriteLevel = WriteLevel;
122 globals.ReadLevel = ReadLevel;
123
124 globals.ClientThink = ClientThink;
125 globals.ClientConnect = ClientConnect;
126 globals.ClientUserinfoChanged = ClientUserinfoChanged;
127 globals.ClientDisconnect = ClientDisconnect;
128 globals.ClientBegin = ClientBegin;
129 globals.ClientCommand = ClientCommand;
130
131 globals.RunFrame = G_RunFrame;
132
133 globals.ServerCommand = ServerCommand;
134
135 globals.edict_size = sizeof(edict_t);
136
137 return &globals;
138 }
139
140 #ifndef GAME_HARD_LINKED
141 // this is only here so the functions in q_shared.c and q_shwin.c can link
Sys_Error(char * error,...)142 void Sys_Error (char *error, ...)
143 {
144 va_list argptr;
145 char text[1024];
146
147 va_start (argptr, error);
148 vsprintf (text, error, argptr);
149 va_end (argptr);
150
151 gi.error (ERR_FATAL, "%s", text);
152 }
153
Com_Printf(char * msg,...)154 void Com_Printf (char *msg, ...)
155 {
156 va_list argptr;
157 char text[1024];
158
159 va_start (argptr, msg);
160 vsprintf (text, msg, argptr);
161 va_end (argptr);
162
163 gi.dprintf ("%s", text);
164 }
165
166 #endif
167
168 //======================================================================
169
170
171 /*
172 =================
173 ClientEndServerFrames
174 =================
175 */
ClientEndServerFrames(void)176 void ClientEndServerFrames (void)
177 {
178 int i;
179 edict_t *ent;
180
181 // calc the player views now that all pushing
182 // and damage has been added
183 for (i=0 ; i<maxclients->value ; i++)
184 {
185 ent = g_edicts + 1 + i;
186 if (!ent->inuse || !ent->client)
187 continue;
188 if(!(ent->svflags & SVF_MONSTER))
189 ClientEndServerFrame (ent);
190 }
191
192 }
193
194
195 /*
196 =================
197 GetNextMap
198
199 get next map's file name
200 =================
201 */
Get_NextMap()202 void Get_NextMap()
203 {
204 FILE *fp;
205 qboolean firstflag = false;
206 char Buff[MAX_QPATH];
207 char top[MAX_QPATH];
208 char nextmap[MAX_QPATH];
209 int i;
210
211 if(!maplist->string) return;
212
213 sprintf(Buff,"%s/3ZBMaps.lst",gamepath->string);
214
215 fp = fopen(Buff,"r");
216 if(fp == NULL) return;
217
218 //search section
219 while(1)
220 {
221 if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto NONEXTMAP;
222
223 if(Buff[0] != '[') continue;
224
225 i = 0;
226 while(1)
227 {
228 if(Buff[i] == ']') Buff[i] = 0;
229
230 if(Buff[i] == 0) break;
231
232 if(++i >= sizeof(Buff))
233 {
234 Buff[i - 1] = 0;
235 break;
236 }
237 }
238 //compare map section name
239 if(Q_stricmp (&Buff[1], maplist->string) == 0) break;
240 }
241
242 //search current mapname
243 while(1)
244 {
245 if(fgets( Buff, sizeof(Buff), fp ) == NULL) goto NONEXTMAP;
246
247 if(Buff[0] == '[')
248 {
249 if( firstflag )
250 {
251 strcpy(nextmap,top);
252 goto SETNEXTMAP;
253 }
254 else goto NONEXTMAP;
255 }
256
257 if(Buff[0] == '\n') continue;
258
259 sscanf(Buff,"%s",nextmap);
260
261 if(!firstflag)
262 {
263 firstflag = true;
264 strcpy(top,nextmap);
265 }
266
267 if(Q_stricmp (level.mapname, nextmap) == 0) break;
268 }
269
270 //search nextmap
271 while(1)
272 {
273 if(fgets( Buff, sizeof(Buff), fp ) == NULL)
274 {
275 if( firstflag )
276 {
277 strcpy(nextmap,top);
278 goto SETNEXTMAP;
279 }
280 else goto NONEXTMAP;
281 }
282
283 if(Buff[0] == '[')
284 {
285 if( firstflag )
286 {
287 strcpy(nextmap,top);
288 goto SETNEXTMAP;
289 }
290 else goto NONEXTMAP;
291 }
292
293 if(Buff[0] == '\n') continue;
294
295 sscanf(Buff,"%s",nextmap);
296 break;
297 }
298 SETNEXTMAP:
299
300 strcpy(level.nextmap,nextmap);
301
302 NONEXTMAP:
303 fclose(fp);
304
305 }
306 /*
307 =================
308 EndDMLevel
309
310 The timelimit or fraglimit has been exceeded
311 =================
312 */
EndDMLevel(void)313 void EndDMLevel (void)
314 {
315 edict_t *ent;
316
317 Get_NextMap();
318
319 // stay on same level flag
320 if ((int)dmflags->value & DF_SAME_LEVEL)
321 {
322 ent = G_Spawn ();
323 ent->classname = "target_changelevel";
324 ent->map = level.mapname;
325 }
326 else if (level.nextmap)
327 { // go to a specific map
328 ent = G_Spawn ();
329 ent->classname = "target_changelevel";
330 ent->map = level.nextmap;
331 }
332 else
333 { // search for a changeleve
334 ent = G_Find (NULL, FOFS(classname), "target_changelevel");
335 if (!ent)
336 { // the map designer didn't include a changelevel,
337 // so create a fake ent that goes back to the same level
338 ent = G_Spawn ();
339 ent->classname = "target_changelevel";
340 ent->map = level.mapname;
341 }
342 }
343
344 BeginIntermission (ent);
345
346 //PONKO
347 Bot_LevelChange();
348 //PONKO
349 }
350
351 /*
352 =================
353 CheckNeedPass
354 =================
355 */
CheckNeedPass(void)356 void CheckNeedPass (void)
357 {
358 int need;
359
360 // if password or spectator_password has changed, update needpass
361 // as needed
362 if (password->modified || spectator_password->modified)
363 {
364 password->modified = spectator_password->modified = false;
365
366 need = 0;
367
368 if (*password->string && Q_stricmp(password->string, "none"))
369 need |= 1;
370 if (*spectator_password->string && Q_stricmp(spectator_password->string, "none"))
371 need |= 2;
372
373 gi.cvar_set("needpass", va("%d", need));
374 }
375 }
376
377 /*
378 =================
379 CheckDMRules
380 =================
381 */
CheckDMRules(void)382 void CheckDMRules (void)
383 {
384 int i;
385 gclient_t *cl;
386
387 if (level.intermissiontime)
388 return;
389
390 if (!deathmatch->value)
391 return;
392
393 if (timelimit->value)
394 {
395 if (level.time >= timelimit->value*60)
396 {
397 gi.bprintf (PRINT_HIGH, "Timelimit hit.\n");
398 EndDMLevel ();
399 return;
400 }
401 }
402
403 if (fraglimit->value)
404 {
405 //ZOID
406 if (ctf->value) {
407 if (CTFCheckRules()) {
408 EndDMLevel ();
409 }
410 }
411 //ZOID
412 for (i=0 ; i<maxclients->value ; i++)
413 {
414 cl = game.clients + i;
415 if (!g_edicts[i+1].inuse)
416 continue;
417
418 if (cl->resp.score >= fraglimit->value)
419 {
420 gi.bprintf (PRINT_HIGH, "Fraglimit hit.\n");
421 EndDMLevel ();
422 return;
423 }
424 }
425 }
426 }
427
428
429 /*
430 =============
431 ExitLevel
432 =============
433 */
ExitLevel(void)434 void ExitLevel (void)
435 {
436 int i;
437 edict_t *ent;
438 char command [256];
439
440 Com_sprintf (command, sizeof(command), "gamemap \"%s\"\n", level.changemap);
441 gi.AddCommandString (command);
442 level.changemap = NULL;
443 level.exitintermission = 0;
444 level.intermissiontime = 0;
445 ClientEndServerFrames ();
446
447 // clear some things before going to next level
448 for (i=0 ; i<maxclients->value ; i++)
449 {
450 ent = g_edicts + 1 + i;
451 if (!ent->inuse)
452 continue;
453 if (ent->health > ent->client->pers.max_health)
454 ent->health = ent->client->pers.max_health;
455 }
456
457 SetBotFlag1(NULL);
458 SetBotFlag2(NULL);
459
460 //ZOID
461 CTFInit();
462 //ZOID
463 }
464
465 /*
466 ================
467 G_RunFrame
468
469 Advances the world by 0.1 seconds
470 ================
471 */
472
473 void G_InitEdict (edict_t *e);
474
G_RunFrame(void)475 void G_RunFrame (void)
476 {
477 int i,j;
478 static int ofs;
479 static float next_fragadd = 0;
480 edict_t *ent;
481
482 vec3_t v,vv;
483 qboolean haveflag;
484 gitem_t *item;
485
486 level.framenum++;
487 level.time = level.framenum*FRAMETIME;
488
489 // choose a client for monsters to target this frame
490 // AI_SetSightClient ();
491
492 // exit intermissions
493
494 if (level.exitintermission)
495 {
496 ExitLevel ();
497 return;
498 }
499
500 //
501 // Bot Spawning
502 //
503 if(SpawnWaitingBots && !level.intermissiontime)
504 {
505 if(spawncycle < level.time)
506 {
507 Bot_SpawnCall();
508 spawncycle = level.time + FRAMETIME * 10 + 0.01 * SpawnWaitingBots;
509 }
510 }
511 else
512 {
513 if(spawncycle < level.time) spawncycle = level.time + FRAMETIME * 10;
514 }
515 //
516 // treat each object in turn
517 // even the world gets a chance to think
518 //
519 haveflag = false;
520 ent = &g_edicts[0];
521 for (i=0 ; i<globals.num_edicts ; i++, ent++)
522 {
523 if (!ent->inuse)
524 continue;
525
526 level.current_entity = ent;
527
528 VectorCopy (ent->s.origin, ent->s.old_origin);
529
530 // if the ground entity moved, make sure we are still on it
531 if ((ent->groundentity) && (ent->groundentity->linkcount != ent->groundentity_linkcount))
532 {
533 ent->groundentity = NULL;
534 if ( !(ent->flags & (FL_SWIM|FL_FLY)) && (ent->svflags & SVF_MONSTER) )
535 {
536 M_CheckGround (ent);
537 }
538 }
539
540 //ctf job assign
541 if(ctf->value)
542 {
543 if(ctfjob_update < level.time)
544 {
545 //gi.bprintf(PRINT_HIGH,"Assigned!!!\n");
546 CTFJobAssign();
547 ctfjob_update = level.time + FRAMETIME * 2;
548 }
549 }
550 //////////���̃X�R�A�`�F�b�N
551 if(zigmode->value == 1)
552 {
553 if(next_fragadd < level.time)
554 {
555 if(i > 0 && i <= maxclients->value && g_edicts[i].client)
556 {
557 if(g_edicts[i].client->pers.inventory[ITEM_INDEX(zflag_item)])
558 {
559 zflag_ent = NULL;
560 haveflag = true;
561 gi.sound(ent, CHAN_VOICE, gi.soundindex("misc/secret.wav"), 1, ATTN_NORM, 0);
562 if (!((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
563 g_edicts[i].client->resp.score += 1;
564 else
565 {
566 //���������Ă�ƃt���b�O��
567 for ( j = 1 ; j <= maxclients->value ; j++)
568 {
569 if(g_edicts[j].inuse)
570 {
571 if(OnSameTeam(&g_edicts[i],&g_edicts[j]))
572 g_edicts[j].client->resp.score += 1;
573 }
574 }
575 }
576 }
577 }
578 if(zflag_ent != NULL)
579 {
580 if(!zflag_ent->inuse)
581 {
582 // item = FindItem("Zig Flag");
583 SelectSpawnPoint (ent, v, vv);
584 // VectorCopy (v, ent->s.origin);
585 if(ZIGDrop_Flag(ent,zflag_item))
586 {
587 VectorCopy (v, zflag_ent->s.origin);
588 }
589 }
590 }
591 }
592 }
593 /////////////
594 if (i > 0 && i <= maxclients->value && !(ent->svflags & SVF_MONSTER))
595 {
596 ClientBeginServerFrame (ent);
597 continue;
598 }
599
600 G_RunEntity (ent);
601 }
602
603 if(next_fragadd < level.time)
604 {
605 if(zflag_ent == NULL && !haveflag && !ctf->value
606 && zigmode->value == 1 && zigflag_spawn == 2)
607 {
608 SelectSpawnPoint (ent, v, vv);
609 //VectorCopy (v, ent->s.origin);
610 if(ZIGDrop_Flag(ent,zflag_item))
611 {
612 VectorCopy (v, zflag_ent->s.origin);
613 }
614 }
615
616 next_fragadd = level.time + FRAMETIME * 100;
617 }
618
619 // see if it is time to end a deathmatch
620 CheckDMRules ();
621
622 // see if needpass needs updated
623 CheckNeedPass ();
624
625 // build the playerstate_t structures for all players
626 ClientEndServerFrames ();
627 }
628
629