- Timestamp:
- Sep 27, 2015, 10:03:53 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/weaponFS15/src/modules/weapons/projectiles/GravityBombField.cc
r10502 r10601 10 10 11 11 namespace orxonox{ 12 12 RegisterClass(GravityBombField); 13 13 14 15 16 17 18 19 20 21 22 23 24 14 //Change these constants to alter the behaviour of the field. 15 16 const float GravityBombField::FORCE_FIELD_LIFETIME = 15; 17 const float GravityBombField::FORCE_SPHERE_START_RADIUS = 250; 18 const float GravityBombField::FORCE_SPHERE_START_STRENGTH = -700; 19 const float GravityBombField::PEAK_EXPLOSION_FORCE = 5e4; 20 const float GravityBombField::FORCE_FIELD_EXPLOSION_DAMMAGE = 100; 21 const float GravityBombField::EXPLOSION_DURATION = 1; 22 const float GravityBombField::EXPLOSION_RADIUS = 600; 23 const float GravityBombField::PEAK_ANGULAR_VELOCITY = 20; 24 const float GravityBombField::CENTRE_MODEL_END_SIZE = 1.5; 25 25 26 27 28 29 30 31 32 33 34 26 GravityBombField::GravityBombField(Context* context) : ForceField(context),RadarViewable(this, static_cast<WorldEntity*>(this)) 27 { 28 RegisterObject(GravityBombField); 29 //Initialize variable with their initial values. 30 lifetime_=FORCE_FIELD_LIFETIME; 31 forceStrength_ = FORCE_SPHERE_START_STRENGTH; 32 forceSphereRadius_ = FORCE_SPHERE_START_RADIUS; 33 modelScaling_ = 1; 34 fieldExploded_ = false; 35 35 36 37 38 39 36 setVelocity(FORCE_SPHERE_START_STRENGTH); 37 setDiameter(2*FORCE_SPHERE_START_RADIUS); 38 setMode(modeSphere_s); 39 setCollisionResponse(false); 40 40 41 42 43 44 45 41 //Make the Field visible on Radar and minimap. 42 this->setRadarObjectColour(ColourValue(1.0, 0.0, 0.2,1)); // Red 43 this->setRadarObjectShape(RadarViewable::Dot); 44 this->setRadarObjectScale(1.0f); 45 46 46 47 48 49 50 51 52 53 47 //Attach Model 48 Model* model = new Model(this->getContext()); 49 model->setMeshSource("GravityBomb.mesh"); //Demo Model from SimpleRocket 50 model->scale(2.5f); 51 bombModel_ = new MovableEntity(context); 52 bombModel_->attach(model); 53 this->attach(bombModel_); 54 54 55 56 57 58 59 60 61 62 55 //Add a Backlight to the centre. 56 centreLight_ = new Backlight(context); 57 centreLight_->setColour(ColourValue(0.2,0.9,0.2,1)); 58 centreLight_->setScale(0.3); 59 centreLight_->setTrailMaterial("Trail/backlighttrail"); 60 centreLight_->setMaterial("Examples/Flare"); 61 centreLight_->setLifetime(20); 62 bombModel_->attach(centreLight_); 63 63 64 65 66 67 68 69 70 71 64 //Let the Bomb Modell in the centre rotate in a random direction. 65 Vector3 randomRotation; 66 srand(time(NULL)); 67 randomRotation.x = rand(); 68 randomRotation.y = rand(); 69 randomRotation.y = rand(); 70 randomRotation.normalise(); 71 bombModel_->setAngularAcceleration(randomRotation*(PEAK_ANGULAR_VELOCITY/FORCE_FIELD_LIFETIME)); 72 72 73 74 75 76 73 //Add Collision Shape 74 SphereCollisionShape* collisionShape = new SphereCollisionShape(context); 75 collisionShape->setRadius(10.0); 76 this->attachCollisionShape(collisionShape); 77 77 78 79 80 81 78 //Add particle effect to visualize the force field. 79 this->particleSphere_ = new ParticleEmitter(this->getContext()); 80 this->attach(this->particleSphere_); 81 particleSphere_->setSource("Orxonox/GravityBombField"); 82 82 83 84 85 86 87 88 89 90 83 //Add a sound effect to the field. 84 WorldSound* fieldSound = new WorldSound(context); 85 fieldSound->setSource("sounds/GravityField.ogg"); 86 fieldSound->setLooping(true); 87 fieldSound->setVolume(1.0); 88 this->attach(fieldSound); 89 fieldSound->play(); 90 } 91 91 92 92 GravityBombField::~GravityBombField(){} 93 93 94 95 96 97 98 94 95 void GravityBombField::tick(float dt) 96 { 97 SUPER(GravityBombField,tick,dt); 98 lifetime_-=dt; 99 99 100 101 102 103 104 105 106 107 108 109 110 111 100 if(lifetime_ > EXPLOSION_DURATION)//If field is still alive, make it smaller and stronger. 101 { 102 modelScaling_ += ((CENTRE_MODEL_END_SIZE-1) / FORCE_FIELD_LIFETIME)*dt; 103 forceStrength_ *= (1+dt/10); 104 forceSphereRadius_ = FORCE_SPHERE_START_RADIUS*(1-((FORCE_FIELD_LIFETIME-lifetime_)/FORCE_FIELD_LIFETIME)*((FORCE_FIELD_LIFETIME-lifetime_)/FORCE_FIELD_LIFETIME)*((FORCE_FIELD_LIFETIME-lifetime_)/FORCE_FIELD_LIFETIME)); 105 } 106 else if(lifetime_ > 0) 107 { 108 if (!fieldExploded_) // Start the field explosion if it has not been started yet. 109 { 110 forceStrength_ = pow((EXPLOSION_DURATION + lifetime_),4)/EXPLOSION_DURATION * PEAK_EXPLOSION_FORCE; 111 fieldExploded_ = true; 112 112 113 114 115 116 117 118 113 //Add particle effect to visualize explosion 114 explosionCross_ = new ParticleEmitter(this->getContext()); 115 explosionCross_->setSource("Orxonox/FieldExplosion"); 116 explosionCross_->setOrientation(rand(), rand(), rand(), rand()); 117 explosionCross_->setScale(0.7); 118 this->attach(explosionCross_); 119 119 120 121 122 123 124 125 120 //Add explosion sound effect. 121 explosionSound_ = new WorldSound(getContext()); 122 explosionSound_->setSource("sounds/GravityFieldExplosion.ogg"); 123 explosionSound_->setVolume(1.0); 124 explosionSound_->play(); 125 } 126 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 127 //Check if any pawn is inside the shockwave and hit it with dammage proportional to the distance between explosion centre and pawn. Make sure, the same pawn is damaged only once. 128 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it) 129 { 130 Vector3 distanceVector = it->getWorldPosition()-this->getWorldPosition(); 131 //orxout(debug_output) << "Found Pawn:" << it->getWorldPosition() << endl; 132 if(distanceVector.length()< forceSphereRadius_) 133 { 134 //orxout(debug_output) << "Force sphere radius is: " << forceSphereRadius_ << " Distance to Pawn is: " << distanceVector.length(); 135 if (std::find(victimsAlreadyDamaged_.begin(),victimsAlreadyDamaged_.end(),*it) == victimsAlreadyDamaged_.end()) 136 { 137 //orxout(debug_output) << "Found Pawn to damage: " << it->getWorldPosition() << endl; 138 float damage = FORCE_FIELD_EXPLOSION_DAMMAGE*(1-distanceVector.length()/EXPLOSION_RADIUS); 139 //orxout(debug_output) << "Damage: " << damage << endl; 140 it->hit(shooter_, it->getWorldPosition(), NULL, damage, 0,0); 141 victimsAlreadyDamaged_.push_back(*it); 142 } 143 } 144 } 145 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 146 forceSphereRadius_ = EXPLOSION_RADIUS*(1-lifetime_/EXPLOSION_DURATION); 147 explosionCross_->setScale(forceSphereRadius_/FORCE_SPHERE_START_RADIUS); 148 } 149 else if (lifetime_ > -6) //The field has to exist for 6 more seconds for the particles of the particle effect to vanish smoothly. 150 { 151 //Make the bomb model invisible, let the strength of the field be zero and remove all particle emitters so the particle effect will slowly vanish. 152 bombModel_->setVisible(false); 153 this->setRadarVisibility(false); 154 forceStrength_ = 0; 155 forceSphereRadius_ = 0.00001; 156 particleSphere_->getParticleInterface()->removeAllEmitters(); 157 explosionCross_->getParticleInterface()->removeAllEmitters(); 158 } 159 160 setDiameter(forceSphereRadius_*2); 161 setVelocity(forceStrength_); 162 if(lifetime_>0) particleSphere_->setScale(forceSphereRadius_/FORCE_SPHERE_START_RADIUS); 163 bombModel_->setScale(modelScaling_); 164 164 165 166 167 168 169 170 165 if (lifetime_ <= -4) 166 { 167 orxout(debug_output) << "Timeout. Destroying field." << endl; 168 this->destroy(); 169 } 170 } 171 171 172 173 174 175 172 void GravityBombField::destroy() 173 { 174 ForceField::destroy(); 175 } 176 176 177 177 }
Note: See TracChangeset
for help on using the changeset viewer.