PlayShots.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 <engine/PlayShots.h>
00022 #include <engine/ScorchedContext.h>
00023 #include <engine/ActionController.h>
00024 #include <tank/TankScore.h>
00025 #include <tank/TankState.h>
00026 #include <tank/TankAccessories.h>
00027 #include <tank/TankPosition.h>
00028 #include <actions/TankFired.h>
00029 #include <actions/TankResign.h>
00030 #include <target/TargetLife.h>
00031 #include <common/OptionsScorched.h>
00032 #include <common/StatsLogger.h>
00033 #include <weapons/AccessoryStore.h>
00034 
00035 PlayShots::PlayShots()
00036 {
00037 }
00038 
00039 PlayShots::~PlayShots()
00040 {
00041 }
00042 
00043 void PlayShots::createMessage(ComsPlayMovesMessage &message)
00044 {
00045         std::map<unsigned int, ComsPlayedMoveMessage *>::iterator itor;
00046         for (itor = messages_.begin();
00047                 itor != messages_.end();
00048                 itor++)
00049         {
00050                 message.getMoves()[(*itor).first] = (*itor).second;
00051         }
00052 }
00053 
00054 void PlayShots::readMessage(ComsPlayMovesMessage &message)
00055 {
00056         clearShots();
00057         std::map<unsigned int, ComsPlayedMoveMessage *>::iterator itor;
00058         for (itor = message.getMoves().begin();
00059                 itor != message.getMoves().end();
00060                 itor++)
00061         {
00062                 messages_[(*itor).first] = (*itor).second;
00063         }
00064 }
00065 
00066 void PlayShots::clearShots()
00067 {
00068         std::map<unsigned int, ComsPlayedMoveMessage *>::iterator itor;
00069         for (itor = messages_.begin();
00070                 itor != messages_.end();
00071                 itor++)
00072         {
00073                 delete (*itor).second;
00074         }
00075         messages_.clear();
00076 }
00077 
00078 bool PlayShots::haveShot(unsigned int playerId)
00079 {
00080         std::map<unsigned int, ComsPlayedMoveMessage *>::iterator itor =
00081                 messages_.find(playerId);
00082         return (itor != messages_.end());
00083 }
00084 
00085 void PlayShots::playShots(ScorchedContext &context)
00086 {
00087         std::map<unsigned int, ComsPlayedMoveMessage *>::iterator itor;
00088         for (itor = messages_.begin();
00089                 itor != messages_.end();
00090                 itor++)
00091         {
00092                 unsigned int playerId = (*itor).first;
00093                 ComsPlayedMoveMessage *message = (*itor).second;
00094 
00095                 // Check the tank exists for this player
00096                 // It may not if the player has left the game after firing.
00097                 Tank *tank = context.getTankContainer().getTankById(playerId);
00098                 if (tank)
00099                 {
00100                         // This tank has now made a move, reset its missed move counter
00101                         tank->getScore().setMissedMoves(0);
00102 
00103                         // Actually play the move
00104                         processPlayedMoveMessage(context, *message, tank);
00105                 }
00106         }
00107 }
00108 
00109 void PlayShots::processPlayedMoveMessage(ScorchedContext &context, 
00110         ComsPlayedMoveMessage &message, Tank *tank)
00111 {
00112         // All actions that are done at the very START of a new round
00113         switch (message.getType())
00114         {
00115                 case ComsPlayedMoveMessage::eShot:
00116                         processFiredMessage(context, message, tank);
00117                         break;
00118                 case ComsPlayedMoveMessage::eSkip:
00119                         // Just do nothing as the player has requested
00120                         // That they skip their move
00121                         break;
00122                 case ComsPlayedMoveMessage::eFinishedBuy:
00123                         // Just used as a notification that the player
00124                         // has finished buying, do nothing
00125                         break;
00126                 case ComsPlayedMoveMessage::eResign:
00127                         processResignMessage(context, message, tank);
00128                         break;
00129                 default:
00130                         break;
00131         }
00132 }
00133 
00134 void PlayShots::processResignMessage(ScorchedContext &context, 
00135         ComsPlayedMoveMessage &message, Tank *tank)
00136 {
00137         TankResign *resign = new TankResign(tank->getPlayerId());
00138         if (context.getOptionsGame().getResignMode() == OptionsGame::ResignStart)
00139         {                                       
00140                 context.getActionController().addAction(resign);
00141         }
00142         else if (context.getOptionsGame().getResignMode() == OptionsGame::ResignDueToHealth)
00143         {
00144                 if (tank->getLife().getMaxLife() / 2 <= tank->getLife().getLife())
00145                 {
00146                         context.getActionController().addAction(resign);
00147                 }
00148                 else
00149                 {
00150                         context.getActionController().addLastAction(resign);
00151                 }
00152         }
00153         else 
00154         {
00155                 context.getActionController().addLastAction(resign);
00156         }
00157 }
00158 
00159 void PlayShots::processFiredMessage(ScorchedContext &context, 
00160         ComsPlayedMoveMessage &message, Tank *tank)
00161 {
00162         // Check the tank is alive
00163         if (tank->getState().getState() != TankState::sNormal)
00164         {
00165                 return;
00166         }
00167 
00168         // Check the weapon name exists and is a weapon
00169         Accessory *accessory = 
00170                 context.getAccessoryStore().findByAccessoryId(message.getWeaponId());
00171         if (!accessory) return;
00172 
00173         Weapon *weapon = (Weapon *) accessory->getAction();
00174         if (accessory->getUseNumber() > 0)
00175         {
00176                 // Actually use up one of the weapons
00177                 // Fuel, is used up differently at the rate of one weapon per movement square
00178                 // This is done sperately in the tank movement action
00179                 tank->getAccessories().rm(accessory, accessory->getUseNumber());
00180         }
00181 
00182         // shot fired action
00183         TankFired *fired = new TankFired(tank->getPlayerId(), 
00184                 weapon,
00185                 message.getRotationXY(), message.getRotationYZ());
00186         context.getActionController().addAction(fired);
00187 
00188         // Set the tank to have the correct rotation etc..
00189         tank->getPosition().rotateGunXY(
00190                 message.getRotationXY(), false);
00191         tank->getPosition().rotateGunYZ(
00192                 message.getRotationYZ(), false);
00193         tank->getPosition().changePower(
00194                 message.getPower(), false);
00195         tank->getPosition().setSelectPosition(
00196                 message.getSelectPositionX(), 
00197                 message.getSelectPositionY());
00198 
00199         // Create the action for the weapon and
00200         // add it to the action controller
00201         FixedVector velocity = tank->getPosition().getVelocityVector() *
00202                 (tank->getPosition().getPower() + 1);
00203         FixedVector position = tank->getPosition().getTankGunPosition();
00204 
00205         WeaponFireContext weaponContext(tank->getPlayerId(), 0);
00206         weapon->fireWeapon(context, weaponContext, position, velocity);
00207         StatsLogger::instance()->tankFired(tank, weapon);
00208         StatsLogger::instance()->weaponFired(weapon, false);
00209 }

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