home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 March / ENTER.ISO / files / fwp-0.0.6-win32-installer.exe / Game.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-01-22  |  38.7 KB  |  1,192 lines

  1. #include "Game.h"
  2.  
  3. #include "Input.h"
  4. #include "System.h"
  5. #include "log.h"
  6. #include "GuiInfo.h"
  7. #include "RendererInfo.h"
  8. #include "Renderer.h"
  9. #include "Network.h"
  10. #include "Gui.h"
  11. #include "LightEffectsParticleClusters.h"
  12. #include "ArenaEffectsParticleClusters.h"
  13. #include "VehicleEffectsParticleClusters.h"
  14. #include "random.h"
  15. #include "Mech.h"
  16. #include "ModelHandler.h"
  17.  
  18. preloadedGameMedia_t Game::preloadedGameMedia;
  19. Camera Game::cam;
  20. Arena* Game::arena=NULL;
  21. arenaCycle_t Game::arenaCycle;
  22.  
  23. Shot* Game::shots[GAME_MAX_SHOTS];
  24. Vehicle* Game::vehicles[GAME_MAX_VEHICLES];
  25.  
  26. bool Game::initialized = false;
  27.  
  28.  
  29. bool Game::init(){
  30.     int i;
  31.  
  32.     if(initialized){
  33.         error("(in Game::init()): Game is already initialized.\n\n");
  34.         return false;
  35.     }
  36.  
  37.  
  38.     log("\n");
  39.     log("*********************\n");
  40.     log("*** Starting Game ***\n");
  41.     log("*********************\n");
  42.     log("\n");
  43.  
  44.  
  45.     info.cvar.game_arena->updateVar();
  46.     info.cvar.game_useArenaCycle->updateVar();
  47.     info.cvar.game_arenaCycleList->updateVar();
  48.     info.cvar.game_mode->updateVar();
  49.     info.cvar.game_enableFriendlyFire->updateVar();
  50.     info.cvar.game_ghostTime->updateVar();
  51.     info.cvar.game_clientGame->updateVar();
  52.     info.cvar.game_player_name->updateVar();
  53.     info.cvar.game_player_team->setVal(GAME_TEAM_SPECTATORS);    // always begin new game as spectator
  54.     info.cvar.game_player_team->updateVar();
  55.  
  56.     cam.setTarget(NULL);
  57.     
  58.     for(i=0;i<GAME_MAX_SHOTS;i++){
  59.         shots[i] = NULL;
  60.     }
  61.     for(i=0;i<GAME_MAX_VEHICLES;i++){
  62.         vehicles[i] = NULL;
  63.     }
  64.     
  65.     Gui::loadingMenu->open();
  66.     Gui::loadingMenu->updateStatusBar("starting game");
  67.  
  68.     if(info.var.clientGame){
  69.         log("Starting client game...\n");
  70.         Gui::loadingMenu->updateStatusBar("connecting...");
  71.         Gui::loadingMenu->updateHeading(Network::info.var.server_hostName);
  72.  
  73.         // init server
  74.         if(!Network::initServer()){
  75.             error("(in Game::init()): Couldn't initialize server.\n\n");
  76.             return false;
  77.         }
  78.  
  79.         // init client
  80.         if( !Network::initClient() ){
  81.             error("(in Game::init()): Couldn't initialize client.\n\n");
  82.             Network::shutdownServer();
  83.             return false;
  84.         }
  85.  
  86.         // connect and receive serverinfo
  87.         if( !Network::client->connect()){
  88.             error("(in Game::init()): Couldn't connect to server.\n\n");
  89.             Network::shutdownClient();
  90.             Network::shutdownServer();
  91.             return false;
  92.         }
  93.     }else{    // server game
  94.         log("Starting client-server game...\n");
  95.  
  96.         if( info.var.useArenaCycle ){
  97.             if( !initArenaCycle() ){
  98.                 error("(in Game::init()): Couldn't initialize arenacycle.\n\n");
  99.                 return false;
  100.             }
  101.         }
  102.  
  103.         // init server
  104.         if(!Network::initServer()){
  105.             error("(in Game::init()): Couldn't initialize server.\n\n");
  106.             return false;
  107.         }
  108.  
  109.         // init client
  110.         if( !Network::initClient() ){
  111.             error("(in Game::init()): Couldn't initialize client.\n\n");
  112.             Network::shutdownServer();
  113.             return false;
  114.         }
  115.  
  116.         // make loopback connection
  117.         if(!Network::makeLoopbackConnection()){
  118.             error("(in Game::init()): Couldn't make loopback connection.\n\n");
  119.             Network::shutdownClient();
  120.             Network::shutdownServer();
  121.             return false;
  122.         }
  123.     }
  124.  
  125.     log("\n");
  126.     log("\n");
  127.  
  128.     if(!File::exists(info.var.arena)){
  129.         error("(in Game::init()): Arena-File '%s' does not exist.\n\n", info.var.arena);
  130.         Network::shutdownClient();
  131.         Network::shutdownServer();
  132.         return false;
  133.     }
  134.  
  135.     Gui::loadingMenu->updateStatusBar("loading arena");
  136.     Gui::loadingMenu->updateSubHeading(Game::getModeName(info.var.mode));
  137.  
  138.     log("Loading arena...\n");
  139.     arena = new Arena(info.var.arena);
  140.     log("Arena '%s' loaded (%i spawnpoints, %i supplypads).\n", info.var.arena, arena->spawnpoints.size(), arena->supplypads.size());
  141.     log("\n");
  142.  
  143.     Gui::loadingMenu->updateStatusBar("loading media");
  144.  
  145.     log("Loading game media...\n");
  146.     if( !Game::initGameMedia() ){
  147.         error("(in Game::init()): Couldn't init game media.\n\n");
  148.         Network::shutdownClient();
  149.         Network::shutdownServer();
  150.         return false;
  151.     }
  152.     log("Game media loaded.\n");
  153.     log("\n");
  154.  
  155.     if(!Renderer::initParticleSystem()){
  156.         error("(in Game::init()): Couldn't init particle system.\n\n");
  157.         Network::shutdownClient();
  158.         Network::shutdownServer();
  159.         return false;
  160.     }
  161.  
  162.     if(!Gui::initHud()){
  163.         error("(in Game::init()): Couldn't init HUD.\n\n");
  164.         Renderer::shutdownParticleSystem();
  165.         Network::shutdownClient();
  166.         Network::shutdownServer();
  167.         return false;
  168.     }
  169.  
  170.     if(Sound::wasInit() && Sound::info.var.enabled && Sound::info.var.playMusic)
  171.         Sound::stopMusic();
  172.  
  173.     Gui::loadingMenu->close();
  174.  
  175.     Input::hideMouseCursor();
  176.     Input::grabInput();
  177.  
  178.     initialized = true;
  179.  
  180.     log("\n");
  181.     log("Game::init() finished. Entering mainloop...\n");
  182.     log("-- Press F1 for keyboard help --\n");
  183.     mainLoop();
  184.  
  185.     return true;    // never reached!
  186. }
  187.  
  188. bool Game::shutdown(){
  189.     int i;
  190.  
  191.     if(!initialized){
  192.         error("(in Game::shutdown()): Game is not initialized.\n\n");
  193.  
  194.         return false;
  195.     }
  196.  
  197.     log("\n");
  198.     log("====================\n");
  199.     log("=== Closing Game ===\n");
  200.     log("====================\n");
  201.     log("\n");
  202.  
  203.     Gui::shutdownHud();
  204.     Renderer::shutdownParticleSystem();
  205. //    Game::shutdownGameMedia();
  206.     Network::shutdownClient();
  207.     Network::shutdownServer();
  208.     if( !info.var.clientGame && info.var.useArenaCycle ){
  209.         shutdownArenaCycle();
  210.     }
  211.  
  212.     log("\n");
  213.     log("Deleting game media...\n");
  214.     Game::shutdownGameMedia();    // FIXME: Models mssen bei shutdownClient noch da sein!!!! (wg. numMeshes)
  215.  
  216.     log("Deleting arena...\n");
  217.     delete arena;
  218.  
  219.     log("Deleting shots and vehicles...\n");
  220.     for(i=0;i<GAME_MAX_SHOTS;i++){
  221.         if( shots[i] != NULL ){
  222.             delete shots[i];
  223.             shots[i] = NULL;
  224.         }
  225.     }
  226.     for(i=0;i<GAME_MAX_VEHICLES;i++){
  227.         if( vehicles[i] != NULL ){
  228.             delete vehicles[i];
  229.             vehicles[i] = NULL;
  230.         }
  231.     }
  232.  
  233.  
  234.     log("\n");
  235.     log("Game closed.\n");
  236.     
  237.     initialized = false;
  238.  
  239.     return true;
  240. }
  241.  
  242. bool Game::wasInit(){
  243.     return initialized;
  244. }
  245.  
  246.  
  247.  
  248. bool Game::registerCVarsAndCCmds(){
  249.     return info.registerCVarsAndCCmds();
  250. }
  251.  
  252. bool Game::unregisterCVarsAndCCmds(){
  253.     return info.unregisterCVarsAndCCmds();
  254. }
  255.  
  256. bool Game::initGameMedia(){
  257.     int i, j;
  258.  
  259.     preloadedGameMedia.supplyPadCylindersModel = new Model("arenas/shared/models/supply_pad_cylinders.model");
  260.     preloadedGameMedia.supplyPadImpulseSound = Sound::loadWAV("arenas/shared/sounds/supply_pad_impulse.wav");
  261.  
  262.     preloadedGameMedia.spawnEffectSpheresModel = new Model("vehicles/shared/models/spawn_effect_spheres.model");
  263.     preloadedGameMedia.spawnEffectSound = Sound::loadWAV("vehicles/shared/sounds/spawn_effect.wav");
  264.     preloadedGameMedia.shockwaveShader = new Shader("vehicles/shared/shaders/shockwave.shader");
  265.  
  266.     preloadedGameMedia.alleycatTorsoModel = new Model("vehicles/alleycat/alleycat_torso.model");
  267.     preloadedGameMedia.alleycatLegsModel = new Model("vehicles/alleycat/alleycat_legs.model");
  268.     preloadedGameMedia.alleycatLegsAnimator = new Animator("vehicles/alleycat/alleycat_legs.animator");
  269.  
  270.     preloadedGameMedia.dragonflyBodyModel = new Model("vehicles/dragonfly/dragonfly_body.model");
  271.     preloadedGameMedia.dragonflyJetsModel = new Model("vehicles/dragonfly/dragonfly_jets.model");
  272.     preloadedGameMedia.dragonflyJetsAnimator = new Animator("vehicles/dragonfly/dragonfly_jets.animator");
  273.  
  274.  
  275.     preloadedGameMedia.tinyExplosionShader = new Shader("weapons/shared/explosion_tiny.shader");
  276.     preloadedGameMedia.smallExplosionShader = new Shader("weapons/shared/explosion_small.shader");
  277.     preloadedGameMedia.mediumExplosionShader = new Shader("weapons/shared/explosion_medium.shader");
  278.     preloadedGameMedia.bigExplosionShader = new Shader("weapons/shared/explosion_big.shader");
  279.     preloadedGameMedia.smallSmokePuffShader = new Shader("weapons/shared/small_smoke_puff.shader");
  280.     preloadedGameMedia.tinyExplosionSound = Sound::loadWAV("weapons/shared/explosion_tiny.wav");
  281.     preloadedGameMedia.smallExplosionSound = Sound::loadWAV("weapons/shared/explosion_small.wav");
  282.     preloadedGameMedia.mediumExplosionSound = Sound::loadWAV("weapons/shared/explosion_medium.wav");
  283.     preloadedGameMedia.bigExplosionSound = Sound::loadWAV("weapons/shared/explosion_big.wav");
  284.  
  285.  
  286.     preloadedGameMedia.laserModel = new Model("weapons/laser/laser.model");
  287.     preloadedGameMedia.laserShotModel = new Model("weapons/laser/laser_shot.model");
  288.     preloadedGameMedia.laserMarkShader = new Shader("weapons/laser/laser_mark.shader");
  289.     preloadedGameMedia.laserFireSound = Sound::loadWAV("weapons/laser/laser_fire.wav");
  290.     preloadedGameMedia.laserImpactSound = Sound::loadWAV("weapons/laser/laser_impact.wav");
  291.     preloadedGameMedia.laserAnimator = new Animator("weapons/laser/laser.animator");    
  292.  
  293.     preloadedGameMedia.chaingunModel = new Model("weapons/chaingun/chaingun.model");
  294.     preloadedGameMedia.chaingunMuzzleFlashModel = new Model("weapons/chaingun/chaingun_muzzle_flash.model");
  295.     preloadedGameMedia.chaingunImpactShader = new Shader("weapons/chaingun/chaingun_impact.shader");
  296.     preloadedGameMedia.chaingunRicochetShader = new Shader("weapons/chaingun/chaingun_ricochet.shader");
  297.     preloadedGameMedia.chaingunFireSound = Sound::loadWAV("weapons/chaingun/chaingun_fire.wav");
  298.     for(i=0;i<MATERIAL_NUM_SURFACE_TYPES;i++){
  299.         preloadedGameMedia.chaingunMarkShaders[i] = NULL;
  300.         for(j=0;j<3;j++){
  301.             preloadedGameMedia.chaingunImpactSounds[i][j] = NULL;
  302.         }
  303.     }
  304.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_METAL][0] = Sound::loadWAV("weapons/chaingun/chaingun_impact_metal_01.wav");
  305.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_METAL][1] = Sound::loadWAV("weapons/chaingun/chaingun_impact_metal_02.wav");
  306.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_METAL][2] = Sound::loadWAV("weapons/chaingun/chaingun_impact_metal_03.wav");
  307.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_STONE][0] = Sound::loadWAV("weapons/chaingun/chaingun_impact_stone_01.wav");
  308.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_STONE][1] = Sound::loadWAV("weapons/chaingun/chaingun_impact_stone_02.wav");
  309.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_STONE][2] = Sound::loadWAV("weapons/chaingun/chaingun_impact_stone_03.wav");
  310.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_WOOD][0] = Sound::loadWAV("weapons/chaingun/chaingun_impact_wood_01.wav");
  311.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_WOOD][1] = Sound::loadWAV("weapons/chaingun/chaingun_impact_wood_02.wav");
  312.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_WOOD][2] = Sound::loadWAV("weapons/chaingun/chaingun_impact_wood_03.wav");
  313.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_DIRT][0] = Sound::loadWAV("weapons/chaingun/chaingun_impact_dirt_01.wav");
  314.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_DIRT][1] = Sound::loadWAV("weapons/chaingun/chaingun_impact_dirt_02.wav");
  315.     preloadedGameMedia.chaingunImpactSounds[MATERIAL_SURFACE_TYPE_DIRT][2] = Sound::loadWAV("weapons/chaingun/chaingun_impact_dirt_03.wav");
  316.  
  317.     preloadedGameMedia.chaingunMarkShaders[MATERIAL_SURFACE_TYPE_METAL] = new Shader("weapons/chaingun/chaingun_mark_metal.shader");
  318.     preloadedGameMedia.chaingunMarkShaders[MATERIAL_SURFACE_TYPE_STONE] = new Shader("weapons/chaingun/chaingun_mark_stone.shader");
  319.     preloadedGameMedia.chaingunMarkShaders[MATERIAL_SURFACE_TYPE_WOOD] = new Shader("weapons/chaingun/chaingun_mark_wood.shader");
  320.     preloadedGameMedia.chaingunMarkShaders[MATERIAL_SURFACE_TYPE_DIRT] = new Shader("weapons/chaingun/chaingun_mark_dirt.shader");
  321.  
  322.     preloadedGameMedia.chaingunAnimator = new Animator("weapons/chaingun/chaingun.animator");
  323.  
  324.  
  325.     preloadedGameMedia.railgunModel = new Model("weapons/railgun/railgun.model");
  326.     preloadedGameMedia.railgunTrailShader = new Shader("weapons/railgun/railgun_trail.shader");
  327.     preloadedGameMedia.railgunImpactShader = new Shader("weapons/railgun/railgun_impact.shader");
  328.     preloadedGameMedia.railgunMarkShader = new Shader("weapons/railgun/railgun_mark.shader");
  329.     preloadedGameMedia.railgunFireSound = Sound::loadWAV("weapons/railgun/railgun_fire.wav");
  330.     preloadedGameMedia.railgunImpactSound = Sound::loadWAV("weapons/railgun/railgun_impact.wav");
  331.     preloadedGameMedia.railgunAnimator = new Animator("weapons/railgun/railgun.animator");
  332.  
  333.  
  334.     preloadedGameMedia.rocketlauncherModel = new Model("weapons/rocketlauncher/rocketlauncher.model");
  335.     preloadedGameMedia.rocketlauncherShotModel = new Model("weapons/rocketlauncher/rocketlauncher_shot.model");
  336.     preloadedGameMedia.rocketlauncherFireSound = Sound::loadWAV("weapons/rocketlauncher/rocketlauncher_fire.wav");
  337. //    preloadedGameMedia.rocketlauncherImpactSound = Sound::loadWAV("weapons/rocketlauncher/rocketlauncher_impact.wav");
  338.     preloadedGameMedia.rocketlauncherAnimator = new Animator("weapons/rocketlauncher/rocketlauncher.animator");
  339.  
  340.  
  341.     preloadedGameMedia.plasmagunModel = new Model("weapons/plasmagun/plasmagun.model");
  342.     preloadedGameMedia.plasmagunShotShader = new Shader("weapons/plasmagun/plasma_ball.shader");
  343.     preloadedGameMedia.plasmagunImpactShader = new Shader("weapons/plasmagun/plasmagun_impact.shader");
  344.     preloadedGameMedia.plasmagunMarkShader = new Shader("weapons/plasmagun/plasmagun_mark.shader");
  345.     preloadedGameMedia.plasmagunFireSound = Sound::loadWAV("weapons/plasmagun/plasmagun_fire.wav");
  346.     preloadedGameMedia.plasmagunImpactSound = Sound::loadWAV("weapons/plasmagun/plasmagun_impact.wav");
  347.     preloadedGameMedia.plasmagunAnimator = new Animator("weapons/plasmagun/plasmagun.animator");
  348.  
  349.  
  350.     for(i=0;i<GAME_VOICE_MESSAGE_FUN1;i++){
  351.         char buff[256];
  352.         sprintf( buff, "vehicles/shared/sounds/voice_messages/%s.wav", Game::getVoiceMessageName(i) );
  353.         preloadedGameMedia.voiceMessages[i] = Sound::loadWAV(buff);
  354.     }
  355.  
  356.     preloadedGameMedia.voiceMessages[GAME_VOICE_MESSAGE_FUN1] = Sound::loadWAV("vehicles/shared/sounds/voice_messages/bender_bite.wav");
  357.     preloadedGameMedia.voiceMessages[GAME_VOICE_MESSAGE_FUN2] = Sound::loadWAV("vehicles/shared/sounds/voice_messages/crush_kill_destroy.wav");
  358.     preloadedGameMedia.voiceMessages[GAME_VOICE_MESSAGE_FUN3] = Sound::loadWAV("vehicles/shared/sounds/voice_messages/austin_behave.wav");
  359.     preloadedGameMedia.voiceMessages[GAME_VOICE_MESSAGE_FUN4] = Sound::loadWAV("vehicles/shared/sounds/voice_messages/dr_evil_angry.wav");
  360.     preloadedGameMedia.voiceMessages[GAME_VOICE_MESSAGE_FUN5] = Sound::loadWAV("vehicles/shared/sounds/voice_messages/fmj_kommi_schwein.wav");
  361.     preloadedGameMedia.voiceMessages[GAME_VOICE_MESSAGE_FUN6] = Sound::loadWAV("vehicles/shared/sounds/voice_messages/homer_champion.wav");
  362.     preloadedGameMedia.voiceMessages[GAME_VOICE_MESSAGE_FUN7] = Sound::loadWAV("vehicles/shared/sounds/voice_messages/homer_invincible.wav");
  363.     preloadedGameMedia.voiceMessages[GAME_VOICE_MESSAGE_FUN8] = Sound::loadWAV("vehicles/shared/sounds/voice_messages/arschloch.wav");
  364.     preloadedGameMedia.voiceMessages[GAME_VOICE_MESSAGE_FUN9] = Sound::loadWAV("vehicles/shared/sounds/voice_messages/evil_laugh.wav");
  365.     preloadedGameMedia.voiceMessages[GAME_VOICE_MESSAGE_FUN10] = Sound::loadWAV("vehicles/shared/sounds/voice_messages/long_laugh.wav");
  366.  
  367.     return true;
  368. }
  369.  
  370. bool Game::shutdownGameMedia(){
  371.     int i, j;
  372.  
  373.     delete preloadedGameMedia.supplyPadCylindersModel;
  374.     Mix_FreeChunk(preloadedGameMedia.supplyPadImpulseSound);
  375.  
  376.     delete preloadedGameMedia.spawnEffectSpheresModel;
  377.     Mix_FreeChunk(preloadedGameMedia.spawnEffectSound);
  378.     delete preloadedGameMedia.shockwaveShader;
  379.  
  380.     delete preloadedGameMedia.alleycatTorsoModel;
  381.     delete preloadedGameMedia.alleycatLegsModel;
  382.     delete preloadedGameMedia.alleycatLegsAnimator;
  383.  
  384.     delete preloadedGameMedia.dragonflyBodyModel;
  385.     delete preloadedGameMedia.dragonflyJetsModel;
  386.     delete preloadedGameMedia.dragonflyJetsAnimator;
  387.  
  388.     delete preloadedGameMedia.tinyExplosionShader;
  389.     delete preloadedGameMedia.smallExplosionShader;
  390.     delete preloadedGameMedia.mediumExplosionShader;
  391.     delete preloadedGameMedia.bigExplosionShader;
  392.     delete preloadedGameMedia.smallSmokePuffShader;
  393.     Mix_FreeChunk(preloadedGameMedia.tinyExplosionSound);
  394.     Mix_FreeChunk(preloadedGameMedia.smallExplosionSound);
  395.     Mix_FreeChunk(preloadedGameMedia.mediumExplosionSound);
  396.     Mix_FreeChunk(preloadedGameMedia.bigExplosionSound);
  397.  
  398.     delete preloadedGameMedia.laserModel;
  399.     delete preloadedGameMedia.laserShotModel;
  400.     delete preloadedGameMedia.laserMarkShader;
  401.     Mix_FreeChunk(preloadedGameMedia.laserFireSound);
  402.     Mix_FreeChunk(preloadedGameMedia.laserImpactSound);
  403.     delete preloadedGameMedia.laserAnimator;
  404.  
  405.     delete preloadedGameMedia.chaingunModel;
  406.     delete preloadedGameMedia.chaingunMuzzleFlashModel;
  407.     delete preloadedGameMedia.chaingunImpactShader;
  408.     delete preloadedGameMedia.chaingunRicochetShader;
  409.     Mix_FreeChunk(preloadedGameMedia.chaingunFireSound);
  410.     for(i=0;i<MATERIAL_NUM_SURFACE_TYPES;i++){
  411.         if( preloadedGameMedia.chaingunMarkShaders[i] != NULL ){
  412.             delete preloadedGameMedia.chaingunMarkShaders[i];
  413.         }
  414.         for(j=0;j<3;j++){
  415.             if( preloadedGameMedia.chaingunImpactSounds[i][j] != NULL ){
  416.                 Mix_FreeChunk(preloadedGameMedia.chaingunImpactSounds[i][j]);
  417.             }
  418.         }
  419.     }
  420.     delete preloadedGameMedia.chaingunAnimator;
  421.  
  422.     delete preloadedGameMedia.railgunModel;
  423.     delete preloadedGameMedia.railgunTrailShader;
  424.     delete preloadedGameMedia.railgunImpactShader;
  425.     delete preloadedGameMedia.railgunMarkShader;
  426.     Mix_FreeChunk(preloadedGameMedia.railgunFireSound);
  427.     Mix_FreeChunk(preloadedGameMedia.railgunImpactSound);
  428.     delete preloadedGameMedia.railgunAnimator;
  429.  
  430.     delete preloadedGameMedia.rocketlauncherModel;
  431.     delete preloadedGameMedia.rocketlauncherShotModel;
  432.     Mix_FreeChunk(preloadedGameMedia.rocketlauncherFireSound);
  433. //    Mix_FreeChunk(preloadedGameMedia.rocketlauncherImpactSound);
  434.     delete preloadedGameMedia.rocketlauncherAnimator;
  435.  
  436.     delete preloadedGameMedia.plasmagunModel;
  437.     delete preloadedGameMedia.plasmagunShotShader;
  438.     delete preloadedGameMedia.plasmagunImpactShader;
  439.     delete preloadedGameMedia.plasmagunMarkShader;
  440.     Mix_FreeChunk(preloadedGameMedia.plasmagunFireSound);
  441.     Mix_FreeChunk(preloadedGameMedia.plasmagunImpactSound);
  442.     delete preloadedGameMedia.plasmagunAnimator;
  443.  
  444.     for(i=0;i<GAME_NUM_VOICE_MESSAGES;i++){
  445.         if( preloadedGameMedia.voiceMessages[i] != NULL ){
  446.             Mix_FreeChunk(preloadedGameMedia.voiceMessages[i]);
  447.         }
  448.     }
  449.     
  450.  
  451.     return true;
  452. }
  453.  
  454. bool Game::initArenaCycle(){
  455.  
  456.     arenaCycle.arenaCycleElements.clear();
  457.  
  458.     log("Reading '%s'...\n", info.var.arenaCycleList);
  459.  
  460.     if( !File::exists("arenas/arenacycle.list") ){
  461.         error("(in Game::initArenaCycle()): File '%s' does not exist.\n\n", info.var.arenaCycleList);
  462.         return false;
  463.     }
  464.  
  465.     File f(info.var.arenaCycleList, "rt");
  466.     if( !f.isOpen() ){
  467.         error("(in Game::initArenaCycle()): Couldn't open file '%s'.\n\n", info.var.arenaCycleList);
  468.         return false;
  469.     }
  470.  
  471.     char buff[256];
  472.     while(f.readLine(256, buff, true) != -1){
  473.         if(strlen(buff) == 0){
  474.             continue;
  475.         }
  476.  
  477.         Tokenizer t(buff, "\" \t", "\"");
  478.  
  479.         if(t.tokc!=2){
  480.             warn("(in Game::initArenaCycle()): Wrong number of tokens in line %i of file '%s' (needed 2 but read %i).\n\n", f.line, f.filename, t.tokc);
  481.             continue;
  482.         }
  483.  
  484.         arenaCycleElement_t ace;
  485.         strncpy(ace.arena, t.tokv[0], CON_MAX_STRING_LENGTH);
  486.         ace.durationMillis = atoi(t.tokv[1]) * 60 * 1000;
  487.         arenaCycle.arenaCycleElements.push_back(ace);
  488.     }
  489.  
  490.     if( arenaCycle.arenaCycleElements.size() == 0 ){
  491.         error("(in Game::initArenaCycle()): No arena in arenacycle.\n\n");
  492.         return false;
  493.     }
  494.  
  495.     arenaCycle.playingSinceMillis = SDL_GetTicks();
  496.     arenaCycle.currentArena = 0;
  497.  
  498.     //strcpy(info.var.arena, arenaCycle.arenaCycleElements[0].arena);
  499.     info.cvar.game_arena->setValStr(arenaCycle.arenaCycleElements[0].arena);
  500.     info.cvar.game_arena->updateVar();
  501.  
  502.     return true;
  503. }
  504.  
  505. bool Game::shutdownArenaCycle(){
  506.     arenaCycle.arenaCycleElements.clear();
  507.     arenaCycle.playingSinceMillis = SDL_GetTicks();
  508.     arenaCycle.currentArena = 0;
  509.  
  510.     return true;
  511. }
  512.  
  513.  
  514. void Game::mainLoop(void){
  515.     bool done = false;
  516.     SDL_Event event;
  517.     unsigned long currentMillis = 0;
  518.     unsigned long frameStartMillis = SDL_GetTicks();
  519.     unsigned long frameDurationMillis = 0;
  520.  
  521.     Network::client->emptyPacketQueue();
  522.     info.cvar.game_player_team->setVal(GAME_TEAM_SPECTATORS);    // always begin new game as spectator
  523.     info.cvar.game_player_team->updateVar();
  524.     Network::client->sendClientSpawn();    // to enter the game
  525.  
  526.     while(!done){
  527.         frameStartMillis = SDL_GetTicks();
  528.     
  529.         while(SDL_PollEvent(& event)){
  530.             switch(event.type){
  531.                 case SDL_QUIT:
  532.                     System::normalQuit();
  533.                     break;
  534.  
  535.                 case SDL_KEYDOWN:
  536.                     if(event.key.keysym.sym==SDLK_ESCAPE){    // inGameMenu toggle
  537.                         if(Gui::inGameMenu->isOpened()){
  538.                             Input::hideMouseCursor();
  539.                             Input::grabInput();
  540.                             Gui::inGameMenu->close();
  541.                         }else if( Gui::hud->chatPrompt->isActive ){    // close chatPrompt
  542.                             Gui::hud->chatPrompt->deactivate();
  543.                         }else{    // open inGameMenu
  544.                             Input::showMouseCursor();
  545.                             Input::freeInput();
  546.                             Gui::inGameMenu->open();
  547.                         }
  548.  
  549.                     }
  550.                     if(!Gui::inGameMenu->isOpened()){
  551.                         Input::handleKeyboardEvent(&event.key);
  552.                     }else{
  553.                         Gui::inGameMenu->handleKeyboardEvent(&event.key);
  554.                     }
  555.                     break;
  556.  
  557.                 case SDL_KEYUP:
  558.                     if(!Gui::inGameMenu->isOpened()){
  559.                         Input::handleKeyboardEvent(&event.key);
  560.                     }else{
  561.                         Gui::inGameMenu->handleKeyboardEvent(&event.key);
  562.                     }
  563.                     break;
  564.  
  565.                 case SDL_MOUSEMOTION:
  566.                     if(!Gui::inGameMenu->isOpened()){
  567.                         Input::handleMouseMotionEvent(&event.motion);
  568.                     }else{
  569.                         Gui::inGameMenu->handleMouseMotionEvent(&event.motion);
  570.                     }
  571.                     break;
  572.  
  573.  
  574.                 case SDL_MOUSEBUTTONDOWN:
  575.                     if(!Gui::inGameMenu->isOpened()){
  576.                         Input::handleMouseButtonEvent(&event.button);
  577.                     }else{
  578.                         Gui::inGameMenu->handleMouseButtonEvent(&event.button);
  579.                     }
  580.                     break;
  581.  
  582.                 case SDL_MOUSEBUTTONUP:
  583.                     if(!Gui::inGameMenu->isOpened()){
  584.                         Input::handleMouseButtonEvent(&event.button);
  585.                     }else{
  586.                         Gui::inGameMenu->handleMouseButtonEvent(&event.button);
  587.                     }
  588.                     break;
  589.  
  590.                 default:
  591.  
  592.                     //warn("(in main::MainLoop()): received unknown event. Ignoring.\n\n");
  593.                     break;
  594.             } // switch
  595.         } // while( SDL_ ...
  596.  
  597.         Network::sendAndReceive();
  598.  
  599.         Input::processInputArray();
  600.  
  601.         Game::moveVehicles();
  602.         Game::moveShots();
  603.         Game::moveCamera();
  604.         if( !Game::info.var.clientGame && Game::info.var.useArenaCycle )
  605.             Game::doArenaCycle();
  606.  
  607.         Renderer::particleSystem.moveParticleClusters();
  608.         Renderer::renderScene();
  609.  
  610.         // Frame-Bremse!
  611.         currentMillis = SDL_GetTicks();
  612.         frameDurationMillis = currentMillis - frameStartMillis;
  613.  
  614.         if( frameDurationMillis < 10 )
  615.             SDL_Delay(10 - frameDurationMillis);
  616.     } // while( ! done)
  617. }
  618.  
  619. void Game::doArenaCycle(){
  620.     static bool oneMinuteWarningSend = false;
  621.     static bool tenSecondsWarningSend = false;
  622.  
  623.     unsigned long currentMillis = SDL_GetTicks();
  624.  
  625.     // do arenacycle stuff
  626.     if( currentMillis + 60000 > arenaCycle.playingSinceMillis + arenaCycle.arenaCycleElements[arenaCycle.currentArena].durationMillis
  627.         && !oneMinuteWarningSend ){
  628.         Network::server->sendChatMessage("Changing arena in one minute!");
  629.         oneMinuteWarningSend = true;
  630.     }else if( currentMillis + 10000 > arenaCycle.playingSinceMillis + arenaCycle.arenaCycleElements[arenaCycle.currentArena].durationMillis
  631.         && !tenSecondsWarningSend ){
  632.         Network::server->sendChatMessage("Changing arena in 10 seconds!");
  633.         tenSecondsWarningSend = true;
  634.     }else if( currentMillis > arenaCycle.playingSinceMillis + arenaCycle.arenaCycleElements[arenaCycle.currentArena].durationMillis ){
  635.  
  636.         Gui::loadingMenu->open();
  637.         Gui::loadingMenu->updateStatusBar("changing arena");
  638.         Gui::loadingMenu->updateHeading("changing arena");
  639.  
  640.         arenaCycle.currentArena++;
  641.         if( arenaCycle.currentArena >= arenaCycle.arenaCycleElements.size() )
  642.             arenaCycle.currentArena = 0;
  643.  
  644.         Game::info.cvar.game_arena->setValStr( arenaCycle.arenaCycleElements[arenaCycle.currentArena].arena );
  645.         Game::info.cvar.game_arena->updateVar();
  646.  
  647.         Network::server->sendArenaChange();
  648.  
  649.         if( !Game::changeArena() ){
  650.             error("(in Game::doArenaCycle()): Game::changeArena() failed.\n\n");
  651.             Game::shutdown();
  652.             Gui::mainMenu->open();
  653.         }
  654.  
  655.         log("\n");
  656.         log("Game::changeArena() finished. Resetting clients...\n");
  657.         Network::server->resetClients();
  658.         Network::server->emptyPacketQueue();
  659.  
  660.         Gui::loadingMenu->close();
  661.  
  662.         arenaCycle.playingSinceMillis = SDL_GetTicks();
  663.         oneMinuteWarningSend = false;
  664.         tenSecondsWarningSend = false;
  665.         log("Re-entering Mainloop...\n");
  666.         // weiter geht's?? - scheint so...
  667.         mainLoop();
  668.  
  669.     }
  670. }
  671.  
  672. bool Game::changeArena(){
  673.     int i;
  674.     char buff[256];
  675.  
  676.     log("Changing arena...\n");
  677.     // show scores
  678.     sprintf(buff, "scores for %s", arena->name);
  679.     Gui::loadingMenu->updateHeading(buff);
  680.     Gui::loadingMenu->updateCenterTexture(arena->thumbnailTexture);
  681.     Gui::loadingMenu->updateSubHeading(Game::getModeName(info.var.mode));
  682.     Gui::loadingMenu->drawScoreboard = true;
  683.     for(i=0;i<10;i++){
  684.         sprintf(buff, "%i seconds", 10 - i);
  685.         Gui::loadingMenu->updateStatusBar(buff);
  686.         SDL_Delay(1000);
  687.     }
  688.     Gui::loadingMenu->drawScoreboard = false;
  689.     Gui::loadingMenu->updateHeading("changing arena");
  690.     Gui::loadingMenu->updateCenterTexture(NULL);
  691.  
  692.  
  693.     // change arena
  694.     log("Deleting shots and vehicles...\n");
  695.     for(i=0;i<GAME_MAX_SHOTS;i++){
  696.         if( shots[i] != NULL ){
  697.             unspawnShot( shots[i] );
  698.         }
  699.     }
  700.     for(i=0;i<GAME_MAX_VEHICLES;i++){
  701.         if( vehicles[i] != NULL ){
  702.             unspawnVehicle( vehicles[i] );
  703.         }
  704.     }
  705.  
  706.     Renderer::shutdownParticleSystem();
  707.     log("Deleting arena...\n");
  708.     delete arena;
  709.     arena = NULL;
  710.  
  711.  
  712.  
  713.     if(!File::exists(info.var.arena)){
  714.         error("(in Game::init()): Arena-File '%s' does not exist.\n\n", info.var.arena);
  715.         Network::shutdownClient();
  716.         Network::shutdownServer();
  717.         return false;
  718.     }
  719.  
  720.     Gui::loadingMenu->updateStatusBar("loading arena");
  721.  
  722.     log("Loading arena...\n");
  723.     arena = new Arena(info.var.arena);
  724.     log("Arena '%s' loaded (%i spawnpoints, %i supplypads).\n", info.var.arena, arena->spawnpoints.size(), arena->supplypads.size());
  725.     log("\n");
  726.  
  727.     if(!Renderer::initParticleSystem()){
  728.         error("(in Game::init()): Couldn't init particle system.\n\n");
  729.         Network::shutdownClient();
  730.         Network::shutdownServer();
  731.         return false;
  732.     }
  733.  
  734.  
  735.     return true;
  736. }
  737.  
  738.  
  739. void Game::moveVehicles(){
  740.     for(int i=0;i<Network::server->si.maxClients;i++){
  741.         if( vehicles[i] != NULL ){
  742.             vehicles[i]->move();
  743.         }
  744.     }
  745.  
  746. }
  747.  
  748. void Game::moveShots(){
  749.     static unsigned int lastShotMoveMillis = SDL_GetTicks();
  750.  
  751.     unsigned long currentMillis = SDL_GetTicks();
  752.     float deltaT = (currentMillis - lastShotMoveMillis)/1000.0f;
  753.     lastShotMoveMillis = currentMillis;
  754.  
  755.     for(int i=0;i<GAME_MAX_SHOTS;i++){
  756.         if( shots[i] != NULL ){
  757.             Shot* s = shots[i];
  758.             if( currentMillis > s->spawntimeMillis + s->lifetimeMillis ){
  759.                 unspawnShot(s);
  760. //                delete s;
  761.             }else{
  762.                 shots[i]->move(deltaT);
  763.             }
  764.         }
  765.     }
  766. }
  767.  
  768. void Game::moveCamera(){
  769.     cam.move();
  770. }
  771.  
  772.  
  773. void Game::findSpawnpointForClient(Client* client){
  774.     unsigned int i;
  775.  
  776.     unsigned int numSpawnPoints = arena->spawnpoints.size();
  777.     unsigned int first = irand(numSpawnPoints-1);
  778.  
  779.     for(i=first;i<numSpawnPoints;i++){
  780.         spawnpoint_t* sp = &arena->spawnpoints[i];
  781.         if( sp->teamFlags & (0x01 << client->ci.team) ){
  782.             float u = frand();
  783.             float v = frand();
  784.             float w = frand();
  785.             vec3_t pos;
  786.  
  787.             pos[0] = (1.0f-u)*sp->min[0] + (u)*sp->max[0];
  788.             pos[1] = (1.0f-v)*sp->min[1] + (v)*sp->max[1];
  789.             pos[2] = (1.0f-w)*sp->min[2] + (w)*sp->max[2];
  790.  
  791.             // TODO: check if pos is save!
  792.             vectorCopy3d(pos, client->cs.pos);
  793.             return;
  794.         }
  795.     }
  796.  
  797.     for(i=0;i<first;i++){
  798.         spawnpoint_t* sp = &arena->spawnpoints[i];
  799.         if( sp->teamFlags & (0x01 << client->ci.team) ){
  800.             float u = frand();
  801.             float v = frand();
  802.             float w = frand();
  803.             vec3_t pos;
  804.  
  805.             pos[0] = (1.0f-u)*sp->min[0] + (u)*sp->max[0];
  806.             pos[1] = (1.0f-v)*sp->min[1] + (v)*sp->max[1];
  807.             pos[2] = (1.0f-w)*sp->min[2] + (w)*sp->max[2];
  808.  
  809.             // TODO: check if pos is save!
  810.             vectorCopy3d(pos, client->cs.pos);
  811.             return;
  812.         }
  813.     }
  814.  
  815.  
  816.     warn("(in Game::findSpawnpointForClient()): Couldn't find spawnpoint for client '%s'.\n\n", client->ci.name);
  817. }
  818.  
  819. void Game::spawnVehicle(Client* client){
  820.     if( client->clientId == -1 ){
  821.         warn("(in Game:spawnVehicle()): Tried to spawn vehicle for client with invalid clientId. Ignoring\n\n");
  822.         return;
  823.     }
  824.  
  825.     int slot = client->clientId;
  826.  
  827.     // ok, spawn him
  828.  
  829.     client->lastSpawnMillis = SDL_GetTicks();
  830.  
  831.     if( client->ci.team == GAME_TEAM_SPECTATORS ){
  832.         if( client == Network::client ){    // local client
  833.             cam.setTarget(NULL);
  834.             cam.setPositionAndOrientation(client->cs.pos, client->cs.dir, client->cs.up);
  835. //            cam.setMode(CAMERA_MODE_FIRST_PERSON);
  836.         }
  837.     }else{
  838.         client->vehicle = Vehicle::createVehicleForClient(client);
  839.         vehicles[slot] = client->vehicle;
  840.  
  841.         if( client == Network::client ){
  842.             cam.setTarget(client->vehicle);
  843.             cam.setPositionAndOrientation(client->cs.pos, client->cs.dir, client->cs.up);    // THINKABOUTME: damit sound im spawneffect richtig abgespeilt wird...
  844. //            cam.setMode(CAMERA_MODE_FIRST_PERSON);
  845.         }
  846.  
  847.         // link effect
  848.         Renderer::particleSystem.linkParticleCluster( new SpawnEffectParticleCluster(client->vehicle->pos) );
  849.     }
  850.  
  851. //    printf("spawned %s.\n", client->ci.name);
  852. }
  853.  
  854. void Game::unspawnVehicle(Vehicle* vehicle){
  855.     if( vehicle->client->clientId == -1 ){
  856.         warn("(in Game:unspawnVehicle()): Tried to unspawn vehicle for client with invalid clientId. Ignoring\n\n");
  857.         return;
  858.     }
  859.  
  860.     if( vehicle != NULL ){
  861.  
  862.         // link effect!
  863. //        Renderer::particleSystem.linkParticleCluster( new SpawnEffectParticleCluster(client->vehicle->pos) );
  864.  
  865.         if( vehicle == cam.target ){
  866.             cam.setTarget(NULL);
  867.         }
  868.  
  869.         // search slot in vehicles-array
  870.         int slot = vehicle->client->clientId;
  871.  
  872.         vehicle->client->vehicle = NULL;
  873.         vehicles[slot] = NULL;
  874.         delete vehicle;
  875.     }else{
  876.         warn("(in Game:unspawnVehicle()): Tried to unspawn client that is already unspawned.\n\n");
  877.     }
  878. }
  879.  
  880. void Game::killClient(Client* killed, Client* killer, char weapon){
  881.     if( killed->vehicle != NULL ){
  882.         killed->cs.armor = 0;
  883.         killed->cs.energy = 0;
  884.  
  885.         killed->nextSpawnMillis = SDL_GetTicks() + Game::info.var.ghostTime;
  886.  
  887.         if( weapon == -1 ){ // killed by server admin
  888.             log("%s was killed by server admin.\n", killed->ci.name);
  889.         }else if( killed == killer ){    // suicide
  890.             log("%s commited suicide.\n", killed->ci.name);
  891.             killed->ci.score--;
  892.             killed->ci.deaths++;
  893.         }else{    // normal kill
  894.             if( killer != NULL ){
  895.                 if( Game::info.var.mode == GAME_MODE_DEATHMATCH ){
  896.                     log("%s became a victim of %ss %s.\n", killed->ci.name, killer->ci.name, Game::getWeaponName(weapon));
  897.                     if( killed == Network::client ){
  898.                         Gui::hud->centerOfScreenMessages->setMessage("You were killed by %s!", killer->ci.name);
  899.                     }else if( killer == Network::client ){
  900.                         Gui::hud->centerOfScreenMessages->setMessage("You killed %s!", killed->ci.name);
  901.                     }
  902.                     killed->ci.deaths++;
  903.                     killer->ci.score++;
  904.                     killer->ci.kills++;
  905.                 }else if( Game::info.var.mode == GAME_MODE_TEAM_DEATHMATCH ){
  906.                     if( killer->ci.team != killed->ci.team ){
  907.                         log("%s became a victim of %ss %s.\n", killed->ci.name, killer->ci.name, Game::getWeaponName(weapon));
  908.                         if( killed == Network::client ){
  909.                             Gui::hud->centerOfScreenMessages->setMessage("You were killed by %s!", killer->ci.name);
  910.                         }else if( killer == Network::client ){
  911.                             Gui::hud->centerOfScreenMessages->setMessage("You killed %s!", killed->ci.name);
  912.                         }
  913.                         killed->ci.deaths++;
  914.                         killer->ci.score++;
  915.                         killer->ci.kills++;
  916.                     }else{    // team kill
  917.                         log("%s was TEAMkilled by %ss %s.\n", killed->ci.name, killer->ci.name, Game::getWeaponName(weapon));
  918.                         if( killed == Network::client ){
  919.                             Gui::hud->centerOfScreenMessages->setMessage("You were TEAMkilled by %s!", killer->ci.name);
  920.                         }else if( killer == Network::client ){
  921.                             Gui::hud->centerOfScreenMessages->setMessage("You TEAMkilled %s!", killed->ci.name);
  922.                         }
  923. //                        killed->ci.deaths++;
  924. //                        killer->ci.score++;
  925. //                        killer->ci.kills++;
  926.                     }
  927.                 }
  928.             }else{
  929.                 log("%s was killed by %ss %s.\n", killed->ci.name, "<disconnected>", Game::getWeaponName(weapon));
  930.                 if( killed == Network::client ){
  931.                     Gui::hud->centerOfScreenMessages->setMessage("You were killed by <disconnected>!", killer->ci.name);
  932.                 }
  933.                 killed->ci.deaths++;
  934.             }
  935.         }
  936.  
  937.         // move camera
  938.         if( cam.target == killed->vehicle && cam.mode == CAMERA_MODE_FIRST_PERSON ){
  939.             vectorMA3d(cam.pos, -5.0f, cam.dir, cam.pos);
  940.             cam.anglesFromVectors();
  941.         }
  942.  
  943.         // remove vehicle
  944.         killed->vehicle->explode();
  945.         unspawnVehicle(killed->vehicle);
  946.     }else{
  947.         warn("(in Game::killClient()): Tried to kill client that is already dead.\n\n");
  948.     }
  949. }
  950.  
  951. void Game::spawnShot(shotSpawnPacket_t* ss){
  952.     Shot* s = Shot::createShotForShotSpawnPacket(ss);
  953.  
  954.     if( s == NULL )
  955.         return;
  956.  
  957.     s->leaveMuzzle();
  958.  
  959.     for(int i=0;i<GAME_MAX_SHOTS;i++){
  960.         if( shots[i] == NULL ){
  961.             shots[i] = s;
  962.             return;
  963.         }
  964.     }
  965.  
  966.     warn("(in Game::spawnShot()): Couldn't spawn shot (GAME_MAX_SHOTS reached).\n\n");
  967.     delete s;
  968. }
  969.  
  970. void Game::unspawnShot(Shot* shot){
  971.     for(int i=0;i<GAME_MAX_SHOTS;i++){
  972.         if( shots[i] == shot ){
  973.             delete shots[i];
  974.             shots[i] = NULL;
  975.             return;
  976.         }
  977.     }
  978.  
  979.     warn("(in Game::unspawnShot()): Couldn't unspawn shot (not found).\n\n");
  980. }
  981.  
  982.  
  983. void Game::chatMessageAll(const char* message){
  984.     Network::client->sendChatMessage(GAME_CHAT_MODE_ALL, message);
  985. }
  986.  
  987. void Game::chatMessageTeam(const char* message){
  988.     Network::client->sendChatMessage(GAME_CHAT_MODE_TEAM, message);
  989. }
  990.  
  991.  
  992. void Game::renderVehicles(){
  993.     for(int i=0;i<GAME_MAX_VEHICLES;i++){
  994.  
  995.         if( vehicles[i] != NULL
  996.             && ( vehicles[i]->boundingSphereRadius == 0.0f || Game::cam.sphereInFrustum(vehicles[i]->pos, vehicles[i]->boundingSphereRadius) )
  997.             ){
  998.             vehicles[i]->render();
  999.  
  1000.         }
  1001.     }
  1002. }
  1003.  
  1004. void Game::renderShots(){
  1005.     for(int i=0;i<GAME_MAX_SHOTS;i++){
  1006.         if( shots[i] != NULL 
  1007.             && ( shots[i]->boundingSphereRadius == 0.0f || Game::cam.sphereInFrustum(shots[i]->pos, shots[i]->boundingSphereRadius) )
  1008.             ){
  1009.             shots[i]->render();
  1010.         }
  1011.     }
  1012. }
  1013.  
  1014.  
  1015.  
  1016. const char* Game::getModeName(int mode){
  1017. //    if(mode == GAME_MODE_TEST){
  1018. //        return "just testing";
  1019. //    }else 
  1020.     if(mode == GAME_MODE_DEATHMATCH){
  1021.         return "deathmatch";
  1022.     }else if(mode == GAME_MODE_TEAM_DEATHMATCH){
  1023.         return "team deathmatch";
  1024. //    }else if(mode == GAME_MODE_SOLE_SURVIVOR){
  1025. //        return "sole survivor";
  1026. //    }else if(mode == GAME_MODE_TEAM_SURVIVOR){
  1027. //        return "team survivor";
  1028.     }else{
  1029.         return "<unknown game mode>";
  1030.     }
  1031. }
  1032.  
  1033. const char* Game::getTeamName(int team){
  1034.     if(team == GAME_TEAM_SPECTATORS){
  1035.         return "spectators";
  1036.     }else if(team == GAME_TEAM_PLAYERS){
  1037.         return "players";
  1038.     }else if(team == GAME_TEAM_RED){
  1039.         return "red";
  1040.     }else if(team == GAME_TEAM_BLUE){
  1041.         return "blue";
  1042.     }else{
  1043.         return "<unknown team>";
  1044.     }
  1045. }
  1046.  
  1047. const char* Game::getVehicleName(int vehicle){
  1048.     if(vehicle == GAME_VEHICLE_DRAGONFLY){
  1049.         return "dragonfly";
  1050.     }else if(vehicle == GAME_VEHICLE_ALLEYCAT){
  1051.         return "alleycat";
  1052. //    }else if(vehicle == GAME_VEHICLE_SLEDGEHAMMER){
  1053. //        return "sledgehammer";
  1054.     }else{
  1055.         return "<unknown vehicle>";
  1056.     }
  1057. }
  1058.  
  1059. const char* Game::getWeaponName(int weapon){
  1060.     if(weapon == GAME_WEAPON_NO_WEAPON){
  1061.         return "no weapon";
  1062.     }else if(weapon == GAME_WEAPON_LASER){
  1063.         return "laser";
  1064.     }else if(weapon == GAME_WEAPON_CHAINGUN){
  1065.         return "chaingun";
  1066.     }else if(weapon == GAME_WEAPON_RAILGUN){
  1067.  
  1068.         return "railgun";
  1069.     }else if(weapon == GAME_WEAPON_ROCKETLAUNCHER){
  1070.         return "rocketlauncher";
  1071.     }else if(weapon == GAME_WEAPON_PLASMAGUN){
  1072.         return "plasmagun";
  1073. //    }else if(weapon == GAME_WEAPON_GRENADELAUNCHER){
  1074. //        return "grenadelauncher";
  1075.  
  1076.     }else{
  1077.         return "<unknown weapon>";
  1078.     }
  1079.  
  1080. }
  1081.  
  1082. int Game::getVoiceMessageId(const char* string){
  1083.     if( streq("attack", string) ){
  1084.         return GAME_VOICE_MESSAGE_ATTACK;
  1085.     }else if( streq("defend", string) ){
  1086.         return GAME_VOICE_MESSAGE_DEFEND;
  1087.     }else if( streq("go", string) ){
  1088.         return GAME_VOICE_MESSAGE_GO;
  1089.     }else if( streq("fall_back", string) ){
  1090.         return GAME_VOICE_MESSAGE_FALL_BACK;
  1091.     }else if( streq("retreat", string) ){
  1092.         return GAME_VOICE_MESSAGE_RETREAT;
  1093.     }else if( streq("report_in", string) ){
  1094.         return GAME_VOICE_MESSAGE_REPORT_IN;
  1095.     }else if( streq("contact", string) ){
  1096.         return GAME_VOICE_MESSAGE_CONTACT;
  1097.     }else if( streq("under_fire", string) ){
  1098.         return GAME_VOICE_MESSAGE_UNDER_FIRE;
  1099.     }else if( streq("need_backup", string) ){
  1100.         return GAME_VOICE_MESSAGE_NEED_BACKUP;
  1101.     }else if( streq("fine", string) ){
  1102.         return GAME_VOICE_MESSAGE_FINE;
  1103.  
  1104.     }else if( streq("taunt", string) ){
  1105.         return GAME_VOICE_MESSAGE_TAUNT;
  1106.     }else if( streq("cheer", string) ){
  1107.         return GAME_VOICE_MESSAGE_CHEER;
  1108.     }else if( streq("sorry", string) ){
  1109.         return GAME_VOICE_MESSAGE_SORRY;
  1110.  
  1111.     }else if( streq("fun1", string) ){
  1112.         return GAME_VOICE_MESSAGE_FUN1;
  1113.     }else if( streq("fun2", string) ){
  1114.         return GAME_VOICE_MESSAGE_FUN2;
  1115.     }else if( streq("fun3", string) ){
  1116.         return GAME_VOICE_MESSAGE_FUN3;
  1117.     }else if( streq("fun4", string) ){
  1118.         return GAME_VOICE_MESSAGE_FUN4;
  1119.     }else if( streq("fun5", string) ){
  1120.         return GAME_VOICE_MESSAGE_FUN5;
  1121.     }else if( streq("fun6", string) ){
  1122.         return GAME_VOICE_MESSAGE_FUN6;
  1123.     }else if( streq("fun7", string) ){
  1124.         return GAME_VOICE_MESSAGE_FUN7;
  1125.     }else if( streq("fun8", string) ){
  1126.         return GAME_VOICE_MESSAGE_FUN8;
  1127.     }else if( streq("fun9", string) ){
  1128.         return GAME_VOICE_MESSAGE_FUN9;
  1129.     }else if( streq("fun10", string) ){
  1130.         return GAME_VOICE_MESSAGE_FUN10;
  1131.     }else{
  1132.         return -1;
  1133.     }
  1134. }
  1135.  
  1136. const char* Game::getVoiceMessageName(int id){
  1137.     if(id == GAME_VOICE_MESSAGE_ATTACK){
  1138.         return "attack";
  1139.     }else if(id == GAME_VOICE_MESSAGE_DEFEND){
  1140.         return "defend";
  1141.     }else if(id == GAME_VOICE_MESSAGE_GO){
  1142.         return "go";
  1143.     }else if(id == GAME_VOICE_MESSAGE_FALL_BACK){
  1144.         return "fall_back";
  1145.     }else if(id == GAME_VOICE_MESSAGE_RETREAT){
  1146.         return "retreat";
  1147.     }else if(id == GAME_VOICE_MESSAGE_REPORT_IN){
  1148.         return "report_in";
  1149.     }else if(id == GAME_VOICE_MESSAGE_CONTACT){
  1150.         return "contact";
  1151.     }else if(id == GAME_VOICE_MESSAGE_UNDER_FIRE){
  1152.         return "under_fire";
  1153.     }else if(id == GAME_VOICE_MESSAGE_NEED_BACKUP){
  1154.         return "need_backup";
  1155.     }else if(id == GAME_VOICE_MESSAGE_FINE){
  1156.         return "fine";
  1157.  
  1158.     }else if(id == GAME_VOICE_MESSAGE_TAUNT){
  1159.         return "taunt";
  1160.     }else if(id == GAME_VOICE_MESSAGE_CHEER){
  1161.         return "cheer";
  1162.     }else if(id == GAME_VOICE_MESSAGE_SORRY){
  1163.         return "sorry";
  1164.  
  1165.     }else if(id == GAME_VOICE_MESSAGE_FUN1){
  1166.         return "fun1";
  1167.     }else if(id == GAME_VOICE_MESSAGE_FUN2){
  1168.         return "fun2";
  1169.     }else if(id == GAME_VOICE_MESSAGE_FUN3){
  1170.         return "fun3";
  1171.     }else if(id == GAME_VOICE_MESSAGE_FUN4){
  1172.         return "fun4";
  1173.     }else if(id == GAME_VOICE_MESSAGE_FUN5){
  1174.         return "fun5";
  1175.     }else if(id == GAME_VOICE_MESSAGE_FUN6){
  1176.         return "fun6";
  1177.     }else if(id == GAME_VOICE_MESSAGE_FUN7){
  1178.         return "fun7";
  1179.     }else if(id == GAME_VOICE_MESSAGE_FUN8){
  1180.         return "fun8";
  1181.     }else if(id == GAME_VOICE_MESSAGE_FUN9){
  1182.         return "fun9";
  1183.     }else if(id == GAME_VOICE_MESSAGE_FUN10){
  1184.         return "fun10";
  1185.  
  1186.     }else{
  1187.         return "<unknown voice message>";
  1188.     }
  1189.  
  1190. }
  1191.  
  1192.