Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

OverheadWinMain.cpp

Go to the documentation of this file.
00001 /*
00002 CS Senior Project 2003
00003 Team : Leftfield
00004 Project : ModernWarfare
00005 Members :
00006 - Russ Christensen              <rchriste@cs.utah.edu>
00007 - Todd Smith                    <tcsmith@cs.utah.edu>
00008 - Usit Duongsaa                 <duongsaa@cs.utah.edu>
00009 Copyright 2003 Russ Christensen, Usit Duongsaa, and Todd Smith. All rights reserved.
00010 
00011 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00012 
00013 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
00014 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 
00015 THIS SOFTWARE IS PROVIDED BY RUSS CHRISTENSEN, USIT DUONGSAA, AND TODD SMITH ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RUSS, USIT, TODD OR OTHER CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00016 */
00017 
00023 #include "Network.h" //This include file *must* come before AEngine.h
00024 #include "Overhead.h"
00025 #include "BattleEntry.h"
00026 #include "Map.h"
00027 #include "Bank.h"
00028 #include "Player.h"
00029 #include "GameConfig.h"
00030 #include "EconData.h"
00031 #include "BattleUnitData.h"
00032 #include "Sound.h"
00033 #include "Typer.h"
00034 #include "HUD.h"
00035 #include "GameState.h"
00036 #include "Tutorial.h"
00037 #include "Icon.h"
00038 
00039 using namespace std;
00040 using namespace NetworkSubsystem;
00041 using namespace NetworkMessages;
00042 using namespace Helper;
00043 
00044 //------------------------------------------------------------------------------------
00045 namespace Overhead {
00046         const int TRANSITION_TIME = 30;
00047         vector<DrawableObject*>& drawableObjects = GameState::drawables();
00048         vector<MilitaryUnit*>& units = GameState::units();
00049         vector<City*>& cities = GameState::cities();
00050         vector<BattleEntry*>& battles = GameState::battles();
00052         vector<MilitaryUnit*>& selectedUnits = GameState::selectedUnits();
00053         Vec2D dragCorner;               // when you drag-select, this is the 2D pt where you first start the drag
00054         bool dragging;
00055         City* selectedCity(0);
00056         FLOAT   camHeight;
00057         bool focusOverhead = true;
00059         PlayerVec& players = GameState::players();
00060         bool showThreatMap = false;
00061         Typer chatBox;
00062         bool chatBoxOn = false;
00063         Tutorial tutorial;
00064         list<BattleSprite> battleCircleAnimation;
00065         Icon unitMaintenance(Vec2D(0.65f,0.81f), Vec2D(0.76f,0.85f), 0);
00066 
00067         const int MODE_PLAYERS_LIST             =       0;
00068         //const int MODE_BATTLES_LIST           =       1;
00069         const int MODE_NONE                             =       2;
00070         int playersNBattleListMode;
00071 
00072         // for switching overhead<-->battle, battle<-->battle transition effect
00073         BattleEntry *prevBattle;
00074         int transitionTimeRemaining;
00075 
00076         bool youWin, youLose;
00077         int  creditTimer;               // normally has value of -1, as soon as you win or lose, 
00078                                                         // this timer becomes 0 and counts up
00079 
00080         bool showConfirmQuitMenu;
00081         //------------------------------------------------------------------------------------
00082         void mainMenuCredit()
00083         {
00084                 youWin = true;
00085                 youLose = false;
00086                 creditTimer = 0;
00087         }
00088         //------------------------------------------------------------------------------------
00089         void updateCredit()
00090         {
00091                 if( creditTimer==0 )            // music
00092                 {
00093                         if( youWin  ) Sound::getObj().playMusic( Sound::SMPL_SONG_WIN );
00094                         if( youLose ) Sound::getObj().playMusic( Sound::SMPL_SONG_LOST );
00095                 }
00096 
00097                 if( creditTimer >= 0 )  creditTimer++;
00098         }
00099         //------------------------------------------------------------------------------------
00100 #define R() vec.push_back( "Russ Christensen" )
00101 #define T() vec.push_back( "Todd Smith" )
00102 #define U() vec.push_back( "Usit Duongsaa" )
00103 #define S() vec.push_back( "" );
00104         void renderCredit()
00105         {
00106                 static vector<string> vec;
00107                 if( vec.size()==0 )
00108                 {
00109                         S();  vec.push_back( "_Overhead Mode" );                R(); T();
00110                         S();  vec.push_back( "_Battle Mode" );                  U();
00111                         S();  vec.push_back( "_3D Graphics Engine" );   U();
00112                         S();  vec.push_back( "_Input Interface" );              U();
00113                         S();  vec.push_back( "_Sound Interface" );              T();
00114                         S();  vec.push_back( "_Network Interface" );    U();
00115                         S();  vec.push_back( "_Multiplayer Support" );  R(); U();
00116                         S();  vec.push_back( "_Chat System" );                  R();
00117                         S();  vec.push_back( "_Game State Synchronization" );           U(); R();
00118                         S();  vec.push_back( "_HUD" );                                  T(); U();
00119                         S();  vec.push_back( "_Game Data Management" ); T();
00120                         S();  vec.push_back( "_Special Effects" );              U();
00121                         S();  vec.push_back( "_Tutorial" );                             R();
00122                         S();  vec.push_back( "_3D Models" );                    U();
00123                         S();  vec.push_back( "_Textures" );                             U(); T();
00124                         S();  vec.push_back( "_Box Art & Quick Reference" );  R();
00125                         S();  vec.push_back( "_Voice Acting" );                 T();                    
00126                         S();  vec.push_back( "_Maps" );                                 T();                    
00127                         S();  vec.push_back( "_Source Control Server Maintenance" );    R();
00128                         S();  vec.push_back( "_Web Site Maintenance" );                                 R();                    
00129                         S();  vec.push_back( "_Internal Testing" );             U(); R(); T();
00130                         S();  vec.push_back( "_Special Thanks to All Beta Testers" );
00131                         vec.push_back( "Dr. John Regehr" );
00132                         vec.push_back( "Michael Warner" );
00133                         vec.push_back( "Tyler Beuchert" );
00134                         vec.push_back( "Thanh Do" );
00135                         vec.push_back( "Gregory Mayberry" );
00136                         vec.push_back( "Anthony Nguyen" );
00137                         vec.push_back( "Jamie Moench" );
00138                         vec.push_back( "James Jensen" );
00139                         vec.push_back( "Nathan Beddes" );
00140                         vec.push_back( "Chantel Beck" );
00141                         vec.push_back( "Scott Little" );
00142                         vec.push_back( "Allison Kelly" );
00143                         vec.push_back( "Justin Olson" );
00144                         vec.push_back( "Kina Kousoum" );
00145                         vec.push_back( "And Several Other People Whose Names We Don't Have" );
00146                         vec.push_back( "_Thank you all for the excellent feedback" );
00147                 }
00148                 
00149                 FLOAT y = 1.6f - creditTimer*0.001f;
00150                 for( UINT i=0; i<vec.size(); i++ )
00151                 {
00152                         FLOAT x = 0.15f;
00153                         FLOAT size = 1.3f;
00154                         Vec3D col( Colors::white );
00155                         string line = vec[i];
00156                         if( line[0]=='_' )
00157                         {
00158                                 line = line.substr(1);
00159                                 size = 1.6f;
00160                                 col  = Colors::yellow;
00161                         }
00162                         
00163                         if( y>=-0.2f && y<=0.7f )
00164                         {
00165                                 overlay_text() << line;
00166                                 overlay_textOut( Vec2D(x,y), size, col, NULL, 9 );
00167                         }
00168                         y += 0.10f;
00169                 }
00170 
00171         }
00172         //------------------------------------------------------------------------------------
00173         void askForRandomNumbers()
00174         {
00175                 static askedNumber(0);
00176                 stringstream sstr;
00177                 sstr << COMMAND_ASK_FOR_RANDOM_NUMBER << " " << COMMIT_TIME << " " << currGameTick + NETWORK_GAME_TICK_LAG 
00178                         << " " << ++askedNumber;
00179                 net_send(sstr.str());
00180         }
00181         //------------------------------------------------------------------------------------
00182         void doVictoryTest()
00183         {
00184                 bool hasLost = true;
00185                 bool hasWon = true;
00186                 for(vector<City*>::iterator iter(GameState::cities().begin()); iter != GameState::cities().end(); ++iter)
00187                 {
00188                         if ((*iter)->color() == GameState::consolePlayer()->color()) hasLost = false;
00189                         else if ((*iter)->owner() ) hasWon = false;                     
00190                 }
00191                 for(vector<MilitaryUnit*>::iterator iter(GameState::units().begin()); iter != GameState::units().end(); ++iter)
00192                 {
00193                         if ((*iter)->color() == GameState::consolePlayer()->color()) hasLost = false;
00194                         else if( (*iter)->owner() )  hasWon = false;
00195                 }
00196 
00197                 // can't win until you finish all battle
00198                 if( GameState::battles().size()>0 )  hasWon = false;
00199 
00200                 // if you still have forces in battle, you can't lose yet
00201                 Vec3D playerCol( GameState::consolePlayer()->color() );         
00202                 for( vector<BattleEntry*>::iterator iter(GameState::battles().begin()); iter!=GameState::battles().end(); iter++ )                      
00203                         if( (*iter)->isFoughtBy(playerCol) ) hasLost = false;
00204 
00205                 // for testing purposes
00206                 if( input_isKeyDown(KeyCodes::key_LCONTROL) && input_isKeyDown(KeyCodes::key_LSHIFT) )
00207                 {
00208                         if( input_isKeyDown(KeyCodes::key_W) ) hasWon  = true;
00209                         if( input_isKeyDown(KeyCodes::key_L) ) hasLost = true;
00210                         if( input_isKeyDown(KeyCodes::key_R) ) { creditTimer = -1; youWin=youLose=false; }
00211                 }
00212 
00213                 if (hasLost) youLose = true;
00214                 if (hasWon)  youWin  = true;
00215                 if( hasWon || hasLost )
00216                         if( creditTimer==-1 ) creditTimer = 0;          
00217         }
00218         //------------------------------------------------------------------------------------
00219         int playerStrength(int playerNumber)
00220         {
00221                 int strength = 0;
00222                 Player* player(Helper::playerNumberToPlayerPointer(playerNumber));
00223                 if (player == 0)
00224                 {
00225                         static bool errorReported = false;
00226                         if (!errorReported)
00227                         {
00228                                 sys_console() << "ERROR!!! Helper::playerNumberToPlayerPointer(" << playerNumber << ") returned NULL" << endl;
00229                                 errorReported = true;
00230                         }
00231                         return 0;
00232                 }
00233 
00234                 int cityCount = Helper::totalCitiesForPlayer(player->color());
00235                 if(cityCount>0)  strength += player->bank().balance() / 1000;
00236                 strength += Helper::totalUnitsForPlayer(player->color());
00237                 strength += Helper::totalUnitsBeingBuiltForPlayer(player->color()) / 2;
00238                 strength += cityCount * 5;
00239                 return strength;
00240         }
00241         //------------------------------------------------------------------------------------
00242         void printPlayerList()
00243         {
00244                 vector<string> playerList(net_getAllPlayers());
00245                 //@param first playerNumber
00246                 //@param second playerStrength          
00247                 pair<int,int> maxPlayerStrength;
00248                 const FLOAT lineHeight = 0.037f;
00249                 int strength;
00250                 int totalPlayerStrength = 0;
00251                 static bool tauntSent = false;
00252                 for (uint i(0); i < playerList.size(); ++i)
00253                 {
00254                         int j = net_getPlayerNumUsingName( playerList[i] );
00255                         strength = playerStrength(j);
00256                         totalPlayerStrength += strength;
00257                         if (strength > maxPlayerStrength.second)
00258                         {
00259                                 maxPlayerStrength.second = strength;
00260                                 maxPlayerStrength.first = j;
00261                         }
00262                 }
00263 
00264                 for (uint i(0); i < playerList.size(); ++i)
00265                 {
00266                         Vec3D plyrColor( playerNumberToPlayerColor(i) );
00267                         string plyrName( net_getPlayerNameUsingNum(i) );
00268                         FLOAT plyrStr = playerStrength(i)*1.0f / totalPlayerStrength;
00269                         if( plyrName.length()>13 ) plyrName = plyrName.substr(0,12) + "-";
00270                         overlay_text() << plyrName;
00271                         overlay_textOut( Vec2D(0.01f, 0.043f+lineHeight*i), 0.8f, plyrColor, NULL, 7 );
00272                         overlay_rect( Vec2D( 0.13f,0.044f+lineHeight*i), Vec2D( 0.13f+plyrStr*0.068f, 0.038f+lineHeight*(i+1) ),
00273                                 true, Colors::gray, BlendModes::MIX, 0.6f, 6 );                 
00274                 }
00275 
00276                 if (maxPlayerStrength.second >= totalPlayerStrength && !tauntSent)
00277                 {
00278                         tauntSent = true;
00279                         stringstream sstr;
00280                         sstr << Helper::playerColorToPlayerName(Helper::playerNumberToPlayerColor(maxPlayerStrength.first)) << " says: ";
00281                         sstr << "I kicking your pfft you w00t!!!";
00282                         GameState::messagesReceived().addMessage(sstr.str());
00283 
00284                 }
00285 
00286                 int numPlayers = (int)net_getAllPlayers().size();               
00287                 overlay_rect( Vec2D(0,0.04f), Vec2D(0.2f,0.04f + lineHeight*numPlayers), true,                          // area box
00288                         Colors::green, BlendModes::MIX, 0.2f, 5 );
00289                 overlay_rect( Vec2D(0,0.04f), Vec2D(0.2f,0.04f + lineHeight*numPlayers), false,                         // outline box
00290                         Colors::gray, BlendModes::MIX, 0.4f, 5 );               
00291         }
00292         //------------------------------------------------------------------------------------
00293         void printBattleList()
00294         {
00295         }
00296         //------------------------------------------------------------------------------------
00297         void printTaunts()
00298         {
00299         }
00300         //------------------------------------------------------------------------------------
00301         void doTutorial()
00302         {
00303                 if (!GameState::battles().empty()) tutorial.battleMode();
00304                 if (GameState::battles().size() > 1) tutorial.twoBattlesAtOnce();
00305                 if (selectedCity) tutorial.city();
00306                 if (!selectedUnits.empty()) tutorial.unit();
00307         }
00308         //------------------------------------------------------------------------------------
00309         void sendMessageToPrintARandomNumberToTheConsole()
00310         {
00311                 stringstream sstr;
00312                 sstr << COMMAND_PRINT_A_RANDOM_NUMBER_TO_THE_CONSOLE << " " << COMMIT_TIME << " " << currGameTick + NETWORK_GAME_TICK_LAG;
00313                 net_send(sstr.str());
00314         }
00315         //------------------------------------------------------------------------------------
00316         bool playerExists(const string & player)
00317         {
00318                 vector<string> playerList(net_getAllPlayers());
00319                 for(vector<string>::iterator iter = playerList.begin(); iter != playerList.end(); ++iter)
00320                 {
00321                         string tmp(Helper::toLower(*iter));
00322                         if (tmp == player) return true;
00323                 }
00324                 return false;
00325         }
00326         //------------------------------------------------------------------------------------
00327         void processCommand(string command)
00328         {
00329                 const string WHOAMI("/whoami");
00330                 const string MORE_MONEY("/moremoney");
00331                 const string ABILITY_TO_CONTROL_EVERYTHING("/iamgod");
00332                 const string ABILITY_TO_CONTROL_ONLY_SELF("/godisdead");
00333                 const string PLAYER_LIST("/playerlist");
00334                 const string SEND_MONEY("/send");
00335                 string lowerCommand(Helper::toLower(command));
00336                 stringstream sstr(lowerCommand);
00337                 string first;
00338                 sstr >> first;
00339                 if (lowerCommand == WHOAMI)
00340                 {
00341                         GameState::messagesReceived().addMessage(lowerCommand + ':' + Helper::serialize(GameState::consolePlayer()->color()));
00342                 } else if (lowerCommand == MORE_MONEY)
00343                 {
00344                         stringstream sstr;
00345                         sstr << COMMAND_MORE_MONEY << " " << COMMIT_TIME << " " << currGameTick + NETWORK_GAME_TICK_LAG;
00346                         net_send(sstr.str());
00347                 } else if (lowerCommand == ABILITY_TO_CONTROL_EVERYTHING)
00348                 {
00349                         GameState::setControlMode(GOD);
00350                         GameState::messagesReceived().addMessage("God Mode Turned On");
00351                 } else if (lowerCommand == ABILITY_TO_CONTROL_ONLY_SELF)
00352                 {
00353                         selectedUnits.clear();
00354                         selectedCity = 0;
00355                         HUD::setSelectedCity(selectedCity = 0);
00356                         HUD::setSelectedUnit(0);
00357                         GameState::setControlMode(NORMAL);
00358                         GameState::messagesReceived().addMessage("God Mode Turned Off");
00359                 } else if (lowerCommand == PLAYER_LIST)
00360                 {
00361                         vector<string> playerList(net_getAllPlayers());
00362                         stringstream sstr;
00363                         sstr << "Player List:";
00364                         for(vector<string>::iterator iter = playerList.begin(); iter != playerList.end(); ++iter)
00365                         {
00366                                 sstr << *iter << ",";
00367                         }
00368                         GameState::messagesReceived().addMessage(sstr.str());
00369                 } else if (first == SEND_MONEY)
00370                 {
00371                         int amount;
00372                         sstr >> amount;
00373                         string to;
00374                         sstr >> to;
00375                         string player;
00376                         getline(sstr,player);
00377                         player = Helper::eatEarlyWhiteSpace(player);
00378                         if (sstr.bad() || to != "to")
00379                         {
00380                                 GameState::messagesReceived().addMessage("Invalid syntax for send money command");
00381                                 GameState::messagesReceived().addMessage("/send <amount> to <player>");
00382                         } else if (playerExists(player))
00383                         {
00384                                 if (GameState::consolePlayer()->bank().balance() >= amount)
00385                                 {
00386                                         if (amount < 0)
00387                                         {
00388                                                 GameState::messagesReceived().addMessage("You cannot send a negative amount of money");
00389                                         } else
00390                                         {
00391                                                 GameState::consolePlayer()->bank().withdraw(amount);
00392                                                 stringstream netOut;
00393                                                 netOut << COMMAND_SEND_MONEY << " " << COMMIT_TIME << " " << currGameTick + NETWORK_GAME_TICK_LAG << " " 
00394                                                         << amount << " " << player;
00395                                                 net_send(netOut.str());
00396                                                 GameState::messagesReceived().addMessage("Money sent");
00397                                         }
00398                                 } else
00399                                 {
00400                                         GameState::messagesReceived().addMessage("you do not have enough money");
00401                                 }
00402                         } else
00403                         {
00404                                 GameState::messagesReceived().addMessage("player:" + player + " does not exist");
00405                         }
00406                 } else
00407                 {
00408                         GameState::messagesReceived().addMessage(lowerCommand + " : is an unknown command");
00409                 }
00410         }
00411         //------------------------------------------------------------------------------------
00412         void printAllMilitaryUnits(void)
00413         {
00414                 sys_console() << "printAllMilitaryUnits begin:" << endl;
00415                 for(vector<MilitaryUnit*>::iterator iter = units.begin(); iter != units.end(); ++iter)
00416                 {
00417                         sys_console() << (*iter)->uniqueID() << endl;
00418                 }
00419                 sys_console() << "printAllMilitaryUnits End" << endl;
00420         }
00421         //------------------------------------------------------------------------------------
00423         void deleteMilitaryUnit(MilitaryUnit* unit)
00424         {
00425                 DrawableIter dIter( find(drawableObjects.begin(), drawableObjects.end(), unit) );
00426                 assert(dIter != drawableObjects.end());
00427                 UnitIter uIter( find(units.begin(), units.end(), unit));
00428                 assert(uIter != units.end());
00429                 units.erase(uIter);
00430                 drawableObjects.erase(dIter);
00431                 uIter = find(selectedUnits.begin(), selectedUnits.end(), unit);
00432                 if (uIter != selectedUnits.end()) selectedUnits.erase(uIter);
00433                 battleCircleAnimation.push_back( BattleSprite(unit->position(), 50, BattleSpriteTypes::EXPLO_LARGE));
00434                 delete unit;
00435         }
00436         //------------------------------------------------------------------------------------
00438         void deleteCity(CityIter iter)
00439         {
00440                 City* tmp(*iter);
00441                 cities.erase(iter);
00442                 delete tmp;
00443         }
00444         //------------------------------------------------------------------------------------
00445         // add unit to the set of selected units.  ensure no duplicates.
00446         // returns whether the add was successful (no dup)
00447         bool addUnitToSelection(MilitaryUnit *u)
00448         {
00449                 selectedCity = 0;
00450                 HUD::setSelectedCity(selectedCity);
00451                 bool exists = false;
00452                 for(vector<MilitaryUnit*>::iterator mIter = selectedUnits.begin(); mIter != selectedUnits.end(); ++mIter)
00453                 {
00454                         if (*mIter == u) exists = true;
00455                 }
00456                 if (!exists) 
00457                 {
00458                         selectedUnits.push_back(u);
00459                         HUD::setSelectedUnit(u);
00460                         return true;
00461                 }
00462 
00463                 return false;
00464         }
00465         //------------------------------------------------------------------------------------
00466         bool amIInThisBattle(BattleEntry* entry)
00467         {
00468                 if (entry->getTeamAColor() == GameState::consolePlayer()->color()) return true;
00469                 else if (entry->getTeamBColor() == GameState::consolePlayer()->color()) return true;
00470                 else return false;
00471         }
00472         //------------------------------------------------------------------------------------
00473         void setSelectedUnits(int key)
00474         {
00475                 for(vector<MilitaryUnit*>::iterator iter(GameState::units().begin()); iter != GameState::units().end(); ++iter)
00476                 {
00477                         if ((*iter)->shortcutKey() == key) (*iter)->setShortcutKey(-1);
00478                 }
00479                 for(vector<MilitaryUnit*>::iterator iter(selectedUnits.begin()); iter != selectedUnits.end(); ++iter)
00480                 {
00481                         (*iter)->setShortcutKey(key);
00482                 }
00483         }
00484         //------------------------------------------------------------------------------------
00485         void getSelectedUnits(int key)
00486         {
00487                 selectedCity = 0;
00488                 HUD::setSelectedCity(0);
00489                 selectedUnits.clear();
00490                 for(vector<MilitaryUnit*>::iterator iter(GameState::units().begin()); iter != GameState::units().end(); ++iter)
00491                 {
00492                         if ((*iter)->shortcutKey() == key) selectedUnits.push_back(*iter);
00493                 }
00494         }
00495         //------------------------------------------------------------------------------------
00497         void processOverheadInput(void)
00498         {
00499                 if (!GameState::battles().empty()) tutorial.overheadWhileBattle();
00500                 if (HUD::processOverheadInput()) return;
00501 
00502                 Vec2D mouse2D( input_getMouseX(), input_getMouseY() );
00503                 Vec3D mouse3D( math_translateScreenToWorldPlane( mouse2D, 0.0f) );
00504 
00505                 // players & battles list
00506                 Box but1( 0,0,   0.07f,0.04f );
00507                 //Box but2( 0.077f,0, 0.16f,0.04f);
00508                 Box but3( 0.161f,0, 0.20f,0.04f);
00509                 if( input_isMouseLBClicked() )
00510                 {
00511                         if( but1.isContain(mouse2D)) { playersNBattleListMode = MODE_PLAYERS_LIST;      return; }
00512                         //if( but2.isContain(mouse2D)) { playersNBattleListMode = MODE_BATTLES_LIST;    return; }
00513                         if( but3.isContain(mouse2D)) { playersNBattleListMode = MODE_NONE;                      return; }
00514                 }
00515                 if( input_isKeyPressed(KeyCodes::key_F1)) { playersNBattleListMode = MODE_PLAYERS_LIST; return; }
00516                 //if( input_isKeyPressed(KeyCodes::key_F2)) { playersNBattleListMode = MODE_BATTLES_LIST;       return; }
00517                 if( input_isKeyPressed(KeyCodes::key_F2)) { playersNBattleListMode = MODE_NONE;                 return; }
00518 
00519                 // camera control
00520                 camHeight = 10.0f + 180.0f * (1 - input_getMouseWheel());
00521                 if( input_getMouseX()<0.01f ) GameState::camTarget().x -= 2.5f;
00522                 if( input_getMouseX()>0.98f ) GameState::camTarget().x += 2.5f;
00523                 if( input_getMouseY()<0.01f ) GameState::camTarget().y -= 2.5f;
00524                 if( input_getMouseY()>0.98f ) GameState::camTarget().y += 2.5f; 
00525                 if( input_isKeyDown(KeyCodes::key_DOWN  ) ) GameState::camTarget().y += 5.5f;
00526                 if( input_isKeyDown(KeyCodes::key_UP    ) ) GameState::camTarget().y -= 5.5f;
00527                 if( input_isKeyDown(KeyCodes::key_LEFT  ) ) GameState::camTarget().x -= 5.5f;
00528                 if( input_isKeyDown(KeyCodes::key_RIGHT ) ) GameState::camTarget().x += 5.5f;   
00529                 if (GameState::camTarget().x > 400) GameState::camTarget().x = 400;
00530                 if (GameState::camTarget().y > 440) GameState::camTarget().y = 440;
00531                 if (GameState::camTarget().x < -400) GameState::camTarget().x = -400;
00532                 if (GameState::camTarget().y < -400) GameState::camTarget().y = -400;
00533                 camera_set( GameState::camTarget()+Vec3D(0.0f,60.0f+camHeight*0.4f,20.0f+camHeight), GameState::camTarget(), 0 );
00534 
00535                 if( input_isMouseRBClicked() ) 
00536                 {
00537                         // only give move order if the goal position is within the bounds of the map
00538                         if( GameState::worldMap().bounds.contains(Vec2D(mouse3D.x, mouse3D.y)) )
00539                         {
00540                                 if( selectedUnits.size()>0 ) Sound::playRandomSound(Sound::CLASS_ACK);
00541                                 for(vector<MilitaryUnit*>::iterator iter = selectedUnits.begin(); iter != selectedUnits.end(); ++iter)
00542                                 {
00543                                         stringstream sstr;
00544                                         sstr << COMMAND_OVERHEAD << " " << COMMIT_TIME << " " << currGameTick + NETWORK_GAME_TICK_LAG << " " << COMMAND_GOAL << " "
00545                                                 << (*iter)->uniqueID() << " " << serialize(mouse3D);
00546                                         net_send(sstr.str());                           
00547                                 }
00548                                 if (selectedCity) 
00549                                 {
00550                                         stringstream sstr;
00551                                         sstr << COMMAND_OVERHEAD << " " << COMMIT_TIME << " " << currGameTick + NETWORK_GAME_TICK_LAG << " " << 
00552                                                 COMMAND_SET_RALLY_POINT << " " << selectedCity->uniqueID() << " " << serialize(mouse3D);
00553                                         net_send(sstr.str());
00554                                 }
00555                         }
00556                 }
00557                 // should only select a unit or a city, if its your own or god mode is on
00558                 Player* plyr = GameState::consolePlayer();
00559                 ControlMode controlMode = GameState::controlMode();
00560 
00561                 // unit selection (by direct clicking)
00562                 if (input_isMouseLBClicked() ) {
00563                         if (!input_isKeyDown(KeyCodes::key_LSHIFT) && !input_isKeyDown(KeyCodes::key_RSHIFT))
00564                         {
00565                                 selectedUnits.clear();
00566                         }
00567                         bool isSelected = false;
00568                         for(UnitIter iter = units.begin(); iter != units.end(); ++iter) 
00569                         {
00570                                 bool permissionCheck = ((*iter)->color() == plyr->color()) || (controlMode == GOD);
00571                                 if ((*iter)->contains(mouse3D) && permissionCheck)                                      
00572                                 {
00573                                         if( addUnitToSelection(*iter) ) 
00574                                         {
00575                                                 isSelected = true;
00576                                                 break;
00577                                         }
00578                                 }
00579                         }
00580                         if(isSelected) Sound::playRandomSound(Sound::CLASS_SELECT);
00581 
00582                         for(CityIter iter = cities.begin(); iter != cities.end(); ++iter)                       // city selection
00583                         {
00584                                 bool permissionCheck = ((*iter)->color() == plyr->color()) || (controlMode == GOD);
00585                                 if ((*iter)->contains(mouse2D) && permissionCheck)
00586                                 {
00587                                         selectedUnits.clear();
00588                                         selectedCity = *iter;
00589                                         HUD::setSelectedCity(selectedCity);
00590                                         HUD::setSelectedUnit(0);
00591                                 }
00592                         }
00593                 }
00594 
00595                 // drag-select
00596                 if( input_isMouseLBDown() && !dragging )                                // start dragging
00597                 {
00598                         dragging = true;
00599                         dragCorner = mouse2D;
00600                 }
00601                 else if( !input_isMouseLBDown() && dragging )                   // finish dragging
00602                 {
00603                         dragging = false;
00604                         if( math_dist2D(dragCorner,mouse2D) > 0.03f )           // make sure it's a drag and not just a click
00605                         {
00606                                 if (!input_isKeyDown(KeyCodes::key_LSHIFT) && !input_isKeyDown(KeyCodes::key_RSHIFT))
00607                                         selectedUnits.clear();
00608 
00609                                 Box b;
00610                                 b.top    = min( dragCorner.y, mouse2D.y );
00611                                 b.bottom = max( dragCorner.y, mouse2D.y );
00612                                 b.left   = min( dragCorner.x, mouse2D.x );
00613                                 b.right  = max( dragCorner.x, mouse2D.x );
00614                                 bool isSelected = false;
00615                                 for(UnitIter iter = units.begin(); iter != units.end(); ++iter)
00616                                 {
00617                                         bool permissionCheck = ((*iter)->color() == plyr->color()) || (controlMode == GOD);
00618                                         if( !permissionCheck ) continue;
00619                                         Vec3D unitPos3D( (*iter)->position() );
00620                                         Vec2D unitPos2D( math_translateWorldToScreen(unitPos3D) );
00621                                         if ( b.isContain(unitPos2D) )
00622                                         {
00623                                                 addUnitToSelection(*iter);
00624                                                 isSelected = true;
00625                                         }
00626                                 }
00627                                 if(isSelected) Sound::playRandomSound(Sound::CLASS_SELECT);
00628                         }
00629                 }
00630 
00631                 // what unit to build
00632                 if (selectedCity)
00633                 {
00634                         if (input_isKeyPressed(KeyCodes::key_L) ) 
00635                         {
00636                                 sendBuildMessage( COMMAND_BUILD_LIGHTTANK, selectedCity->uniqueID() );
00637                         } else if (input_isKeyPressed(KeyCodes::key_H) ) {
00638                                 sendBuildMessage( COMMAND_BUILD_HEAVYTANK, selectedCity->uniqueID() );
00639                         } else if (input_isKeyPressed(KeyCodes::key_R) ) {
00640                                 sendBuildMessage( COMMAND_BUILD_ROCKET_LAUNCHER, selectedCity->uniqueID() );
00641                         } else if (input_isKeyPressed(KeyCodes::key_A) ) {
00642                                 sendBuildMessage( COMMAND_BUILD_ARTILLERY, selectedCity->uniqueID() );
00643                         } else if (input_isKeyPressed(KeyCodes::key_J) ) {
00644                                 sendBuildMessage( COMMAND_BUILD_JET, selectedCity->uniqueID() );
00645                         }
00646                 }
00647 
00648                 if (input_isMouseLBDblClicked())
00649                 {
00650                         for(vector<BattleEntry*>::iterator iter = GameState::battles().begin(); iter != GameState::battles().end(); ++iter)
00651                         {
00652                                 if ((*iter)->contains(mouse3D) && amIInThisBattle(*iter)) 
00653                                 {
00654                                         GameState::setActiveBattle(*iter);
00655                                         HUD::setSelectedCity(NULL);
00656                                         HUD::setSelectedUnit(NULL);
00657                                         break; /*So the first battle found is the one we go with*/
00658                                 }
00659                         }
00660                 }
00661 
00662                 if (input_isKeyDown(KeyCodes::key_LCONTROL) || input_isKeyDown(KeyCodes::key_RCONTROL))
00663                 {
00664                         if (input_isKeyPressed(KeyCodes::key_0)) setSelectedUnits(KeyCodes::key_0);
00665                         else if (input_isKeyPressed(KeyCodes::key_1)) setSelectedUnits(KeyCodes::key_1);
00666                         else if (input_isKeyPressed(KeyCodes::key_2)) setSelectedUnits(KeyCodes::key_2);
00667                         else if (input_isKeyPressed(KeyCodes::key_3)) setSelectedUnits(KeyCodes::key_3);
00668                         else if (input_isKeyPressed(KeyCodes::key_4)) setSelectedUnits(KeyCodes::key_4);
00669                         else if (input_isKeyPressed(KeyCodes::key_5)) setSelectedUnits(KeyCodes::key_5);
00670                         else if (input_isKeyPressed(KeyCodes::key_6)) setSelectedUnits(KeyCodes::key_6);
00671                         else if (input_isKeyPressed(KeyCodes::key_7)) setSelectedUnits(KeyCodes::key_7);
00672                         else if (input_isKeyPressed(KeyCodes::key_8)) setSelectedUnits(KeyCodes::key_8);
00673                         else if (input_isKeyPressed(KeyCodes::key_9)) setSelectedUnits(KeyCodes::key_9);
00674                 } else
00675                 {
00676                         if (input_isKeyPressed(KeyCodes::key_0)) getSelectedUnits(KeyCodes::key_0);
00677                         else if (input_isKeyPressed(KeyCodes::key_1)) getSelectedUnits(KeyCodes::key_1);
00678                         else if (input_isKeyPressed(KeyCodes::key_2)) getSelectedUnits(KeyCodes::key_2);
00679                         else if (input_isKeyPressed(KeyCodes::key_3)) getSelectedUnits(KeyCodes::key_3);
00680                         else if (input_isKeyPressed(KeyCodes::key_4)) getSelectedUnits(KeyCodes::key_4);
00681                         else if (input_isKeyPressed(KeyCodes::key_5)) getSelectedUnits(KeyCodes::key_5);
00682                         else if (input_isKeyPressed(KeyCodes::key_6)) getSelectedUnits(KeyCodes::key_6);
00683                         else if (input_isKeyPressed(KeyCodes::key_7)) getSelectedUnits(KeyCodes::key_7);
00684                         else if (input_isKeyPressed(KeyCodes::key_8)) getSelectedUnits(KeyCodes::key_8);
00685                         else if (input_isKeyPressed(KeyCodes::key_9)) getSelectedUnits(KeyCodes::key_9);
00686                 }
00687 
00689                 //if( input_isKeyDown(KeyCodes::key_LCONTROL) && input_isKeyPressed(KeyCodes::key_M) )
00690                 //      showThreatMap = !showThreatMap;
00691         }
00692         //------------------------------------------------------------------------------------
00694         void processInput(void)
00695         {
00696                 if(GameState::activeBattle()) GameState::activeBattle()->input();
00697                 else processOverheadInput();
00698         }
00699         //------------------------------------------------------------------------------------
00701         void updateUnits(void)
00702         {
00703                 for(UnitIter iter = units.begin(); iter != units.end(); ++iter) (*iter)->move();
00704         }
00705         //------------------------------------------------------------------------------------
00707         void updateCities(void)
00708         {
00709                 for(CityIter iter = cities.begin(); iter != cities.end(); ++iter) {
00710                         (*iter)->update();
00711                 }
00712         }
00713         //------------------------------------------------------------------------------------
00715         void deleteBattleEntry(BattleIter iter)
00716         {
00717                 BattleEntry* tmp(*iter);
00718                 battles.erase(iter);
00719                 delete tmp;
00720         }
00721         //------------------------------------------------------------------------------------
00723         void updateBattleEntries(void)
00724         {
00725                 bool done = false;
00726                 for(BattleIter iter = battles.begin(); iter != battles.end() && !done; ++iter) 
00727                 {
00728                         (*iter)->update();
00729                         if((*iter)->isBattleFinished() ) 
00730                         {
00731                                 if( *iter == GameState::activeBattle() ) GameState::setActiveBattle(0);
00732 
00733                                 // one side, (the losing side), will have at most a group of jets to send back. so we
00734                                 // need to create the units for both sides.
00735                                 for(vector<Int3Tuple>::iterator unitIter = (*iter)->teamAGroups.begin(); unitIter != (*iter)->teamAGroups.end(); ++unitIter)
00736                                 {
00737                                         switch (unitIter->a)
00738                                         {
00739                                         case UnitTypes::LIGHT_TANK:
00740                                                 GameState::addMilitaryUnit(new LightTank(Vec3D((*iter)->getBattleLocation().x,(*iter)->getBattleLocation().y,0.0f), 
00741                                                         GameState::findPlayer((*iter)->getTeamAColor()), unitIter->b));
00742                                                 (*GameState::units().rbegin())->setShortcutKey(unitIter->c);
00743                                                 break;
00744                                         case UnitTypes::HEAVY_TANK:
00745                                                 GameState::addMilitaryUnit(new HeavyTank(Vec3D((*iter)->getBattleLocation().x,(*iter)->getBattleLocation().y,0.0f), 
00746                                                         GameState::findPlayer((*iter)->getTeamAColor()), unitIter->b ));
00747                                                 (*GameState::units().rbegin())->setShortcutKey(unitIter->c);
00748                                                 break;
00749                                         case UnitTypes::LAUNCHER:
00750                                                 GameState::addMilitaryUnit(new RocketLauncher(Vec3D((*iter)->getBattleLocation().x,(*iter)->getBattleLocation().y,0.0f), 
00751                                                         GameState::findPlayer((*iter)->getTeamAColor()), unitIter->b));
00752                                                 (*GameState::units().rbegin())->setShortcutKey(unitIter->c);
00753                                                 break;
00754                                         case UnitTypes::ARTILLERY:
00755                                                 GameState::addMilitaryUnit(new Artillery(Vec3D((*iter)->getBattleLocation().x,(*iter)->getBattleLocation().y,0.0f), 
00756                                                         GameState::findPlayer((*iter)->getTeamAColor()), unitIter->b ));
00757                                                 (*GameState::units().rbegin())->setShortcutKey(unitIter->c);
00758                                                 break;
00759                                         case UnitTypes::JET:
00760                                                 {
00761                                                         City* c = GameState::getCity(unitIter->c);
00762                                                         if (c->color() == (*iter)->getTeamAColor())
00763                                                         {
00764                                                                 GameState::addMilitaryUnit(new Jet(c->position(), 
00765                                                                         GameState::findPlayer((*iter)->getTeamAColor()), unitIter->b, unitIter->c));
00766                                                         }
00767                                                         break;
00768                                                 }
00769                                         default:
00770                                                 sys_console() << "ERROR!!!" << " Programming Error: invalid unit!" << endl;
00771                                         }
00772                                 }
00773 
00774                                 for(vector<Int3Tuple>::iterator unitIter = (*iter)->teamBGroups.begin(); unitIter != (*iter)->teamBGroups.end(); ++unitIter)
00775                                 {
00776                                         switch (unitIter->a)
00777                                         {
00778                                         case UnitTypes::LIGHT_TANK:
00779                                                 GameState::addMilitaryUnit(new LightTank(Vec3D((*iter)->getBattleLocation().x,(*iter)->getBattleLocation().y,0.0f), 
00780                                                         GameState::findPlayer((*iter)->getTeamBColor()), unitIter->b));
00781                                                 (*GameState::units().rbegin())->setShortcutKey(unitIter->c);
00782                                                 break;
00783                                         case UnitTypes::HEAVY_TANK:
00784                                                 GameState::addMilitaryUnit(new HeavyTank(Vec3D((*iter)->getBattleLocation().x,(*iter)->getBattleLocation().y,0.0f), 
00785                                                         GameState::findPlayer((*iter)->getTeamBColor()), unitIter->b ));
00786                                                 (*GameState::units().rbegin())->setShortcutKey(unitIter->c);
00787                                                 break;
00788                                         case UnitTypes::LAUNCHER:
00789                                                 GameState::addMilitaryUnit(new RocketLauncher(Vec3D((*iter)->getBattleLocation().x,(*iter)->getBattleLocation().y,0.0f), 
00790                                                         GameState::findPlayer((*iter)->getTeamBColor()), unitIter->b));
00791                                                 (*GameState::units().rbegin())->setShortcutKey(unitIter->c);
00792                                                 break;
00793                                         case UnitTypes::ARTILLERY:
00794                                                 GameState::addMilitaryUnit(new Artillery(Vec3D((*iter)->getBattleLocation().x,(*iter)->getBattleLocation().y,0.0f), 
00795                                                         GameState::findPlayer((*iter)->getTeamBColor()), unitIter->b ));
00796                                                 (*GameState::units().rbegin())->setShortcutKey(unitIter->c);
00797                                                 break;
00798                                         case UnitTypes::JET:
00799                                                 {
00800                                                         City* c = GameState::getCity(unitIter->c);
00801                                                         if (c->color() == (*iter)->getTeamBColor())
00802                                                         {
00803                                                                 GameState::addMilitaryUnit(new Jet(c->position(), 
00804                                                                         GameState::findPlayer((*iter)->getTeamBColor()), unitIter->b, unitIter->c));
00805                                                         }
00806                                                         break;
00807                                                 }
00808                                         default:
00809                                                 sys_console() << "ERROR!!!" << " Programming Error: invalid unit!" << endl;
00810                                         }
00811                                 }
00812 
00813                                 deleteBattleEntry(iter);
00814                                 done = true;
00815                         }
00816                 }
00817 
00818         }
00819         //------------------------------------------------------------------------------------
00821         void updatePlayers()
00822         {
00823                 for(PlayerIter iter=players.begin(); iter != players.end(); ++iter)     (*iter)->update();
00824         }
00825         //------------------------------------------------------------------------------------
00827         void deletePlayer(PlayerIter iter)
00828         {
00829                 Player* tmp(*iter);
00830                 players.erase(iter);
00831                 delete tmp;
00832         }
00833         //------------------------------------------------------------------------------------
00834         // grab units of the same side as '*unit'
00835         // the limit is 8 ground units and 4 jets
00836         vector<MilitaryUnit*> getSurroundingUnits(MilitaryUnit* unit)
00837         {
00838                 vector<MilitaryUnit*> result;
00839                 result.push_back(unit);
00840                 int numGrounds = 1;
00841                 int numJets        = 0;
00842                 for(UnitIter unitIter(GameState::units().begin()); unitIter != GameState::units().end(); ++unitIter)
00843                 {
00844                         if (unit->color() != (*unitIter)->color() || unit == *unitIter) continue;
00845                         if((*unitIter)->unitType()==UnitTypes::JET )                            // jets
00846                         {
00847                                 if( math_distPlanar3D(unit->position(), (*unitIter)->position()) >= 300.0f ) continue;
00848                                 if( numJets >= 4 ) continue;
00849                                 numJets++;
00850                                 result.push_back(*unitIter);
00851                         }
00852                         else                                                                                            // ground units
00853                         {
00854                                 if( math_distPlanar3D(unit->position(), (*unitIter)->position()) >= 100.0f ) continue;
00855                                 if( numGrounds >= 8 ) continue;
00856                                 numGrounds++;
00857                                 result.push_back(*unitIter);
00858                         }
00859                 }
00860                 return result;
00861         }
00862         //------------------------------------------------------------------------------------
00866         void doCollisionDetection(void)
00867         {
00868                 bool done = false;
00869                 for(UnitIter iter(units.begin()); iter != units.end() && !done; ++iter) 
00870                 {
00871                         //Do collision detection against other units
00872                         for(UnitIter secondIter(iter+1); secondIter < units.end() && !done; ++secondIter) 
00873                         {
00874                                 assert(iter != secondIter && "Programming Error");
00875                                 if ((*iter)->fightingCollision(*secondIter) && (*iter)->color() != (*secondIter)->color()
00876                                         && (*iter)->unitType()!=UnitTypes::JET && (*secondIter)->unitType()!=UnitTypes::JET )
00877                                 {
00878                                         vector<MilitaryUnit*> teamA(getSurroundingUnits(*iter));
00879                                         vector<MilitaryUnit*> teamB(getSurroundingUnits(*secondIter));
00880                                         battles.push_back(new BattleEntry( (*teamA.begin())->color(), (*teamB.begin())->color(), 
00881                                                 Vec2D(((*teamA.begin())->position().x+(*teamB.begin())->position().x)/2, 
00882                                                 ((*teamA.begin())->position().y+(*teamB.begin())->position().y)/2) ));
00883                                         for(UnitIter unitIter(teamA.begin()); unitIter != teamA.end(); ++unitIter)
00884                                         {
00885                                                 int cityID = 0;
00886                                                 if( (*unitIter)->unitType()==UnitTypes::JET ) cityID = ((Jet*)(*unitIter))->getCityID();
00887                                                 else cityID = (*unitIter)->shortcutKey();
00888                                                 (*battles.rbegin())->teamAGroups.push_back( Int3Tuple( (*unitIter)->unitType(), (*unitIter)->armySize(), cityID ) );
00889                                                 deleteMilitaryUnit(*unitIter);
00890                                         }
00891                                         for(UnitIter unitIter(teamB.begin()); unitIter != teamB.end(); ++unitIter)
00892                                         {
00893                                                 int cityID = 0;
00894                                                 if( (*unitIter)->unitType()==UnitTypes::JET ) cityID = ((Jet*)(*unitIter))->getCityID();
00895                                                 else cityID = (*unitIter)->shortcutKey();
00896                                                 (*battles.rbegin())->teamBGroups.push_back( Int3Tuple( (*unitIter)->unitType(), (*unitIter)->armySize(), cityID ) );
00897                                                 deleteMilitaryUnit(*unitIter);
00898                                         }
00899                                         selectedUnits.clear();
00900                                         HUD::clearSelections();
00901                                         // only set active battle if the console player is involved
00902                                         if( (*battles.rbegin())->isFoughtBy(GameState::consolePlayer()->color()))
00903                                         {
00904                                                 if (GameState::activeBattle() == 0) GameState::setActiveBattle( *battles.rbegin() );
00905                                                 else 
00906                                                 {
00907                                                         stringstream sstr;
00908                                                         sstr << "You just entered another battle with ";
00909                                                         if ( (*battles.rbegin())->getTeamAColor() != GameState::consolePlayer()->color())
00910                                                         {
00911                                                                 sstr << Helper::playerColorToPlayerName((*battles.rbegin())->getTeamAColor());
00912                                                         } else sstr << Helper::playerColorToPlayerName((*battles.rbegin())->getTeamBColor());
00913                                                         GameState::messagesReceived().addMessage(sstr.str());
00914                                                         static counter = 5;
00915                                                         if (--counter > 0) GameState::messagesReceived().addMessage("Press space to go to this battle");
00916                                                         Sound::play(Sound::MSG_ANOTHER_BATTLE_IS_HAPPENING, 1.0f);
00917                                                 }
00918                                         }
00919                                         done = true;
00920                                 }
00921                         }
00922                         //Do collision detection against the cities
00923                         for(CityIter cityIter(cities.begin()); cityIter < cities.end() && !done; ++cityIter) 
00924                         {
00925                                 if((*cityIter)->color() != (*iter)->color() && (*cityIter)->collision(*iter) && (*iter)->unitType() != UnitTypes::JET) 
00926                                 {
00927                                         (*cityIter)->changeOwner( (*iter)->owner(), true );
00928                                         done = true;
00929                                 }
00930                         }
00931                 }
00932         }
00933         //------------------------------------------------------------------------------------
00936         void doAI() 
00937         {
00938                 //pAiPlayer->update();
00939         }
00940         //------------------------------------------------------------------------------------
00944         void loadMap(string &file)
00945         {
00946                 ifstream inFile(file.data());
00947                 if(!inFile) throw Error(string("Map not found: ")+file);
00948 
00949                 while(!inFile.eof())
00950                 {
00951                         string line;
00952                         getline(inFile, line);
00953                         if( line.find(Map::TOK_COMMENT) != string::npos ) { } // do nothing
00954                         else if( line.find(Map::TOK_MAP_DIMS) != string::npos)
00955                         {
00956                                 Map::WorldMap wm = Map::createWorldMap(line.substr(Map::TOK_MAP_DIMS.size()));
00957                                 GameState::setWorldMap(wm);
00958                                 HUD::setWorldMap(wm);
00959                         }
00960                         else if( line.find(Map::TOK_CREATE_UNIT) != string::npos )
00961                                 GameState::addMilitaryUnit(Map::createUnit(line.substr(Map::TOK_CREATE_UNIT.size())));
00962                         else if( line.find(Map::TOK_CREATE_CITY) != string::npos )
00963                                 GameState::addCity(Map::createCity(line.substr(Map::TOK_CREATE_CITY.size())));
00964                 }
00965         }
00966         //------------------------------------------------------------------------------------
00967         string& stripComments(string& str)
00968         {
00969                 size_t start;
00970                 size_t end;
00971                 while( (start = str.find("//")) != string::npos )
00972                 {
00973                         end = str.find("\n", start)+1;
00974                         str.erase(start, end-start);
00975                 }
00976                 return str;
00977         }
00978         //------------------------------------------------------------------------------------
00979         void initData()
00980         {
00981                 ifstream fileIn("data.txt");
00982                 if(!fileIn) throw Error("Cannot open data file: data.txt");
00983 
00984                 ostringstream fileDump;
00985 
00986                 fileDump << fileIn.rdbuf();
00987                 string file = stripComments(fileDump.str());
00988 
00989                 size_t start = file.find(EconData::TOK_BEGIN_DATA)+EconData::TOK_BEGIN_DATA.size();
00990                 size_t len = file.find(EconData::TOK_END_DATA) - start;
00991                 EconData::getObj().initData(istringstream(file.substr(start, len)));
00992 
00993                 start = file.find(BattleUnitData::TOK_BEGIN_DATA)+BattleUnitData::TOK_BEGIN_DATA.size();
00994                 len = file.find(BattleUnitData::TOK_END_DATA) - start;
00995                 BattleUnitData::getObj().initData(istringstream(file.substr(start, len)));
00996         }
00997         //------------------------------------------------------------------------------------
00998         void initHUD()
00999         {
01000                 ifstream fileIn("HUD.txt");
01001                 if(!fileIn) throw Error("Cannot open HUD init file: HUD.txt");
01002                 ostringstream fileDump;
01003 
01004                 fileDump << fileIn.rdbuf();
01005                 string file = stripComments(fileDump.str());
01006                 HUD::init(istringstream(file));
01007         }
01008         //------------------------------------------------------------------------------------
01010         void overhead_init()
01011         {
01012                 GameConfig gc("config.txt");
01013 
01014                 sys_console() << "atan(1,0): " << atan2f(1.0f, 0.0f) << endl;
01015                 sys_console() << "atan(0,1): " << atan2f(0.0f, 1.0f) << endl;
01016                 sys_console() << "atan(-1,0): " << atan2f(-1.0f, 0.0f) << endl;
01017                 sys_console() << "atan(0,-1): " << atan2f(0.0f, -1.0f) << endl;
01018 
01019                 initData();
01020                 initHUD();
01021 
01022                 loadMap(gc.mapFileName);
01023 
01024                 creditTimer = -1;
01025                 youWin = youLose = false;
01026                 showConfirmQuitMenu = false;
01027 
01028                 City* pPlayerCity = 0;
01029 
01030                 Vec3D colors[8] = {Colors::red, Colors::blue, Colors::green, Colors::yellow, 
01031                         Colors::cyan, Colors::white, Colors::black, Colors::magenta};
01032                 // is this a single player game?
01033                 int consolePlayerNum = net_getPlayerNumber();
01034                 if( consolePlayerNum == -1 )
01035                 {
01036                         // single player init
01037                         Player* p = new Player(Colors::blue, gc.initPlayerBalance, units, cities);
01038                         GameState::setConsolePlayer(p);
01039                         players.push_back(p);
01040                         HUD::setPlayer(p);
01041                         pPlayerCity = cities[0];
01042                         // set one city to be players color, the rest neutral
01043                         cities[0]->changeOwner(p);
01044                         // create more players to help with testing purposes
01045                         p = new Player(Colors::red, gc.initPlayerBalance, units, cities);
01046                         players.push_back(p);
01047                         cities[1]->changeOwner(p);
01048                         p = new Player(Colors::green, gc.initPlayerBalance, units, cities);
01049                         players.push_back(p);
01050                         cities[2]->changeOwner(p);
01051                         GameState::setControlMode(GOD);
01052                         GameState::messagesReceived().addMessage("God Mode Turned On");
01053                 }
01054                 else
01055                 {
01056                         // multiplayer init
01057                         vector<string> &names = net_getAllPlayers();
01058                         players.resize( names.size() );
01059                         for(size_t i = 0; i < names.size(); ++i)
01060                         {
01061                                 if(i == consolePlayerNum )
01062                                 {
01063                                         Player* p = new Player(colors[consolePlayerNum], gc.initPlayerBalance, units, cities);
01064                                         GameState::setConsolePlayer(p);
01065                                         players[consolePlayerNum] = p;                                  
01066                                         HUD::setPlayer(p);
01067                                         pPlayerCity = cities[i];
01068                                 }
01069                                 else
01070                                 {       
01071                                         int playerNum = net_getPlayerNumUsingName(names[i]);
01072                                         Vec3D playerColor( colors[playerNum] );
01073                                         players[playerNum] = new Player(playerColor, gc.initPlayerBalance, units, cities);
01074                                 }                               
01075                         }
01076                         for(size_t i = 0; i < names.size(); ++i)
01077                                 GameState::cities()[i]->changeOwner(players[i]);
01078 
01079                         for( UINT i=0; i<GameState::cities().size(); i++ )
01080                         {
01081                                 if( GameState::cities()[i]->owner() )
01082                                 {
01083                                         Vec3D c = GameState::cities()[i]->owner()->color();
01084                                         sys_console() << "City #" << i << " " << c.x << " " << c.y << " " << c.z << endl;
01085                                 }
01086                         }
01087 
01088                 }
01089 
01090                 selectedUnits.clear();
01091 
01092                 Sound::playMusic(Sound::SMPL_SONG_WAR_WORLDS);
01093 
01094                 camHeight = 100.0f;
01095                 // focus camera on player city
01096                 GameState::camTarget().x = pPlayerCity->position().x;
01097                 GameState::camTarget().y = pPlayerCity->position().y;
01098                 dragging = false;
01099 
01100                 transitionTimeRemaining = -1;
01101                 prevBattle = NULL;
01102 
01103                 unitMaintenance.setHelpString("Unit Maintenance Cost:\n 0-14 100% Income\n15-24 50% Income\n25+    10% Income");
01104                 GameState::availableRFM().resize(5);
01105 
01106                 playersNBattleListMode = MODE_PLAYERS_LIST;
01107         }
01108         //------------------------------------------------------------------------------------
01110         void overhead_shutdown()
01111         {
01112                 //This might be an inefficient way of deallocating the units.  But it is quick and easy.  If exiting the program ever takes to long
01113                 //then consider changing this or only turning this on during a debug build.
01114                 while(!units.empty()) deleteMilitaryUnit(*units.begin());
01115                 while(!cities.empty()) deleteCity(cities.begin());
01116                 while(!battles.empty()) deleteBattleEntry(battles.begin());
01117                 delete Globals::artWork;
01118                 while(!players.empty()) deletePlayer(players.begin());
01119 
01120                 Sound::shutdown();
01121                 EconData::getObj().shutdown();
01122                 BattleUnitData::getObj().shutdown();
01123                 HUD::shutdown();
01124         }
01125         //------------------------------------------------------------------------------------
01129         void overhead_update()
01130         {
01131                 if (currGameTick % 100 == 0) 
01132                 {
01133                         sys_console() << "currGameTick:" << currGameTick << endl;
01134                 }
01135 
01136                 
01137                 updateCredit();
01138 
01139                 // confirmQuit
01140                 if( input_isKeyPressed(KeyCodes::key_ESCAPE) ) showConfirmQuitMenu = !showConfirmQuitMenu;
01141                 if( showConfirmQuitMenu && input_isMouseLBClicked() )
01142                 {
01143                         Vec2D mousePos( input_getMouseX(), input_getMouseY() );
01144                         Box yes( 0.320f, 0.305f, 0.480f, 0.368f );
01145                         Box no ( 0.514f, 0.305f, 0.654f, 0.368f );
01146                         if( yes.isContain(mousePos) )  sys_terminate();
01147                         if( no .isContain(mousePos) )  showConfirmQuitMenu = false;
01148                 }
01149 
01150                 if (input_isKeyPressed(KeyCodes::key_P)) printAllMilitaryUnits();
01151                 if (input_isKeyPressed(KeyCodes::key_Q)) tutorial.stopTutorial();
01152                 if (input_isKeyPressed(KeyCodes::key_R))
01153                 {
01154                         sendMessageToPrintARandomNumberToTheConsole();
01155                 }
01156                 if (input_isKeyPressed(KeyCodes::key_RETURN) && chatBoxOn)
01157                 {
01158                         if (*chatBox.getString().begin() == '/')
01159                         {
01160                                 processCommand(chatBox.getString());
01161                         } else if( chatBox.getString().length() > 0 )
01162                         {
01163                                 stringstream sstr;
01164                                 sstr << COMMAND_TEXT_MESSAGE << " " << COMMIT_TIME << " " << currGameTick + NETWORK_GAME_TICK_LAG << " "
01165                                         << net_getPlayerName() << " says \"" << chatBox.getString() << "\"";
01166                                 net_send(sstr.str());
01167                         }
01168                         chatBox.clear();
01169                 }
01170                 receiveNetworkData();
01171                 static int waitingPrintout(0);
01172                 const int WAITING_MESSAGE_TRIGGER_POINT(30);
01173                 if (!hasNetworkDataForCurrentTickBeenReceived()) 
01174                 {
01175                         if (waitingPrintout++ == WAITING_MESSAGE_TRIGGER_POINT) 
01176                         {
01177                                 stringstream sstr;
01178                                 sstr << "Waiting for other player, current game time is " << currGameTick;
01179                                 GameState::messagesReceived().addMessage(sstr.str());
01180                         }
01181                         return;
01182                 } else if (waitingPrintout > WAITING_MESSAGE_TRIGGER_POINT)
01183                 {
01184                         GameState::messagesReceived().addMessage("Waiting complete, resuming game");
01185                 }
01186                 waitingPrintout = 0;
01187 
01188                 ++currGameTick;         
01189 
01190                 Overhead::tutorial.update();
01191                 tutorial.intro();
01192                 HUD::update();
01193                 processNetworkData();
01194                 processInput();
01195                 doAI();
01196                 doTutorial();
01197                 updateUnits();
01198                 updateCities();
01199                 updateBattleEntries();
01200                 updatePlayers();
01201                 doCollisionDetection();
01202                 if (!chatBoxOn && GameState::activeBattle() != 0 && input_isKeyPressed(KeyCodes::key_SPACE))
01203                 {
01204                         for(vector<BattleEntry*>::reverse_iterator iter = battles.rbegin(); iter != battles.rend(); ++iter)
01205                         {
01206                                 if ((*iter)->isFoughtBy(GameState::consolePlayer()->color()))
01207                                 {
01208                                         GameState::setActiveBattle(*battles.rbegin());
01209                                         GameState::messagesReceived().addMessage("Just changed to newest battle");
01210                                         break;
01211                                 }
01212                         }
01213                 }
01214                 if (chatBoxOn && !input_isKeyPressed(KeyCodes::key_LCONTROL) && !input_isKeyPressed(KeyCodes::key_RCONTROL))
01215                 {
01216                         chatBox.input();
01217                 }
01218                 if (input_isKeyPressed(KeyCodes::key_RETURN)) chatBoxOn = !chatBoxOn;
01219                 if (currGameTick % Globals::NETWORK_SYNC_RATE == 0)
01220                 {
01221                         stringstream sstr;
01222                         sstr << COMMAND_SYNC << " " << COMMIT_TIME << " " << currGameTick + NETWORK_GAME_TICK_LAG;
01223                         net_send(sstr.str());
01224                 }
01225                 const int OUT_OF_SYNC_INTERNAL_CHECK_FREQ(60 * 30);
01226                 if (currGameTick % OUT_OF_SYNC_INTERNAL_CHECK_FREQ == 0 && net_amIServer())
01227                 {
01228                         askForRandomNumbers();
01229                 }
01230                 const int PRINT_OUT_OF_SYNC_DEBUG_INFO_INTERNAL_CHECK(60 * 300);
01231                 if (currGameTick % PRINT_OUT_OF_SYNC_DEBUG_INFO_INTERNAL_CHECK == 0 && net_amIServer())
01232                 {
01233                         sendMessageToPrintARandomNumberToTheConsole();
01234                         printAllMilitaryUnits();
01235                 }
01236                 if (currGameTick % MESSAGE_DISPLAY_LENGTH == 0)
01237                 {
01238                         doVictoryTest();
01239                 }
01240                 // transition effect
01241                 if( GameState::activeBattle()!=prevBattle )
01242                 {
01243                         if( transitionTimeRemaining==-1 )               // start transition
01244                         {
01245                                 transitionTimeRemaining = TRANSITION_TIME;
01246                         }
01247                         else if( transitionTimeRemaining==0 )   // finish transition
01248                         {
01249                                 transitionTimeRemaining = -1;
01250                                 prevBattle = GameState::activeBattle();
01251                         }
01252                         else
01253                         {
01254                                 transitionTimeRemaining--;
01255                         }
01256                 }
01257 
01258                 // move overhead camera target to active battle
01259                 if( GameState::activeBattle() )
01260                 {
01261                         Vec3D newTarget( GameState::activeBattle()->getBattleLocation().x,
01262                                 GameState::activeBattle()->getBattleLocation().y,
01263                                 0.0f );
01264                         GameState::camTarget() = GameState::camTarget()*0.9f + newTarget*0.1f;
01265                 }
01266 
01267                 // calc how much reinforcement is available
01268                 for( int i=0; i<UnitTypes::COUNT; i++ )  GameState::availableRFM()[i] = 0;
01269                 if( GameState::activeBattle() )
01270                 {
01271                         Vec2D battlePos = GameState::activeBattle()->getBattleLocation();
01272                         for( UnitIter iter(GameState::units().begin()); iter!=GameState::units().end(); iter++ )
01273                                 if( (*iter)->color()==GameState::consolePlayer()->color() )
01274                                 {
01275                                         Vec2D unitPos( (*iter)->position().x, (*iter)->position().y );
01276                                         if( math_dist2D(battlePos,unitPos) <= 100.0f )
01277                                                 GameState::availableRFM()[ (*iter)->unitType() ]++;
01278                                 }
01279                 }
01280                 static bool maxMoneyMessage = false;
01281                 if (!maxMoneyMessage && (currGameTick % 200))
01282                 {
01283                         if (GameState::consolePlayer()->bank().balance() == MAX_MONEY)
01284                         {
01285                                 maxMoneyMessage = true;
01286                                 GameState::messagesReceived().addMessage("$10,000 max money limit reached");
01287                         }
01288                 }
01289         }
01290         //------------------------------------------------------------------------------------
01292         void overheadRender()
01293         {
01294                 for(DrawableIter iter = drawableObjects.begin(); iter != drawableObjects.end(); ++iter) (*iter)->draw();
01295                 for(vector<MilitaryUnit*>::iterator iter = selectedUnits.begin(); iter != selectedUnits.end(); ++iter)
01296                 {
01297                         (*iter)->drawBox();
01298                 }
01299                 if (selectedCity) selectedCity->drawSelectBox();
01300 
01301                 terrain_render( artWork->worldMap, artWork->terrainTexLow, artWork->terrainTexHigh, artWork->terrainTexNormal );
01302 
01303                 bool found = false;
01304                 Vec2D foundMiddle;
01305                 FLOAT foundDist;
01306                 Vec2D foundFrom;
01307                 Vec2D foundTo;
01308                 for(UnitIter iter(units.begin()); iter != units.end(); ++iter) 
01309                 {
01310                         for(UnitIter secondIter(iter+1); secondIter < units.end(); ++secondIter) 
01311                         {
01312                                 assert(iter != secondIter && "Programming Error");
01313                                 if ((*iter)->nearEachOther(*secondIter) && (*iter)->color() != (*secondIter)->color()) 
01314                                 {
01315                                         Vec2D from(math_translateWorldToScreen((*iter)->position()));
01316                                         Vec2D to(math_translateWorldToScreen((*secondIter)->position()));
01317                                         Vec2D middle((from.x + to.x) / 2, (from.y + to.y) / 2);
01318                                         FLOAT dist(math_dist3D((*iter)->position(),(*secondIter)->position()));
01319                                         if (!found || dist < foundDist)
01320                                         {
01321                                                 found = true;
01322                                                 foundDist = dist;
01323                                                 foundMiddle = middle;
01324                                                 foundFrom = from;
01325                                                 foundTo = to;
01326                                         }
01327                                 }
01328                         }
01329                 }
01330                 if (found)
01331                 {
01332                         mesh_render(Globals::artWork->thinCircle, math_translateScreenToWorldPlane(foundMiddle, BATTLE_CIRCLE_HEIGHT), 
01333                                 Vec3D(BATTLE_RADIUS,BATTLE_RADIUS,1.0f), Vec3D(0,0,0), artWork->colorRed);
01334                         overlay_line(foundFrom, foundTo, Colors::red, BlendModes::NONE, 1.0f, 0, 1);
01335                         tutorial.battleCircle();
01336                 }
01337 
01338                 for(vector<BattleEntry*>::iterator iter(GameState::battles().begin()); iter != GameState::battles().end(); ++iter)
01339                 {
01340                         if ((*iter)->isFoughtBy(GameState::consolePlayer()->color()))
01341                         {
01342                                 mesh_render(Globals::artWork->thinCircle, Vec3D((*iter)->getBattleLocation().x, (*iter)->getBattleLocation().y,
01343                                         BATTLE_CIRCLE_HEIGHT), Vec3D(BATTLE_RADIUS,BATTLE_RADIUS,1.0f), Vec3D(0,0,0), artWork->colorRed);
01344                         } else 
01345                         {
01346                                 mesh_render(Globals::artWork->thinCircle, Vec3D((*iter)->getBattleLocation().x, (*iter)->getBattleLocation().y, 
01347                                         BATTLE_CIRCLE_HEIGHT), Vec3D(BATTLE_RADIUS,BATTLE_RADIUS,1.0f), Vec3D(0,0,0), artWork->colorBlue);
01348                         }
01349                         if (sys_localRandInt() % 5 == 0)
01350                         {
01351                                 FLOAT dist(sys_localRandFloat() * BATTLE_RADIUS / 2.5f);
01352                                 FLOAT angle(sys_localRandFloat() * 2.0f * 3.1415f);
01353                                 FLOAT height((sys_localRandFloat() * 0.5f + 0.5f) * BATTLE_CIRCLE_HEIGHT);
01354                                 FLOAT x((*iter)->getBattleLocation().x + dist * cosf(angle));
01355                                 FLOAT y((*iter)->getBattleLocation().y + dist * sinf(angle));
01356                                 Vec3D location(Vec3D(x, y, height));
01357                                 int type(sys_localRandInt() % 3);
01358                                 int MAX_LENGTH(50);
01359                                 battleCircleAnimation.push_back( BattleSprite(location , MAX_LENGTH, type));
01360                         }
01361                         Vec2D location(math_translateWorldToScreen(Vec3D((*iter)->getBattleLocation().x - BATTLE_RADIUS / 3.0f, 
01362                                 (*iter)->getBattleLocation().y - BATTLE_RADIUS / 4.0f, BATTLE_CIRCLE_HEIGHT)));
01363                         FLOAT scale(0.8f);
01364                         Helper::printPlayerNameToScreen((*iter)->getTeamAColor(), location, scale);
01365                         overlay_text() << "   vs." << endl;
01366                         overlay_textOut(location + Vec2D(0, 0.015f), scale , Colors::yellow);
01367                         Helper::printPlayerNameToScreen((*iter)->getTeamBColor(), location + Vec2D(0, 0.03f), scale);
01368                 }
01369                 updateParticleList(battleCircleAnimation);
01370                 renderParticleList(battleCircleAnimation);
01371 
01372                 for(vector<MilitaryUnit*>::iterator iter(selectedUnits.begin()); iter != selectedUnits.end(); ++iter)
01373                 {
01374                         if ((*iter)->isMoving())
01375                         {
01376                                 Vec2D goal(math_translateWorldToScreen((*iter)->goalPosition()));
01377                                 overlay_line(math_translateWorldToScreen((*iter)->position()), goal,
01378                                         Colors::green);
01379                                 overlay_point(goal, 1.0f, Colors::red);
01380                         }
01381                 }
01382 
01383                 int totalUnits(Helper::totalUnitsForPlayer(GameState::consolePlayer()->color()));
01384                 Vec3D unitTextColor;
01385                 if (totalUnits < 15) unitTextColor = Colors::green;
01386                 else if (totalUnits < 25) unitTextColor = Colors::yellow;
01387                 else unitTextColor = Colors::red;
01388                 overlay_text() << "Units: " << totalUnits;
01389                 overlay_textOut(Vec2D(0.65f,0.81f), 1.0f, unitTextColor);
01390                 unitMaintenance.drawHelpString();
01391 
01392                 // Players & Battle List
01393                 overlay_image( artWork->playersNBattlesListTex, Vec2D(0.1f,0.02f), Vec2D(0.2f,0.04f),           // header menu
01394                         BlendModes::NONE, 1.0f, 6 );
01395                 if( playersNBattleListMode==MODE_PLAYERS_LIST )                 printPlayerList();
01396 
01397                 Icon list1( Vec2D(0,0),          Vec2D(0.07f,0.04f), NULL );
01398                 //Icon list2( Vec2D(0.077f,0), Vec2D(0.16f,0.04f), NULL ); 
01399                 Icon list3( Vec2D(0.161f,0), Vec2D(0.20f,0.04f), NULL );
01400                 list1.setHelpString( "List all players (Colored)\nand their total strength\nHot Key[F1]" );
01401                 //list2.setHelpString( "List all active battles\nand the relative strength of each side\nHot Key[F2]" );
01402                 list3.setHelpString( "Closes this Window\nHot Key[F2]" );
01403                 Vec2D mousePos( input_getMouseX(), input_getMouseY() );
01404                 if( list1.contains(mousePos) ) list1.drawOutline( Colors::yellow );
01405                 //if( list2.contains(mousePos) ) list2.drawOutline( Colors::yellow );
01406                 if( list3.contains(mousePos) ) list3.drawOutline( Colors::yellow );
01407                 list1.drawHelpString();
01408                 //list2.drawHelpString();
01409                 list3.drawHelpString();
01410 
01411 
01412                 // mouse cursor
01413                 FLOAT x = input_getMouseX(), y = input_getMouseY();
01414                 overlay_image( Globals::artWork->mouse, Vec2D(x+0.025f,y+0.025f), Vec2D(0.05f,0.05f), BlendModes::KEY, 1.0f, MOUSE_RENDER_PRIORITY );
01415 
01416                 // drag-select box
01417                 if( dragging )  overlay_rect( dragCorner, Vec2D(x,y), false, Colors::green );
01418         }
01419         //------------------------------------------------------------------------------------
01421         void renderThreatMap()
01422         {
01423 
01424                 // TS: draw on overhead map
01425                 //overlay_rect(Vec2D(0.0f, 0.0f), Vec2D(1.0f*AI::threatMapScale, 1.0f*AI::threatMapScale), true, Colors::red, 
01426                 //      BlendModes::MIX, 0.6f);
01428                 //for(float x=0.0f; x < /*Globals::mapWidth*/ worldMap.width ; x += worldMap.width/worldMap.gridWidth)
01429                 //{
01430                 //      overlay_line(Vec2D(x/worldMap.width*AI::threatMapScale,0.0f), Vec2D(x/worldMap.width*AI::threatMapScale, 
01431                 //              1.0f*AI::threatMapScale));
01432                 //}
01433                 //for(float i = 0.0f; i < worldMap.height; i += worldMap.height/worldMap.gridHeight)
01434                 //{
01435                 //      overlay_line(Vec2D(0.0f, i/worldMap.height*AI::threatMapScale), Vec2D(1.0f*AI::threatMapScale, 
01436                 //              i/worldMap.height*AI::threatMapScale));
01437                 //}
01438                 //for(UnitIter iter = units.begin(); iter != units.end(); ++iter)
01439                 //{
01440                 //      Vec2D unitpoint(((*iter)->position().x - worldMap.bounds.bounds()[0].x)/worldMap.height*AI::threatMapScale, 
01441                 //              ((*iter)->position().y - worldMap.bounds.bounds()[0].y)/worldMap.width*AI::threatMapScale);
01442                 //      overlay_point(unitpoint, 1.0f, (*iter)->color(), 
01443                 //              BlendModes::MIX, 0.75f);
01444 
01445                 //}
01446                 // draw the threatened areas
01447                 //AI::ThreatMap tm = pAiPlayer->threatMap();
01448 
01449                 //sys_console() << "-------- Threat Map ----------" << endl;
01450                 //for(int row=0; row < worldMap.gridHeight; ++row) 
01451                 //{
01452                 //      for(int col=0; col < worldMap.gridWidth; ++col) 
01453                 //      {
01454                 //              FLOAT startCol = (static_cast<FLOAT>(col)/worldMap.gridWidth)*AI::threatMapScale;
01455                 //              FLOAT startRow = (static_cast<FLOAT>(row)/worldMap.gridHeight)*AI::threatMapScale;
01456                 //              FLOAT endCol = (static_cast<FLOAT>(col+1)/worldMap.gridWidth)*AI::threatMapScale;
01457                 //              FLOAT endRow = (static_cast<FLOAT>(row+1)/worldMap.gridHeight)*AI::threatMapScale;
01458 
01459                 //              // 
01460                 //              FLOAT alpha = tm[row][col];
01461                 //              // values > 1.0f cause the alpha to 'roll over' the cell becomes transparent again
01462                 //              if(alpha > 1.0f) alpha = 1.0f;
01463                 //              overlay_rect(Vec2D(startCol, startRow), Vec2D(endCol, endRow), true, Colors::yellow, BlendModes::MIX, alpha);
01464                 //      }
01465                 //}
01466 
01467         }
01468         //------------------------------------------------------------------------------------
01473         void overhead_render()
01474         {
01475 #if 0 /*Turn on if you want to fast forward the game*/
01476                 if (currGameTick > 1 && currGameTick <= 8800) sys_fastForwardUpdate(120);
01477 #endif
01478 
01479                 if( creditTimer>0 ) renderCredit();
01480 
01481                 // confirm quit menu
01482                 if( showConfirmQuitMenu )
01483                 {
01484                         overlay_image( artWork->confirmQuit, Vec2D(0.5f,0.3f), Vec2D(0.5f,0.2f), BlendModes::NONE, 1.0f, 8 );
01485                         Vec2D mousePos( input_getMouseX(), input_getMouseY() );
01486                         Box yes( 0.320f, 0.305f, 0.480f, 0.368f );
01487                         Box no ( 0.514f, 0.305f, 0.654f, 0.368f );
01488                         if( yes.isContain(mousePos) )  overlay_rect( Vec2D(yes.left,yes.top), Vec2D(yes.right,yes.bottom), false, Colors::yellow, BlendModes::NONE, 1.0f, 8 );
01489                         if( no .isContain(mousePos) )  overlay_rect( Vec2D(no .left,no .top), Vec2D(no .right,no .bottom), false, Colors::yellow, BlendModes::NONE, 1.0f, 8 );
01490                 }
01491 
01492                 // win/lose condition msg
01493                 if( youWin  && creditTimer < 300 )
01494                         overlay_image( artWork->youWinTex,  Vec2D(0.5f,0.5f), Vec2D(0.9f,0.25f), BlendModes::KEY, 1.0f, 7 );
01495                 if( youLose && creditTimer < 300 )
01496                         overlay_image( artWork->youLoseTex, Vec2D(0.5f,0.5f), Vec2D(0.7f,0.25f), BlendModes::KEY, 1.0f, 7 );
01497 
01498                 if( transitionTimeRemaining!=-1 )   // transition effect
01499                 {
01500                         float trans = transitionTimeRemaining*1.0f/TRANSITION_TIME;             // 1=just start, 0=about done
01501 
01502                         if( prevBattle==NULL )                                                  // from overhead to battle
01503                         {
01504                                 overheadRender();
01505                                 Vec3D camTarget( GameState::camTarget() );
01506                                 Vec3D camPos( camTarget+Vec3D(0.0f,60.0f+camHeight*0.4f,20.0f+camHeight) );                             
01507                                 camera_set( camTarget+(camPos-camTarget)*(trans*0.9f+0.1f), camTarget, 0 );
01508                         }
01509                         else if( GameState::activeBattle()==NULL )              // from battle to overhead
01510                         {
01511                                 overheadRender();
01512                                 Vec3D camTarget( GameState::camTarget() );
01513                                 Vec3D camPos( camTarget+Vec3D(0.0f,60.0f+camHeight*0.4f,20.0f+camHeight) );                             
01514                                 camera_set( camTarget+(camPos-camTarget)*((1.0f-trans)*0.9f+0.1f), camTarget, 0 );
01515                         }
01516                         else                                                                                    // from battle to another battle
01517                         {
01518                         }
01519                 }                       
01520                 else                                                            // transition already done.  render directly
01521                 {
01522                         if(GameState::activeBattle()) GameState::activeBattle()->render();
01523                         else overheadRender();
01524                 }
01525 
01526                 if( showThreatMap ) renderThreatMap();
01527                 GameState::messagesReceived().print();
01528                 if (chatBoxOn)
01529                 {
01530                         overlay_text() << chatBox.getString();
01531                         const Vec2D TEXT_BOX_LOCATION(0.205f,0.77f);
01532                         const float TEXT_BOX_TEXT_SIZE(1.0f);
01533                         const Vec3D TEXT_BOX_COLOR(Colors::green);
01534                         const int TEXT_BOX_CURSOR_SPEED(30);
01535                         if ((currGameTick / TEXT_BOX_CURSOR_SPEED) % 2 == 0) overlay_text() << '_';
01536                         overlay_textOut(TEXT_BOX_LOCATION, TEXT_BOX_TEXT_SIZE, TEXT_BOX_COLOR);
01537                 }
01538                 HUD::render();
01539         }
01540         //------------------------------------------------------------------------------------
01541 }

Generated on Wed Apr 23 05:50:16 2003 for Modern Warfare by doxygen1.3-rc2