Merge from development branch heightmap to main.
[scorched3d.git] / src / common / actions / ShotProjectile.cpp
blobeafe68439789806285549e5afc53f195cd2976c7
1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2003
3 //
4 // This file is part of Scorched3D.
5 //
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // Scorched3D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with Scorched3D; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ////////////////////////////////////////////////////////////////////////////////
21 #include <actions/ShotProjectile.h>
22 #ifndef S3D_SERVER
23 #include <sprites/MissileActionRenderer.h>
24 #include <tankgraph/RenderTracer.h>
25 #endif
26 #include <landscapemap/LandscapeMaps.h>
27 #include <landscapedef/LandscapeTex.h>
28 #include <tank/TankContainer.h>
29 #include <tank/TankState.h>
30 #include <tankai/TankAI.h>
31 #include <common/Defines.h>
32 #include <engine/ScorchedContext.h>
33 #include <engine/ViewPoints.h>
34 #include <weapons/AccessoryStore.h>
35 #include <math.h>
37 ShotProjectile::ShotProjectile(FixedVector &startPosition, FixedVector &velocity,
38 WeaponProjectile *weapon, WeaponFireContext &weaponContext,
39 unsigned int flareType,
40 fixed spinSpeed ) :
41 startPosition_(startPosition), velocity_(velocity),
42 weapon_(weapon), weaponContext_(weaponContext),
43 flareType_(flareType), vPoint_(0),
44 snapTime_(fixed(true, 2000)), up_(false),
45 totalTime_(0), spinSpeed_(spinSpeed)
50 void ShotProjectile::init()
52 #ifndef S3D_SERVER
53 if (!context_->getServerMode())
55 setActionRender(new MissileActionRenderer(flareType_,
56 weapon_->getScale(*context_).asFloat(),
57 spinSpeed_.asFloat()));
59 #endif // #ifndef S3D_SERVER
61 vPoint_ = context_->getViewPoints().getNewViewPoint(weaponContext_.getPlayerId());
62 PhysicsParticleInfo info(ParticleTypeShot, weaponContext_.getPlayerId(), this);
63 setPhysics(info, startPosition_, velocity_,
64 0, 0, weapon_->getWindFactor(*context_), getWeapon()->getUnder(),
65 false, getWeapon()->getWallCollision());
66 thrustTime_ = getWeapon()->getThrustTime(*context_);
67 thrustAmount_ = getWeapon()->getThrustAmount(*context_);
68 timedCollision_ = getWeapon()->getTimedCollision(*context_);
69 drag_ = getWeapon()->getDrag(*context_);
72 std::string ShotProjectile::getActionDetails()
74 return S3D::formatStringBuffer("%i,%i,%i %i,%i,%i %s",
75 startPosition_[0].getInternal(), startPosition_[1].getInternal(), startPosition_[2].getInternal(),
76 velocity_[0].getInternal(), velocity_[1].getInternal(), velocity_[2].getInternal(),
77 weapon_->getParent()->getName());
80 ShotProjectile::~ShotProjectile()
82 if (vPoint_) context_->getViewPoints().releaseViewPoint(vPoint_);
85 void ShotProjectile::collision(PhysicsParticleObject &position,
86 ScorchedCollisionId collisionId)
88 if (!collision_)
90 // Tell all AIs about this collision
91 std::map<unsigned int, Tank *> tanks =
92 context_->getTankContainer().getAllTanks();
93 std::map<unsigned int, Tank *>::iterator itor;
94 for (itor = tanks.begin();
95 itor != tanks.end();
96 itor++)
98 Tank *tank = (*itor).second;
99 TankAI *ai = tank->getTankAI();
100 if (ai)
102 if (tank->getState().getState() == TankState::sNormal &&
103 !tank->getState().getSpectator())
105 ai->shotLanded(collisionId,
106 getWeapon(), getPlayerId(),
107 getCurrentPosition().asVector());
112 bool doColl = true;
114 // Apex collisions dud if they collide with the ground
115 // unless no dud is set
116 if (getWeapon()->getApexCollision() && !getWeapon()->getApexNoDud())
118 doColl = false;
120 if ((getWeapon()->getTimedCollision(*context_) > 0) && getWeapon()->getTimedDud())
122 doColl = false;
125 if (doColl) doCollision(position.getPosition());
127 PhysicsParticleReferenced::collision(position, collisionId);
130 void ShotProjectile::simulate(fixed frameTime, bool &remove)
132 totalTime_ += frameTime;
133 if (vPoint_)
135 vPoint_->setPosition(getCurrentPosition());
137 FixedVector velocity = -getCurrentVelocity();
138 velocity[2] = 10;
139 vPoint_->setLookFrom(velocity);
142 // Water collision
143 if (!remove &&
144 getWeapon()->getWaterCollision())
146 fixed waterHeight = -10;
147 LandscapeTex &tex = *context_->getLandscapeMaps().getDefinitions().getTex();
148 if (tex.border->getType() == LandscapeTexType::eWater)
150 LandscapeTexBorderWater *water =
151 (LandscapeTexBorderWater *) tex.border;
153 waterHeight = water->height;
156 if (getCurrentPosition()[2] < waterHeight)
158 doCollision(getCurrentPosition());
159 remove = true;
163 // Apex collision
164 if (!remove &&
165 getWeapon()->getApexCollision())
167 if (getCurrentVelocity()[2] > 0) up_ = true;
168 else if (up_)
170 doCollision(getCurrentPosition());
171 remove = true;
175 // Thrust
176 if (thrustAmount_ > 0)
178 if (totalTime_ < thrustTime_ ||
179 thrustTime_ == 0)
181 FixedVector direction = getCurrentVelocity();
182 direction.StoreNormalize();
183 direction *= thrustAmount_;
184 applyForce(direction);
188 // Drag
189 if (drag_ > 0)
191 FixedVector direction = getCurrentVelocity();
192 direction *= -drag_;
193 applyForce(direction);
196 // Timed collision
197 if (!remove &&
198 timedCollision_ > 0)
200 if (totalTime_ > timedCollision_)
202 doCollision(getCurrentPosition());
203 remove = true;
207 // Shot path
208 #ifndef S3D_SERVER
209 if (!context_->getServerMode())
211 if (getWeapon()->getShowShotPath())
213 snapTime_ += frameTime;
214 if (snapTime_.asFloat() > 0.1f || remove)
216 Vector up (0.0f, 0.0f, 1.0f);
217 RenderTracer::TracerLinePoint point;
218 point.position = getCurrentPosition().asVector();
219 point.cross = (getCurrentVelocity().asVector() * up).Normalize();
220 positions_.push_back(point);
221 snapTime_ = 0;
225 #endif // #ifndef S3D_SERVER
227 PhysicsParticleReferenced::simulate(frameTime, remove);
230 void ShotProjectile::doCollision(FixedVector &position)
232 #ifndef S3D_SERVER
233 if (!context_->getServerMode())
235 if (getWeapon()->getShowShotPath())
237 RenderTracer::instance()->
238 addSmokeTracer(weaponContext_.getPlayerId(),
239 position.asVector(), positions_);
241 else if (getWeapon()->getShowEndPoint())
243 RenderTracer::instance()->
244 addTracer(weaponContext_.getPlayerId(), position.asVector());
247 #endif // #ifndef S3D_SERVER
249 FixedVector velocity;
250 getWeapon()->getCollisionAction()->fireWeapon(
251 *context_, weaponContext_, position, getCurrentVelocity());