00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <sprites/MissileActionRenderer.h>
00022 #include <sprites/ExplosionTextures.h>
00023 #include <GLEXT/GLCameraFrustum.h>
00024 #include <weapons/Accessory.h>
00025 #include <actions/ShotProjectile.h>
00026 #include <landscape/Landscape.h>
00027 #include <landscapemap/LandscapeMaps.h>
00028 #include <landscape/ShadowMap.h>
00029 #include <graph/OptionsDisplay.h>
00030 #include <common/Defines.h>
00031 #include <tank/TankContainer.h>
00032 #include <client/ScorchedClient.h>
00033 #include <engine/ScorchedContext.h>
00034 #include <graph/ParticleEngine.h>
00035 #include <sound/Sound.h>
00036
00037 MissileActionRenderer::MissileActionRenderer(int flareType, float scale, float spinSpeed) :
00038 flareType_(flareType), counter_(0.05f, 0.05f),
00039 mesh_(0), scale_(scale), rotation_(180.0f),
00040 flameemitter_(0), smokeemitter_(0), sound_(0),
00041 spinSpeed_(spinSpeed)
00042 {
00043 frame_ = (float) rand();
00044 }
00045
00046 MissileActionRenderer::~MissileActionRenderer()
00047 {
00048 delete flameemitter_;
00049 delete smokeemitter_;
00050 delete sound_;
00051 }
00052
00053 void MissileActionRenderer::simulate(Action *action, float timepassed, bool &remove)
00054 {
00055 ShotProjectile *shot = (ShotProjectile *) action;
00056 if (!flameemitter_)
00057 {
00058 flameemitter_ = new ParticleEmitter;
00059 flameemitter_->setAttributes(
00060 shot->getWeapon()->getFlameLife() / 2.0f, shot->getWeapon()->getFlameLife(),
00061 0.5f, 1.0f,
00062 0.01f, 0.02f,
00063 Vector(-0.05f, -0.1f, 0.3f), Vector(0.05f, 0.1f, 0.9f),
00064 shot->getWeapon()->getFlameStartColor1(), 0.9f,
00065 shot->getWeapon()->getFlameStartColor2(), 1.0f,
00066 shot->getWeapon()->getFlameEndColor1(), 0.0f,
00067 shot->getWeapon()->getFlameEndColor2(), 0.1f,
00068 shot->getWeapon()->getFlameStartSize() / 2.0f, shot->getWeapon()->getFlameStartSize() / 2.0f, shot->getWeapon()->getFlameStartSize(), shot->getWeapon()->getFlameStartSize(),
00069 shot->getWeapon()->getFlameEndSize() / 2.0f, shot->getWeapon()->getFlameEndSize() / 2.0f, shot->getWeapon()->getFlameEndSize(), shot->getWeapon()->getFlameEndSize(),
00070 Vector(0.0f, 0.0f, 10.0f),
00071 true,
00072 true);
00073 }
00074 if (!smokeemitter_)
00075 {
00076 smokeemitter_ = new ParticleEmitter;
00077 smokeemitter_->setAttributes(
00078 shot->getWeapon()->getSmokeLife() / 2.0f, shot->getWeapon()->getSmokeLife(),
00079 0.2f, 0.5f,
00080 0.01f, 0.02f,
00081 Vector(-0.05f, -0.1f, 0.3f), Vector(0.05f, 0.1f, 0.9f),
00082 Vector(0.7f, 0.7f, 0.7f), 0.3f,
00083 Vector(0.7f, 0.7f, 0.7f), 0.3f,
00084 Vector(0.7f, 0.7f, 0.7f), 0.0f,
00085 Vector(0.8f, 0.8f, 0.8f), 0.1f,
00086 shot->getWeapon()->getSmokeStartSize() / 2.0f, shot->getWeapon()->getSmokeStartSize() / 2.0f, shot->getWeapon()->getSmokeStartSize(), shot->getWeapon()->getSmokeStartSize(),
00087 shot->getWeapon()->getSmokeEndSize() / 2.0f, shot->getWeapon()->getSmokeEndSize() / 2.0f, shot->getWeapon()->getSmokeEndSize(), shot->getWeapon()->getSmokeEndSize(),
00088 Vector(0.0f, 0.0f, 100.0f),
00089 false,
00090 true);
00091 }
00092 if (!sound_)
00093 {
00094 const char *engineSound = shot->getWeapon()->getEngineSound();
00095 if (0 != strcmp("none", engineSound))
00096 {
00097 SoundBuffer *rocket = Sound::instance()->fetchOrCreateBuffer(
00098 S3D::getDataFile(engineSound));
00099 sound_ = new VirtualSoundSource(VirtualSoundPriority::eMissile, true, false);
00100 sound_->setPosition(shot->getCurrentPosition().asVector());
00101 sound_->setGain(0.25f);
00102 sound_->play(rocket);
00103 }
00104 }
00105 if (sound_)
00106 {
00107 sound_->setPosition(shot->getCurrentPosition().asVector());
00108 sound_->setVelocity(shot->getCurrentVelocity().asVector());
00109 }
00110
00111 Vector &actualPos = shot->getCurrentPosition().asVector();
00112 Vector actualPos1;
00113 actualPos1[0] = actualPos[0] - 0.25f;
00114 actualPos1[1] = actualPos[1] - 0.25f;
00115 actualPos1[2] = actualPos[2] - 0.25f;
00116 Vector actualPos2;
00117 actualPos2[0] = actualPos[0] + 0.25f;
00118 actualPos2[1] = actualPos[1] + 0.25f;
00119 actualPos2[2] = actualPos[2] + 0.25f;
00120
00121
00122 frame_ += timepassed * 20.0f;
00123 rotation_ += shot->getCurrentVelocity().Magnitude().asFloat() * spinSpeed_;
00124
00125
00126
00127 if (shot->getWeapon()->getCreateFlame())
00128 {
00129 flameemitter_->emitLinear(2, actualPos1, actualPos2,
00130 ScorchedClient::instance()->getParticleEngine(),
00131 ParticleRendererQuads::getInstance());
00132 }
00133
00134
00135 if (shot->getWeapon()->getCreateSmoke())
00136 {
00137 if (counter_.nextDraw(timepassed))
00138 {
00139 Vector vel1 = shot->getCurrentVelocity().asVector();
00140 Vector vel2;
00141 vel1 *= -0.4f;
00142 vel2 = vel1 * 0.7f;
00143
00144 actualPos1 -= shot->getCurrentVelocity().asVector() * 0.2f;
00145 actualPos2 -= shot->getCurrentVelocity().asVector() * 0.2f;
00146
00147 smokeemitter_->setVelocity(vel1, vel2);
00148 smokeemitter_->emitLinear(3, actualPos1, actualPos2,
00149 ScorchedClient::instance()->getParticleEngine(),
00150 ParticleRendererQuads::getInstance());
00151 }
00152 }
00153 }
00154
00155 void MissileActionRenderer::draw(Action *action)
00156 {
00157 ShotProjectile *shot = (ShotProjectile *) action;
00158 Vector &actualPos = shot->getCurrentPosition().asVector();
00159 Vector &actualdir = shot->getCurrentVelocity().asVector();
00160
00161 if (shot->getWeapon()->getShowShotPath())
00162 {
00163 Tank *current =
00164 action->getScorchedContext()->getTankContainer().
00165 getTankById(shot->getPlayerId());
00166 if (current)
00167 {
00168 glColor3fv(current->getColor());
00169 RenderTracer::instance()->drawSmokeTracer(
00170 shot->getPositions());
00171 }
00172 }
00173
00174
00175 if (!GLCameraFrustum::instance()->sphereInFrustum(actualPos, 1.0f))
00176 {
00177 return;
00178 }
00179
00180
00181 if (!mesh_)
00182 {
00183 Tank *currentPlayer = action->
00184 getScorchedContext()->getTankContainer().getTankById(
00185 shot->getPlayerId());
00186 mesh_ = Accessory::getWeaponMesh(
00187 shot->getWeapon()->getModelID(), currentPlayer);
00188 }
00189
00190
00191 mesh_->setScale(scale_);
00192 mesh_->draw(actualPos, actualdir, flareType_, rotation_, frame_);
00193
00194
00195 float aboveGround =
00196 actualPos[2] - ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().
00197 getHeight((int) actualPos[0], (int) actualPos[1]).asFloat();
00198 Landscape::instance()->getShadowMap().
00199 addCircle(actualPos[0], actualPos[1], aboveGround / 10.0f);
00200 }