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