OptionsTransient.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <common/OptionsTransient.h>
00022 #include <common/OptionsScorched.h>
00023 #include <common/Defines.h>
00024 #include <tank/TankContainer.h>
00025 #include <tank/TankState.h>
00026 #include <time.h>
00027 #include <math.h>
00028 
00029 OptionsTransient::OptionsTransient(OptionsScorched &optionsGame) :
00030         optionsGame_(optionsGame), newGame_(false),
00031         currentRoundNo_(options_, "CurrentRoundNo", 
00032                 "The current number of rounds played in this game", 0, 0),
00033         currentGameNo_(options_, "CurrentGameNo",
00034                 "The current game", 0, 0),
00035         windAngle_(options_, "WindAngle",
00036                 "The current wind angle (direction)", 0, 0),
00037         windStartAngle_(options_, "WindStartAngle",
00038                 "The angle (direction) the wind started the round on", 0, 0),
00039         windSpeed_(options_, "WindSpeed",
00040                 "The current speed of the wind", 0, 0), 
00041         windDirection_(options_, "WindDirection",
00042                 "The current wind direction vector", 0, FixedVector::getNullVector()),
00043         wallType_(options_, "WallType",
00044                 "The current wall type", 0, 0)
00045 {
00046         
00047 }
00048 
00049 OptionsTransient::~OptionsTransient()
00050 {
00051 }
00052 
00053 const char *OptionsTransient::getGameType()
00054 {
00055         const char *gameType = "Unknown";
00056         switch (optionsGame_.getTurnType())
00057         {
00058         case OptionsGame::TurnSequentialLooserFirst:
00059                 gameType = "Sequential (Loser)";
00060                 break;
00061         case OptionsGame::TurnSequentialRandom:
00062                 gameType = "Sequential (Random)";
00063                 break;
00064         case OptionsGame::TurnSimultaneous:
00065                 gameType = "Simultaneous";
00066                 break;
00067         }
00068         return gameType;
00069 }
00070 
00071 unsigned int OptionsTransient::getLeastUsedTeam(TankContainer &container)
00072 {
00073         // Reset all the counts
00074         std::map<unsigned int, unsigned int> counts;
00075         for (int i=1; i<=optionsGame_.getTeams(); i++)
00076         {
00077                 counts[i] = 0;
00078         }
00079 
00080         // Add all the tanks to the counts
00081         std::map<unsigned int, Tank *>::iterator itor;
00082         std::map<unsigned int, Tank *> &tanks = 
00083                 container.getPlayingTanks();
00084         for (itor = tanks.begin();
00085                 itor != tanks.end();
00086                 itor++)
00087         {
00088                 Tank *tank = (*itor).second;
00089                 if (!tank->getState().getSpectator())
00090                 {
00091                         if (tank->getTeam() > 0)
00092                         {
00093                                 counts[tank->getTeam()] ++;
00094                         }
00095                 }
00096         }
00097 
00098         // Find the least counted team
00099         unsigned int team = 1;
00100         unsigned int count = counts[1];
00101         for (int i=2; i<=optionsGame_.getTeams(); i++)
00102         {
00103                 if (counts[i] < count)
00104                 {
00105                         team = i;
00106                         count = counts[i];
00107                 }
00108         }
00109         return team;
00110 }
00111 
00112 bool OptionsTransient::writeToBuffer(NetBuffer &buffer)
00113 {
00114         if (!OptionEntryHelper::writeToBuffer(options_, buffer, false)) return false;
00115         return true;
00116 }
00117 
00118 bool OptionsTransient::readFromBuffer(NetBufferReader &reader)
00119 {
00120         if (!OptionEntryHelper::readFromBuffer(options_, reader, false)) return false;
00121         return true;
00122 }
00123 
00124 void OptionsTransient::reset()
00125 {
00126         currentGameNo_.setValue(0);
00127         currentRoundNo_.setValue(0);
00128 }
00129 
00130 void OptionsTransient::startNewGame()
00131 {
00132         currentRoundNo_.setValue(optionsGame_.getNoRounds()+1);
00133 }
00134 
00135 void OptionsTransient::startNewRound()
00136 {
00137         currentGameNo_.setValue(optionsGame_.getNoMaxRoundTurns() + 1);
00138 }
00139 
00140 void OptionsTransient::newGame()
00141 {
00142         newGame_ = true;
00143         currentRoundNo_.setValue(currentRoundNo_.getValue() + 1);
00144         if (currentRoundNo_.getValue() >= optionsGame_.getBuyOnRound() &&
00145                 !optionsGame_.getGiveAllWeapons())
00146         {
00147                 currentGameNo_.setValue(0);     
00148         }
00149         else
00150         {
00151                 currentGameNo_.setValue(1);
00152         }
00153         
00154         newGameWind();
00155         newGameWall();
00156 }
00157 
00158 void OptionsTransient::nextRound()
00159 {
00160         if (!newGame_)
00161         {
00162                 currentGameNo_.setValue(currentGameNo_.getValue() + 1);
00163         }
00164         newGame_ = false;
00165         nextRoundWind();
00166 }
00167 
00168 void OptionsTransient::newGameWind()
00169 {
00170         RandomGenerator random;
00171         random.seed(rand());
00172 
00173         switch(optionsGame_.getWindForce())
00174         {
00175                 case OptionsGame::WindRandom:
00176                         windSpeed_.setValue(
00177                                 (random.getRandFixed() * fixed(true, 59000)).asInt()); // ie range 0->5
00178                         break;
00179                 case OptionsGame::Wind1:
00180                 case OptionsGame::Wind2:
00181                 case OptionsGame::Wind3:
00182                 case OptionsGame::Wind4:
00183                 case OptionsGame::Wind5:
00184                         windSpeed_.setValue(
00185                                 fixed(int(optionsGame_.getWindForce()) - 1));
00186                         break;
00187                 case OptionsGame::WindBreezy:
00188                         windSpeed_.setValue(
00189                                 (random.getRandFixed() * fixed(true, 29000)).asInt());// ie range 0->2);
00190                         break;
00191                 case OptionsGame::WindGale:
00192                         windSpeed_.setValue(
00193                                 (random.getRandFixed() * fixed(true, 29000)).asInt() + 3); // ie range 3->5);
00194                         break;
00195                 case OptionsGame::WindNone:
00196                 default:
00197                         windSpeed_.setValue(0);
00198                         break;
00199         }
00200 
00201         if (windSpeed_.getValue() > 0)
00202         {
00203                 fixed winAngle = random.getRandFixed() * 360;
00204                 windStartAngle_.setValue(winAngle);
00205                 windAngle_.setValue(winAngle);
00206                 
00207                 fixed windDirX = (winAngle / fixed(180) * fixed::XPI).sin();
00208                 fixed windDirY = (winAngle / fixed(180) * fixed::XPI).cos();
00209                 FixedVector windDir(windDirX, windDirY, 0);
00210                 windDirection_.setValue(windDir);
00211         }
00212         else
00213         {
00214                 windStartAngle_.setValue(0);
00215                 windAngle_.setValue(0);
00216                 windDirection_.setValue(FixedVector::getNullVector());
00217         }
00218 }
00219 
00220 void OptionsTransient::nextRoundWind()
00221 {
00222         if (optionsGame_.getWindType() != OptionsGame::WindOnMove)
00223         {
00224                 return;
00225         }
00226 
00227         if (windSpeed_.getValue() > 0)
00228         {
00229                 RandomGenerator random;
00230                 random.seed(rand());
00231 
00232                 fixed winAngle = windStartAngle_.getValue() + ((random.getRandFixed() * 40) - 20);
00233                 windAngle_.setValue(winAngle);
00234                 
00235                 fixed windDirX = (winAngle / fixed(180) * fixed::XPI).sin();
00236                 fixed windDirY = (winAngle / fixed(180) * fixed::XPI).cos();
00237                 FixedVector windDir(windDirX, windDirY, 0);
00238                 windDirection_.setValue(windDir);
00239         }
00240 }
00241 
00242 Vector &OptionsTransient::getWallColor()
00243 {
00244         static Vector wallColor;
00245         switch (getWallType())
00246         {
00247         case wallWrapAround:
00248                 wallColor = Vector(0.5f, 0.5f, 0.0f);
00249                 break;
00250         case wallBouncy:
00251                 wallColor = Vector(0.0f, 0.0f, 0.5f);
00252                 break;
00253         case wallConcrete:
00254                 wallColor = Vector(0.5f, 0.5f, 0.5f);
00255                 break;
00256         default:
00257                 wallColor = Vector(0.0f, 0.0f, 0.0f);
00258                 break;
00259         }
00260 
00261         return wallColor;
00262 }
00263 
00264 void OptionsTransient::newGameWall()
00265 {
00266         switch (optionsGame_.getWallType())
00267         {
00268         case OptionsGame::WallConcrete:
00269                 wallType_.setValue((int) wallConcrete);
00270                 break;
00271         case OptionsGame::WallBouncy:
00272                 wallType_.setValue((int) wallBouncy);
00273                 break;
00274         case OptionsGame::WallWrapAround:
00275                 wallType_.setValue((int) wallWrapAround);
00276                 break;
00277         case OptionsGame::WallNone:
00278                 wallType_.setValue((int) wallNone);
00279                 break;
00280         float r;
00281         case OptionsGame::WallActive:   // Bouncy or Wrap
00282                 r = RAND * 2.0f + 1.0f;
00283                 wallType_.setValue((int) r);
00284                 break;
00285         case OptionsGame::WallInactive: // Concrete or None
00286                 if (RAND < 0.5f) wallType_.setValue((int) wallConcrete);
00287                 else wallType_.setValue((int) wallNone);
00288                 break;
00289         default:
00290                 r = RAND * 4.0f;
00291                 wallType_.setValue((int) r);
00292                 break;
00293         }
00294 }
00295 
00296 int OptionsTransient::getArmsLevel()
00297 {
00298         float start = (float) optionsGame_.getStartArmsLevel();
00299         float end = (float) optionsGame_.getEndArmsLevel();
00300 
00301         float roundsPlayed = float(getCurrentRoundNo());
00302         float totalRounds = float(optionsGame_.getNoRounds());
00303 
00304         float armsLevel = start + ((end - start) * (roundsPlayed / totalRounds));
00305         return (int) armsLevel;
00306 }

Generated on Mon Feb 16 15:14:49 2009 for Scorched3D by  doxygen 1.5.3