home *** CD-ROM | disk | FTP | other *** search
/ Gambler 19 / GAMBLERCD19.BIN / UTILS / 3D / BRONIE / DUAL_LAU.ZIP / src / g_main.c < prev    next >
C/C++ Source or Header  |  1997-11-26  |  6KB  |  345 lines

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