1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2003
4 // This file is part of Scorched3D.
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>
23 #include <sprites/MissileActionRenderer.h>
24 #include <tankgraph/RenderTracer.h>
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>
37 ShotProjectile::ShotProjectile(FixedVector
&startPosition
, FixedVector
&velocity
,
38 WeaponProjectile
*weapon
, WeaponFireContext
&weaponContext
,
39 unsigned int flareType
,
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()
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
)
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();
98 Tank
*tank
= (*itor
).second
;
99 TankAI
*ai
= tank
->getTankAI();
102 if (tank
->getState().getState() == TankState::sNormal
&&
103 !tank
->getState().getSpectator())
105 ai
->shotLanded(collisionId
,
106 getWeapon(), getPlayerId(),
107 getCurrentPosition().asVector());
114 // Apex collisions dud if they collide with the ground
115 // unless no dud is set
116 if (getWeapon()->getApexCollision() && !getWeapon()->getApexNoDud())
120 if ((getWeapon()->getTimedCollision(*context_
) > 0) && getWeapon()->getTimedDud())
125 if (doColl
) doCollision(position
.getPosition());
127 PhysicsParticleReferenced::collision(position
, collisionId
);
130 void ShotProjectile::simulate(fixed frameTime
, bool &remove
)
132 totalTime_
+= frameTime
;
135 vPoint_
->setPosition(getCurrentPosition());
137 FixedVector velocity
= -getCurrentVelocity();
139 vPoint_
->setLookFrom(velocity
);
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());
165 getWeapon()->getApexCollision())
167 if (getCurrentVelocity()[2] > 0) up_
= true;
170 doCollision(getCurrentPosition());
176 if (thrustAmount_
> 0)
178 if (totalTime_
< thrustTime_
||
181 FixedVector direction
= getCurrentVelocity();
182 direction
.StoreNormalize();
183 direction
*= thrustAmount_
;
184 applyForce(direction
);
191 FixedVector direction
= getCurrentVelocity();
193 applyForce(direction
);
200 if (totalTime_
> timedCollision_
)
202 doCollision(getCurrentPosition());
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
);
225 #endif // #ifndef S3D_SERVER
227 PhysicsParticleReferenced::simulate(frameTime
, remove
);
230 void ShotProjectile::doCollision(FixedVector
&position
)
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());