00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00023 #include "City.h"
00024 #include "BattleUnitStat.h"
00025 #include "EconData.h"
00026 #include "Overhead.h"
00027 #include "GameState.h"
00028 #include "Sound.h"
00029
00030 namespace Overhead {
00032 void deleteMilitaryUnit(MilitaryUnit* unit);
00033 extern list<BattleSprite> battleCircleAnimation;
00034 }
00035
00036 namespace {
00037 Vec3D citySize(8.0f, 8.0f, 8.0f);
00038 uint pointsNeededForaNewUnit(62*10);
00039 }
00040
00041 City::City(const Vec3D & location, Player* theOwner ) :
00042 m_size(Vec3D(15.0f, 15.0f, 15.0)),
00043 m_position(location),
00044 m_color( (theOwner ? theOwner->color() : Globals::NO_OWNER) ),
00045 m_rallyPoint(location),
00046 m_trainees(),
00047 m_timer(-1),
00048 m_currUnitType(-1),
00049 m_pOwner(theOwner),
00050 m_timeOfLastDeposit(-5000),
00051
00052 m_econLevel(1),
00053 m_econRemainingTime(-1),
00054 m_jetGaurdSize(0)
00055 {
00056 }
00057
00058 City::~City(void)
00059 {
00060 }
00061
00062 void City::draw(void) const
00063 {
00064 using namespace Globals;
00065 mesh_render( artWork->city_mesh, this->m_position, citySize, Vec3D(0.0f,90.0f,0.0f), artWork->city_texture, 0, this->color() );
00066 }
00067
00068 void City::drawSelectBox(void) const
00069 {
00070 Vec3D pos = m_position;
00071 pos.z += 1.2f;
00072 FLOAT angle = (FLOAT)( (Globals::currGameTick*5) % 360 );
00073 mesh_render( artWork->circle, pos, Vec3D(13.0f,13.0f,0.001f), Vec3D(angle,0,0), artWork->colorGreen );
00074
00075
00076 Vec2D screenPoint = math_translateWorldToScreen(this->m_position + Vec3D(0.0f,0.0f,0.0f));
00077 Vec2D rp = math_translateWorldToScreen(m_rallyPoint);
00078 overlay_line(screenPoint, rp, Colors::red);
00080 overlay_text() << "Rally Point";
00081 overlay_textOut(rp, 1.0f, Colors::red);
00082 }
00083
00084
00085 void City::startEconUpgrade( int secToComplete )
00086 {
00087 m_econRemainingTime = 62*secToComplete;
00088 }
00089
00090 int City::timeUntilFinishEconUpgrade()
00091 {
00092 if( m_econRemainingTime==-1 ) return -1;
00093 return m_econRemainingTime / 62;
00094 }
00095
00096 int City::econLevel()
00097 {
00098 return m_econLevel;
00099 }
00100
00101 void City::upgradeEcon()
00102 {
00103 if( !m_pOwner ) return;
00104 if( m_econRemainingTime!=-1 ) return;
00105 if( m_pOwner->bank().withdraw(EconData::getObj().econUpgradeCost(m_econLevel)) )
00106 {
00107 startEconUpgrade( EconData::getObj().econUpgradeTime(m_econLevel) );
00108 }
00109 }
00110
00111 void City::update(void)
00112 {
00113 m_position.z = terrain_getHeight( artWork->worldMap, m_position.x, m_position.y );
00114
00115 DWORD currTime = Globals::currGameTick;
00116 if( m_pOwner && (currTime - m_timeOfLastDeposit >= EconData::getObj().depositInterval()) )
00117 {
00118 m_pOwner->bank().deposit(Helper::maintenanceMultiplier(this->color(), EconData::getObj().depositPerCity(m_econLevel)));
00119 m_timeOfLastDeposit = currTime;
00120 }
00121
00122
00123 if(m_econRemainingTime>-1) m_econRemainingTime--;
00124 if( m_econRemainingTime==0 )
00125 {
00126 m_econRemainingTime = -1;
00127 if( m_econLevel<5 ) m_econLevel++;
00128 }
00129
00130
00131 if(m_timer > 0) --m_timer;
00132 else if (m_timer == 0)
00133 {
00134
00135 switch(m_currUnitType)
00136 {
00137 case UnitTypes::LIGHT_TANK:
00138 {
00139 MilitaryUnit* mu = new LightTank(m_position, m_pOwner, DEFAULT_LIGHT_TANK_SIZE);
00140 mu->goal(m_rallyPoint);
00141 GameState::addMilitaryUnit(mu);
00142 if(m_color == GameState::consolePlayer()->color())
00143 Sound::playRandomSound(Sound::CLASS_CREATE_LT);
00144 break;
00145 }
00146 case UnitTypes::HEAVY_TANK:
00147 {
00148 MilitaryUnit* mu = new HeavyTank(m_position, m_pOwner, DEFAULT_HEAVY_TANK_SIZE);
00149 mu->goal(m_rallyPoint);
00150 GameState::addMilitaryUnit(mu);
00151 if(m_color == GameState::consolePlayer()->color())
00152 Sound::playRandomSound(Sound::CLASS_CREATE_HT);
00153 break;
00154 }
00155 case UnitTypes::LAUNCHER:
00156 {
00157 MilitaryUnit* mu = new RocketLauncher(m_position, m_pOwner, DEFAULT_ROCKET_LAUNCHER_SIZE);
00158 mu->goal(m_rallyPoint);
00159 GameState::addMilitaryUnit(mu);
00160 if(m_color == GameState::consolePlayer()->color())
00161 Sound::playRandomSound(Sound::CLASS_CREATE_RT);
00162 }
00163 break;
00164 case UnitTypes::ARTILLERY:
00165 {
00166 MilitaryUnit* mu = new Artillery(m_position, m_pOwner, DEFAULT_ARTILLERY_SIZE);
00167 mu->goal(m_rallyPoint);
00168 GameState::addMilitaryUnit(mu);
00169 if(m_color == GameState::consolePlayer()->color())
00170 Sound::playRandomSound(Sound::CLASS_CREATE_AR);
00171 break;
00172 }
00173 case UnitTypes::JET:
00174 {
00175 MilitaryUnit* mu = new Jet(m_position, m_pOwner, 12, (int)uniqueID() );
00176 GameState::addMilitaryUnit(mu);
00177 if(m_color == GameState::consolePlayer()->color())
00178 Sound::playRandomSound(Sound::CLASS_CREATE_JT);
00179 break;
00180 }
00181 default:
00182 sys_console() << "Warning! Invalid unit given as UnitType when trying to have a city build a new unit. Type:"
00183 << m_currUnitType << endl;
00184 }
00185
00186 m_trainees.pop_front();
00187 --m_timer;
00188 }
00189 else if( !m_trainees.empty() )
00190 {
00191 m_currUnitType = m_trainees.front();
00192 m_timer = EconData::getObj().unitTrainingTime(m_currUnitType);
00193 }
00194
00195 }
00196
00197 bool City::contains(Vec2D that) const
00198 {
00199 Vec2D city2Dpos( math_translateWorldToScreen(m_position) );
00200 return math_dist2D( city2Dpos,that ) < 0.07f;
00201 }
00202
00203 Vec3D City::position(void) const
00204 {
00205 return m_position;
00206 }
00207
00208 Player* City::owner(void) const
00209 {
00210 return this->m_pOwner;
00211 }
00212
00213 Vec3D City::color(void) const
00214 {
00215 return m_color;
00216 }
00217
00218 void City::changeOwner(Player* newOwner, bool taunting)
00219 {
00220 Player* preOwner = m_pOwner;
00221 m_pOwner = newOwner;
00222 m_color = m_pOwner->color();
00223
00224 vector<MilitaryUnit*> toDelete;
00225 for(UnitIter unitIter(GameState::units().begin()); unitIter != GameState::units().end(); ++unitIter)
00226 {
00227 if ((*unitIter)->unitType() == UnitTypes::JET)
00228 {
00229 if ((*unitIter)->color() != this->color() && dynamic_cast<Jet*>((*unitIter))->getCityID() == this->uniqueID())
00230 {
00231 toDelete.push_back(*unitIter);
00232 }
00233 }
00234 }
00235 for(UnitIter unitIter(toDelete.begin()); unitIter != toDelete.end(); ++unitIter)
00236 {
00237 Overhead::deleteMilitaryUnit(*unitIter);
00238 }
00239 if (taunting && preOwner)
00240 {
00241 Overhead::battleCircleAnimation.push_back( BattleSprite(this->position(), 60, BattleSpriteTypes::EXPLO_LARGE));
00242 Overhead::battleCircleAnimation.push_back( BattleSprite(this->position(), 100, BattleSpriteTypes::SMOKE_LARGE));
00243 stringstream sstr;
00244 if (preOwner->color() == Colors::white)
00245 {
00246 sstr << Helper::playerColorToPlayerName(newOwner->color()) << " took over a neutral city";
00247 } else
00248 {
00249 sstr << Helper::playerColorToPlayerName(newOwner->color()) << " says: ";
00250 switch (sys_randInt() % 4)
00251 {
00252 case 0:
00253 sstr << "I took over " << Helper::playerColorToPlayerName(preOwner->color()) << "'s city!";
00254 break;
00255 case 1:
00256 sstr << "Another city mine! " << Helper::playerColorToPlayerName(preOwner->color()) << " is taking a woopin";
00257 break;
00258 case 2:
00259 sstr << "Another city mine! " << Helper::playerColorToPlayerName(preOwner->color()) << " is getting a butt woopin";
00260 break;
00261 case 3:
00262 sstr << "Some people are destined to loose! City's mine";
00263 break;
00264 default:
00265 break;
00266 }
00267 }
00268 GameState::messagesReceived().addMessage(sstr.str());
00269 }
00270 }
00271
00272 bool City::collision(const MilitaryUnit* unit) const
00273 {
00274 return ((this->m_position.x + citySize.x > unit->position().x) &&
00275 (this->m_position.x - citySize.x < unit->position().x) &&
00276 (this->m_position.y + citySize.y > unit->position().y) &&
00277 (this->m_position.y - citySize.y < unit->position().y));
00278 }
00279
00280 void City::setRallyPoint(Vec3D rp) { m_rallyPoint = rp; }
00281
00282 Vec3D& City::rallyPoint() { return m_rallyPoint; }
00283
00284 void City::trainUnit(int type)
00285 {
00286 if( !m_pOwner ) return;
00287 if( m_pOwner->bank().withdraw(EconData::getObj().unitAmount(type)) )
00288 {
00289 if ((Helper::totalUnitsForPlayer(this->color()) + Helper::totalUnitsBeingBuiltForPlayer(this->color())) < MAX_UNITS_FOR_EACH_PLAYER)
00290 {
00291 m_trainees.push_back(type);
00292 } else
00293 {
00294 GameState::messagesReceived().addMessage("Cannot Build: Max unit limit reached");
00295 }
00296 } else if (this->color() == GameState::consolePlayer()->color())
00297 {
00298 GameState::messagesReceived().addMessage("Cannot Build: Not enough funds");
00299 }
00300
00301 }
00302
00303 const deque<int>& City::trainees() const { return m_trainees; }
00304
00305 int City::trainingTimeLeft() const { return m_timer; }
00306
00307 void City::addJetGaurd() { ++m_jetGaurdSize; }
00308
00309 void City::deleteJetGuard()
00310 {
00311 if (!(--m_jetGaurdSize >= 0))
00312 {
00313 sys_console() << WARNING << "!(--m_jetGaurdSize >= 0)" << endl;
00314 sys_flushConsole();
00315 }
00316 }
00317
00318 int City::jetGaurdSize() { return m_jetGaurdSize; }