00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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());
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());
00190 break;
00191 case OptionsGame::WindGale:
00192 windSpeed_.setValue(
00193 (random.getRandFixed() * fixed(true, 29000)).asInt() + 3);
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:
00282 r = RAND * 2.0f + 1.0f;
00283 wallType_.setValue((int) r);
00284 break;
00285 case OptionsGame::WallInactive:
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 }