ShotProjectile.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 <actions/ShotProjectile.h>
00022 #ifndef S3D_SERVER
00023         #include <sprites/MissileActionRenderer.h>
00024         #include <tankgraph/RenderTracer.h>
00025 #endif
00026 #include <landscapemap/LandscapeMaps.h>
00027 #include <landscapedef/LandscapeTex.h>
00028 #include <tank/TankContainer.h>
00029 #include <tank/TankState.h>
00030 #include <tankai/TankAI.h>
00031 #include <common/Defines.h>
00032 #include <engine/ScorchedContext.h>
00033 #include <engine/ViewPoints.h>
00034 #include <weapons/AccessoryStore.h>
00035 #include <math.h>
00036 
00037 ShotProjectile::ShotProjectile(FixedVector &startPosition, FixedVector &velocity,
00038                                                            WeaponProjectile *weapon, WeaponFireContext &weaponContext,
00039                                                            unsigned int flareType,
00040                                                            fixed spinSpeed ) :
00041         startPosition_(startPosition), velocity_(velocity), 
00042         weapon_(weapon), weaponContext_(weaponContext), 
00043         flareType_(flareType), vPoint_(0),
00044         snapTime_(fixed(true, 2000)), up_(false),
00045         totalTime_(0), spinSpeed_(spinSpeed)
00046 {
00047 
00048 }
00049 
00050 void ShotProjectile::init()
00051 {
00052 #ifndef S3D_SERVER
00053         if (!context_->getServerMode()) 
00054         {
00055                 setActionRender(new MissileActionRenderer(flareType_, 
00056                                 weapon_->getScale(*context_).asFloat(),
00057                                 spinSpeed_.asFloat()));
00058         }
00059 #endif // #ifndef S3D_SERVER
00060 
00061         vPoint_ = context_->getViewPoints().getNewViewPoint(weaponContext_.getPlayerId());
00062         PhysicsParticleInfo info(ParticleTypeShot, weaponContext_.getPlayerId(), this);
00063         setPhysics(info, startPosition_, velocity_, 
00064                 0, 0, weapon_->getWindFactor(*context_), getWeapon()->getUnder(), 
00065                 false, getWeapon()->getWallCollision());
00066         thrustTime_ = getWeapon()->getThrustTime(*context_);
00067         thrustAmount_ = getWeapon()->getThrustAmount(*context_);
00068         timedCollision_ = getWeapon()->getTimedCollision(*context_);
00069         drag_ = getWeapon()->getDrag(*context_);
00070 }
00071 
00072 std::string ShotProjectile::getActionDetails()
00073 {
00074         return S3D::formatStringBuffer("%i,%i,%i %i,%i,%i %s",
00075                 startPosition_[0].getInternal(), startPosition_[1].getInternal(), startPosition_[2].getInternal(),
00076                 velocity_[0].getInternal(), velocity_[1].getInternal(), velocity_[2].getInternal(),
00077                 weapon_->getParent()->getName());
00078 }
00079 
00080 ShotProjectile::~ShotProjectile()
00081 {
00082         if (vPoint_) context_->getViewPoints().releaseViewPoint(vPoint_);
00083 }
00084 
00085 void ShotProjectile::collision(PhysicsParticleObject &position, 
00086         ScorchedCollisionId collisionId)
00087 {
00088         if (!collision_)
00089         {
00090                 // Tell all AIs about this collision
00091                 std::map<unsigned int, Tank *> tanks = 
00092                         context_->getTankContainer().getAllTanks();
00093                 std::map<unsigned int, Tank *>::iterator itor;
00094                 for (itor = tanks.begin();
00095                         itor != tanks.end();
00096                         itor++)
00097                 {
00098                         Tank *tank = (*itor).second;
00099                         TankAI *ai = tank->getTankAI();
00100                         if (ai)
00101                         {               
00102                                 if (tank->getState().getState() == TankState::sNormal &&
00103                                         !tank->getState().getSpectator())
00104                                 {
00105                                         ai->shotLanded(collisionId, 
00106                                                 getWeapon(), getPlayerId(), 
00107                                                 getCurrentPosition().asVector());
00108                                 }
00109                         }
00110                 }
00111 
00112                 bool doColl = true;
00113 
00114                 // Apex collisions dud if they collide with the ground
00115                 // unless no dud is set
00116                 if (getWeapon()->getApexCollision() && !getWeapon()->getApexNoDud())
00117                 {
00118                         doColl = false;
00119                 }
00120                 if ((getWeapon()->getTimedCollision(*context_) > 0) && getWeapon()->getTimedDud())
00121                 {
00122                         doColl = false;
00123                 }
00124 
00125                 if (doColl) doCollision(position.getPosition());
00126         }
00127         PhysicsParticleReferenced::collision(position, collisionId);
00128 }
00129 
00130 void ShotProjectile::simulate(fixed frameTime, bool &remove)
00131 {
00132         totalTime_ += frameTime;
00133         if (vPoint_)
00134         {
00135                 vPoint_->setPosition(getCurrentPosition());
00136 
00137                 FixedVector velocity = -getCurrentVelocity();
00138                 velocity[2] = 10;
00139                 vPoint_->setLookFrom(velocity);
00140         }
00141 
00142         // Water collision
00143         if (!remove &&
00144                 getWeapon()->getWaterCollision())
00145         {
00146                 fixed waterHeight = -10;
00147                 LandscapeTex &tex = *context_->getLandscapeMaps().getDefinitions().getTex();
00148                 if (tex.border->getType() == LandscapeTexType::eWater)
00149                 {
00150                         LandscapeTexBorderWater *water = 
00151                                 (LandscapeTexBorderWater *) tex.border;
00152 
00153                         waterHeight = water->height;
00154                 }
00155 
00156                 if (getCurrentPosition()[2] < waterHeight)
00157                 {
00158                         doCollision(getCurrentPosition());
00159                         remove = true;
00160                 }
00161         }
00162 
00163         // Apex collision
00164         if (!remove &&
00165                 getWeapon()->getApexCollision())
00166         {
00167                 if (getCurrentVelocity()[2] > 0) up_ = true;
00168                 else if (up_)
00169                 {
00170                         doCollision(getCurrentPosition());
00171                         remove = true;
00172                 }
00173         }
00174 
00175         // Thrust
00176         if (thrustAmount_ > 0)
00177         {
00178                 if (totalTime_ < thrustTime_ ||
00179                         thrustTime_ == 0)
00180                 {
00181                         FixedVector direction = getCurrentVelocity();
00182                         direction.StoreNormalize();
00183                         direction *= thrustAmount_;
00184                         applyForce(direction);
00185                 }
00186         }
00187 
00188         // Drag
00189         if (drag_ > 0)
00190         {
00191                 FixedVector direction = getCurrentVelocity();
00192                 direction *= -drag_;
00193                 applyForce(direction);
00194         }
00195 
00196         // Timed collision
00197         if (!remove &&
00198                 timedCollision_ > 0)
00199         {
00200                 if (totalTime_ > timedCollision_)
00201                 {
00202                         doCollision(getCurrentPosition());
00203                         remove = true;
00204                 }
00205         }
00206 
00207         // Shot path
00208 #ifndef S3D_SERVER
00209         if (!context_->getServerMode())
00210         {
00211                 if (getWeapon()->getShowShotPath())
00212                 {
00213                         snapTime_ += frameTime;
00214                         if (snapTime_.asFloat() > 0.1f || remove)
00215                         {
00216                                 Vector up (0.0f, 0.0f, 1.0f);
00217                                 RenderTracer::TracerLinePoint point;
00218                                 point.position = getCurrentPosition().asVector();
00219                                 point.cross = (getCurrentVelocity().asVector() * up).Normalize();
00220                                 positions_.push_back(point);
00221                                 snapTime_ = 0;
00222                         }
00223                 }
00224         }
00225 #endif  // #ifndef S3D_SERVER
00226 
00227         PhysicsParticleReferenced::simulate(frameTime, remove);
00228 }
00229 
00230 void ShotProjectile::doCollision(FixedVector &position)
00231 {       
00232 #ifndef S3D_SERVER
00233         if (!context_->getServerMode())
00234         {
00235                 if (getWeapon()->getShowShotPath())
00236                 {
00237                         RenderTracer::instance()->
00238                                 addSmokeTracer(weaponContext_.getPlayerId(), 
00239                                         position.asVector(), positions_);
00240                 }
00241                 else if (getWeapon()->getShowEndPoint())
00242                 {
00243                         RenderTracer::instance()->
00244                                 addTracer(weaponContext_.getPlayerId(), position.asVector());
00245                 }
00246         }
00247 #endif // #ifndef S3D_SERVER
00248 
00249         FixedVector velocity;
00250         getWeapon()->getCollisionAction()->fireWeapon(
00251                 *context_, weaponContext_, position, getCurrentVelocity());
00252 }
00253 

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