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

City.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 "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),     // so that at the 1st game tick, everyone get exactly 1 deposit
00051 // regardless of how long the game has been spinning before host starts
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         // also draw the rally point
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;                                 // can't train unit from a neutral city
00104         if( m_econRemainingTime!=-1 ) return;   // already upgrading
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         // check econ upgrades
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         // check timers for unit building
00131         if(m_timer > 0) --m_timer;
00132         else if (m_timer == 0)
00133         {
00134                 // only play sounds if the unit being created is on the console players team
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                 // so that we train the next unit
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         //m_jetGaurdSize = 0;
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;         // can't train unit from a neutral city
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; }

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