00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00115
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
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
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
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
00189 if (drag_ > 0)
00190 {
00191 FixedVector direction = getCurrentVelocity();
00192 direction *= -drag_;
00193 applyForce(direction);
00194 }
00195
00196
00197 if (!remove &&
00198 timedCollision_ > 0)
00199 {
00200 if (totalTime_ > timedCollision_)
00201 {
00202 doCollision(getCurrentPosition());
00203 remove = true;
00204 }
00205 }
00206
00207
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