| 1 | /* | 
|---|
| 2 |  * GravityBombField.cc | 
|---|
| 3 |  * | 
|---|
| 4 |  *  Created on: Apr 2, 2015 | 
|---|
| 5 |  *      Author: meggiman | 
|---|
| 6 |  */ | 
|---|
| 7 |  | 
|---|
| 8 | #include "GravityBombField.h" | 
|---|
| 9 | #include "graphics/Model.h" | 
|---|
| 10 |  | 
|---|
| 11 | namespace orxonox{ | 
|---|
| 12 |         RegisterClass(GravityBombField); | 
|---|
| 13 |  | 
|---|
| 14 |         const float GravityBombField::FORCE_FIELD_LIFETIME = 20; | 
|---|
| 15 |         const float GravityBombField::FORCE_SPHERE_START_RADIUS = 250; | 
|---|
| 16 |         const float GravityBombField::FORCE_SPHERE_START_STRENGTH = -500; | 
|---|
| 17 |         const float GravityBombField::PEAK_EXPLOSION_FORCE = 1e6; | 
|---|
| 18 |         const float GravityBombField::FORCE_FIELD_EXPLOSION_DAMMAGE = 100; | 
|---|
| 19 |         const float GravityBombField::EXPLOSION_DURATION = 1; | 
|---|
| 20 |         const float GravityBombField::EXPLOSION_RADIUS = 400; | 
|---|
| 21 |         const float GravityBombField::PEAK_ANGULAR_VELOCITY = 20; | 
|---|
| 22 |  | 
|---|
| 23 |         GravityBombField::GravityBombField(Context* context) : ForceField(context),RadarViewable(this, static_cast<WorldEntity*>(this)) | 
|---|
| 24 |         { | 
|---|
| 25 |                 RegisterObject(GravityBombField); | 
|---|
| 26 |                 lifetime_=FORCE_FIELD_LIFETIME; | 
|---|
| 27 |                 forceStrength_ = FORCE_SPHERE_START_STRENGTH; | 
|---|
| 28 |                 forceSphereRadius_ = FORCE_SPHERE_START_RADIUS; | 
|---|
| 29 |                 fieldExploded_ = false; | 
|---|
| 30 |  | 
|---|
| 31 |                 setVelocity(FORCE_SPHERE_START_STRENGTH); | 
|---|
| 32 |                 setDiameter(2*FORCE_SPHERE_START_RADIUS); | 
|---|
| 33 |                 setMode(modeSphere_s); | 
|---|
| 34 |                 setCollisionResponse(false); | 
|---|
| 35 |  | 
|---|
| 36 |                 this->setRadarObjectColour(ColourValue(0.2, 0.2, 1.0,1)); // Blue | 
|---|
| 37 |                 this->setRadarObjectShape(RadarViewable::Dot); | 
|---|
| 38 |                 this->setRadarObjectScale(0.5f); | 
|---|
| 39 |  | 
|---|
| 40 |                 //Attach Model | 
|---|
| 41 |                 Model* model = new Model(this->getContext()); | 
|---|
| 42 |                 model->setMeshSource("GravityBomb.mesh"); //Demo Model from SimpleRocket | 
|---|
| 43 |                 model->scale(3.0f); | 
|---|
| 44 |                 bombModel_ = new MovableEntity(context); | 
|---|
| 45 |                 bombModel_->attach(model); | 
|---|
| 46 |                 this->attach(bombModel_); | 
|---|
| 47 |  | 
|---|
| 48 |                 Backlight* centreLight = new Backlight(context); | 
|---|
| 49 |                 centreLight->setColour(ColourValue(0.9,0.5,0.5,1)); | 
|---|
| 50 |                 centreLight->setScale(1.0); | 
|---|
| 51 |                 centreLight->setTrailMaterial("Trail/backlighttrail"); | 
|---|
| 52 |                 centreLight->setMaterial("Examples/Flare"); | 
|---|
| 53 |                 centreLight->setLifetime(20); | 
|---|
| 54 |                 bombModel_->attach(centreLight); | 
|---|
| 55 |  | 
|---|
| 56 |                 Vector3 randomRotation; | 
|---|
| 57 |                 srand(time(NULL)); | 
|---|
| 58 |                 randomRotation.x = rand(); | 
|---|
| 59 |                 randomRotation.y = rand(); | 
|---|
| 60 |                 randomRotation.y = rand(); | 
|---|
| 61 |                 randomRotation.normalise(); | 
|---|
| 62 |                 bombModel_->setAngularAcceleration(randomRotation*(PEAK_ANGULAR_VELOCITY/FORCE_FIELD_LIFETIME)); | 
|---|
| 63 |  | 
|---|
| 64 |                 //Add Collision Shape | 
|---|
| 65 |                 SphereCollisionShape* collisionShape = new SphereCollisionShape(context); | 
|---|
| 66 |                 collisionShape->setRadius(3.0); | 
|---|
| 67 |                 this->attachCollisionShape(collisionShape); | 
|---|
| 68 |  | 
|---|
| 69 |                 this->particleSphere_ = new ParticleEmitter(this->getContext()); | 
|---|
| 70 |                 this->attach(this->particleSphere_); | 
|---|
| 71 |                 particleSphere_->setSource("Orxonox/GravityBombField"); | 
|---|
| 72 |         } | 
|---|
| 73 |  | 
|---|
| 74 |         GravityBombField::~GravityBombField(){} | 
|---|
| 75 |  | 
|---|
| 76 |         void GravityBombField::tick(float dt) | 
|---|
| 77 |         { | 
|---|
| 78 |                 SUPER(GravityBombField,tick,dt); | 
|---|
| 79 |                 lifetime_-=dt; | 
|---|
| 80 |  | 
|---|
| 81 |                 if(lifetime_ > EXPLOSION_DURATION) | 
|---|
| 82 |                 { | 
|---|
| 83 |                         forceStrength_ *= (1+dt/10); | 
|---|
| 84 |                         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)); | 
|---|
| 85 |                 } | 
|---|
| 86 |                 else if(lifetime_ > 0) | 
|---|
| 87 |                 { | 
|---|
| 88 |                         if (!fieldExploded_) | 
|---|
| 89 |                         { | 
|---|
| 90 |                                 forceStrength_ = PEAK_EXPLOSION_FORCE; | 
|---|
| 91 |                                 fieldExploded_ = true; | 
|---|
| 92 |  | 
|---|
| 93 |                                 explosionCross_ = new ParticleEmitter(this->getContext()); | 
|---|
| 94 |                                 this->attach(explosionCross_); | 
|---|
| 95 |                                 explosionCross_->setSource("Orxonox/FieldExplosion"); | 
|---|
| 96 |                         } | 
|---|
| 97 |  | 
|---|
| 98 |                         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it) | 
|---|
| 99 |                         { | 
|---|
| 100 |                                 Vector3 distanceVector = it->getWorldPosition()-this->getWorldPosition(); | 
|---|
| 101 |                                  orxout(debug_output) << "Found Pawn:" << it->getWorldPosition() << endl; | 
|---|
| 102 |                                 if(distanceVector.length()< forceSphereRadius_) | 
|---|
| 103 |                                  { | 
|---|
| 104 |                                          orxout(debug_output) << "Force sphere radius is: " << forceSphereRadius_ << " Distance to Pawn is: " << distanceVector.length(); | 
|---|
| 105 |                                          if (std::find(victimsAlreadyDamaged_.begin(),victimsAlreadyDamaged_.end(),*it) == victimsAlreadyDamaged_.end()) | 
|---|
| 106 |                                          { | 
|---|
| 107 |                                                  orxout(debug_output) << "Found Pawn to damage: " << it->getWorldPosition() << endl; | 
|---|
| 108 |                                                  float damage = FORCE_FIELD_EXPLOSION_DAMMAGE*(1-distanceVector.length()/EXPLOSION_RADIUS); | 
|---|
| 109 |                                                  orxout(debug_output) << "Damage: " << damage << endl; | 
|---|
| 110 |                                                  it->hit(shooter_, it->getWorldPosition(), NULL, damage, 0,0); | 
|---|
| 111 | //                                               it->removeHealth(damage); | 
|---|
| 112 |                                                  victimsAlreadyDamaged_.push_back(*it); | 
|---|
| 113 |                                          } | 
|---|
| 114 |                                  } | 
|---|
| 115 |                         } | 
|---|
| 116 |  | 
|---|
| 117 |                         forceSphereRadius_ = EXPLOSION_RADIUS*(1-lifetime_/EXPLOSION_DURATION); | 
|---|
| 118 |                         explosionCross_->setScale(forceSphereRadius_/FORCE_SPHERE_START_RADIUS); | 
|---|
| 119 |                 } | 
|---|
| 120 |                 else if (lifetime_ > -4) | 
|---|
| 121 |                 { | 
|---|
| 122 |                         bombModel_->setVisible(false); | 
|---|
| 123 |                         this->setRadarVisibility(false); | 
|---|
| 124 |                         forceStrength_ = 0; | 
|---|
| 125 |                         forceSphereRadius_ = 0.00001; | 
|---|
| 126 |                         particleSphere_->getParticleInterface()->removeAllEmitters(); | 
|---|
| 127 |                         explosionCross_->getParticleInterface()->removeAllEmitters(); | 
|---|
| 128 |                 } | 
|---|
| 129 |  | 
|---|
| 130 |                 setDiameter(forceSphereRadius_*2); | 
|---|
| 131 |                 setVelocity(forceStrength_); | 
|---|
| 132 |                 particleSphere_->setScale(forceSphereRadius_/FORCE_SPHERE_START_RADIUS); | 
|---|
| 133 |  | 
|---|
| 134 |                 if (lifetime_ <= -4) | 
|---|
| 135 |                 { | 
|---|
| 136 |                         orxout(debug_output) << "Timeout. Destroying field." << endl; | 
|---|
| 137 |                         this->destroy(); | 
|---|
| 138 |                 } | 
|---|
| 139 |         } | 
|---|
| 140 |  | 
|---|
| 141 |         void GravityBombField::destroy() | 
|---|
| 142 |         { | 
|---|
| 143 |                 //Animation | 
|---|
| 144 |                 ForceField::destroy(); | 
|---|
| 145 |         } | 
|---|
| 146 |  | 
|---|
| 147 | } | 
|---|