Changeset 1629 for code/branches/input/src/orxonox/objects/SpaceShipAI.cc
- Timestamp:
- Jun 27, 2008, 8:07:29 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/input/src/orxonox/objects/SpaceShipAI.cc
r1505 r1629 32 32 #include <OgreMath.h> 33 33 #include "Projectile.h" 34 #include "ParticleSpawner.h" 34 35 #include "core/CoreIncludes.h" 35 36 #include "core/Iterator.h" … … 37 38 #include "core/ConsoleCommand.h" 38 39 #include "core/XMLPort.h" 40 #include "tools/ParticleInterface.h" 39 41 40 42 #define ACTION_INTERVAL 1.0f … … 51 53 RegisterObject(SpaceShipAI); 52 54 53 this->alive_ = true;54 this->setPosition(Vector3(rnd(-1000, 1000), rnd(-1000, 1000), rnd(-1000, 0000)));55 55 this->target_ = 0; 56 56 this->bShooting_ = 0; … … 70 70 } 71 71 72 SpaceShipAI::~SpaceShipAI() 73 { 74 for (Iterator<SpaceShipAI> it = ObjectList<SpaceShipAI>::begin(); it; ++it) 75 it->shipDied(this); 76 } 77 72 78 void SpaceShipAI::XMLPort(Element& xmlelement, XMLPort::Mode mode) 73 79 { 74 80 SpaceShip::XMLPort(xmlelement, mode); 75 myShip_=true;76 81 77 82 this->actionTimer_.setTimer(ACTION_INTERVAL, true, this, createExecutor(createFunctor(&SpaceShipAI::action))); … … 85 90 newenemy->setMesh("assff.mesh"); 86 91 // newenemy->setPosition(0, 0, 0); 92 newenemy->setPosition(Vector3(rnd(-3000, 3000), rnd(-3000, 3000), rnd(-3000, 3000))); 87 93 newenemy->setScale(10); 88 94 newenemy->setMaxSpeed(500); … … 95 101 Element xmlelement; 96 102 newenemy->XMLPort(xmlelement, XMLPort::LoadObject); 103 104 ParticleSpawner* spawneffect = new ParticleSpawner("Orxonox/fairytwirl", LODParticle::normal, 2.0, 0, 0, newenemy->getOrth()); 105 spawneffect->setPosition(newenemy->getPosition() - newenemy->getOrth() * 50); 106 spawneffect->create(); 97 107 } 98 108 } … … 103 113 for (Iterator<SpaceShipAI> it = ObjectList<SpaceShipAI>::begin(); it; ) 104 114 { 105 delete *(it++); 106 ++i; 115 (it++)->kill(); 107 116 if (num && i >= num) 108 117 break; … … 122 131 // search enemy 123 132 random = rnd(maxrand); 124 //std::cout << "search enemy: " << random << std::endl; 125 if (random < 20 && (!this->target_)) 126 { 133 if (random < 15 && (!this->target_)) 127 134 this->searchNewTarget(); 128 }129 135 130 136 // forget enemy 131 137 random = rnd(maxrand); 132 //std::cout << "forget enemy: " << random << std::endl;133 138 if (random < 5 && (this->target_)) 134 {135 139 this->forgetTarget(); 136 }137 140 138 141 // next enemy 139 142 random = rnd(maxrand); 140 //std::cout << "next enemy: " << random << std::endl;141 143 if (random < 10 && (this->target_)) 142 {143 144 this->searchNewTarget(); 144 }145 145 146 146 // fly somewhere 147 147 random = rnd(maxrand); 148 //std::cout << "fly somewhere: " << random << std::endl; 149 if (random < 40 && (!this->bHasTargetPosition_ && !this->target_)) 150 { 148 if (random < 50 && (!this->bHasTargetPosition_ && !this->target_)) 151 149 this->searchNewTargetPosition(); 152 }153 150 154 151 // stop flying 155 152 random = rnd(maxrand); 156 //std::cout << "stop flying: " << random << std::endl;157 153 if (random < 10 && (this->bHasTargetPosition_ && !this->target_)) 158 {159 154 this->bHasTargetPosition_ = false; 160 }161 155 162 156 // fly somewhere else 163 157 random = rnd(maxrand); 164 //std::cout << "fly somewhere else: " << random << std::endl;165 158 if (random < 30 && (this->bHasTargetPosition_ && !this->target_)) 166 {167 159 this->searchNewTargetPosition(); 168 }169 160 170 161 // shoot 171 162 random = rnd(maxrand); 172 //std::cout << "shoot: " << random << std::endl;173 163 if (random < 75 && (this->target_ && !this->bShooting_)) 174 {175 164 this->bShooting_ = true; 176 }177 165 178 166 // stop shooting 179 167 random = rnd(maxrand); 180 //std::cout << "stop shooting: " << random << std::endl;181 168 if (random < 25 && (this->bShooting_)) 182 {183 169 this->bShooting_ = false; 184 } 170 } 171 172 void SpaceShipAI::damage(float damage) 173 { 174 this->health_ -= damage; 175 if (this->health_ <= 0) 176 { 177 this->kill(); 178 SpaceShipAI::createEnemy(1); 179 } 180 } 181 182 void SpaceShipAI::kill() 183 { 184 ParticleSpawner* explosion = new ParticleSpawner("Orxonox/BigExplosion1part1", LODParticle::low, 3.0); 185 explosion->setPosition(this->getPosition()); 186 explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true); 187 explosion->setScale(4); 188 explosion->create(); 189 190 explosion = new ParticleSpawner("Orxonox/BigExplosion1part2", LODParticle::normal, 3.0); 191 explosion->setPosition(this->getPosition()); 192 explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true); 193 explosion->setScale(4); 194 explosion->create(); 195 explosion = new ParticleSpawner("Orxonox/BigExplosion1part2", LODParticle::high, 3.0); 196 explosion->setPosition(this->getPosition()); 197 explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true); 198 explosion->setScale(4); 199 explosion->create(); 200 201 Vector3 ringdirection = Vector3(rnd(), rnd(), rnd()); 202 ringdirection.normalise(); 203 explosion = new ParticleSpawner("Orxonox/BigExplosion1part3", LODParticle::normal, 3.0, 0.5, 0, ringdirection); 204 explosion->setPosition(this->getPosition()); 205 explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true); 206 explosion->setScale(4); 207 explosion->create(); 208 explosion = new ParticleSpawner("Orxonox/BigExplosion1part3", LODParticle::high, 3.0, 0.5, 0, ringdirection); 209 explosion->setPosition(this->getPosition()); 210 explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true); 211 explosion->setScale(4); 212 explosion->create(); 213 214 delete this; 185 215 } 186 216 187 217 void SpaceShipAI::tick(float dt) 188 218 { 219 if (!this->isActive()) 220 return; 221 189 222 if (this->target_) 190 223 this->aimAtTarget(); … … 193 226 this->moveToTargetPosition(dt); 194 227 195 if (this->bShooting_ && this->isCloseAtTarget(2 000) && this->isLookingAtTarget(Ogre::Math::PI / 10.0f))228 if (this->bShooting_ && this->isCloseAtTarget(2500) && this->isLookingAtTarget(Ogre::Math::PI / 20.0)) 196 229 this->doFire(); 197 230 … … 201 234 void SpaceShipAI::moveToTargetPosition(float dt) 202 235 { 203 static Radian RadianZERO(0); 204 205 // float dotprod = (this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(this->targetPosition_ - this->getPosition()); 206 Quaternion rotation = (this->getOrientation() * Ogre::Vector3::UNIT_X).getRotationTo(this->targetPosition_ - this->getPosition()); 207 /* 208 std::cout << "scalprod: " << dotprod << std::endl; 209 std::cout << "dist: " << this->targetPosition_ - this->getPosition() << std::endl; 210 std::cout << "yaw: " << rotation.getYaw().valueRadians() << std::endl; 211 std::cout << "pitch: " << rotation.getPitch().valueRadians() << std::endl; 212 std::cout << "roll: " << rotation.getRoll().valueRadians() << std::endl; 213 */ 214 this->setMoveYaw(-rotation.getRoll().valueRadians()); 215 this->setMovePitch(rotation.getYaw().valueRadians()); 216 217 if ((this->targetPosition_ - this->getPosition()).length() > 100) 218 { 219 this->setMoveLongitudinal(1); 220 } 221 236 Vector2 coord = get2DViewdirection(this->getPosition(), this->getDir(), this->getOrth(), this->targetPosition_); 237 238 float distance = (this->targetPosition_ - this->getPosition()).length(); 239 if (this->target_ || distance > 50) 240 { 241 // Multiply with 0.8 to make them a bit slower 242 this->setMoveYaw(0.8 * sgn(coord.x) * coord.x*coord.x); 243 this->setMovePitch(0.8 * sgn(coord.y) * coord.y*coord.y); 244 } 245 246 if (this->target_ && distance < 1000 && this->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength()) 247 this->setMoveLongitudinal(-0.5); // They don't brake with full power to give the player a chance 248 else if (!this->target_ && distance <= this->getVelocity().length() / (2 * this->getTransAcc())) 249 this->setMoveLongitudinal(-1.0); 250 else 251 this->setMoveLongitudinal(0.8); 222 252 } 223 253 … … 241 271 Vector3 distanceNew = it->getPosition() - this->getPosition(); 242 272 if (!this->target_ || it->getPosition().squaredDistance(this->getPosition()) * (1.5f + acos((this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(distanceNew) / speed / distanceNew.length()) / (2 * Ogre::Math::PI)) 243 < this->targetPosition_.squaredDistance(this->getPosition()) * (1.5f + acos((this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / (2 * Ogre::Math::PI)) )273 < this->targetPosition_.squaredDistance(this->getPosition()) * (1.5f + acos((this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / (2 * Ogre::Math::PI)) + rnd(-250, 250)) 244 274 { 245 275 this->target_ = (*it); … … 248 278 } 249 279 } 250 }280 } 251 281 252 282 void SpaceShipAI::forgetTarget() … … 260 290 if (!this->target_) 261 291 return; 262 /* 263 Vector3 enemymovement = this->target_->getVelocity(); 264 Vector3 distance_normalised = this->target_->getPosition() - this->getPosition(); 265 distance_normalised.normalise(); 266 267 float scalarprod = enemymovement.dotProduct(distance_normalised); 268 float aimoffset = scalarprod*scalarprod + Projectile::getSpeed() * Projectile::getSpeed() - this->target_->getVelocity().squaredLength(); 269 if (aimoffset < 0) 270 { 271 this->bHasTargetPosition_ = false; 272 return; 273 } 274 aimoffset = -scalarprod + sqrt(aimoffset); 275 this->targetPosition_ = enemymovement + distance_normalised * aimoffset; 276 this->bHasTargetPosition_ = true; 277 278 std::cout << "targetpos: " << this->targetPosition_ << std::endl; 279 */ 280 this->targetPosition_ = this->target_->getPosition(); 281 this->bHasTargetPosition_ = true; 292 293 this->targetPosition_ = getPredictedPosition(this->getPosition(), Projectile::getSpeed(), this->target_->getPosition(), this->target_->getOrientation() * this->target_->getVelocity()); 294 this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO); 282 295 } 283 296 284 297 bool SpaceShipAI::isCloseAtTarget(float distance) 285 298 { 286 return (this->getPosition().squaredDistance(this->targetPosition_) < distance*distance); 299 if (!this->target_) 300 return (this->getPosition().squaredDistance(this->targetPosition_) < distance*distance); 301 else 302 return (this->getPosition().squaredDistance(this->target_->getPosition()) < distance*distance); 287 303 } 288 304 289 305 bool SpaceShipAI::isLookingAtTarget(float angle) 290 306 { 291 return (this->getOrientation() * Ogre::Vector3::UNIT_X).directionEquals(this->targetPosition_ - this->getPosition(), Radian(angle)); 307 return (getAngle(this->getPosition(), this->getDir(), this->targetPosition_) < angle); 308 } 309 310 void SpaceShipAI::shipDied(SpaceShipAI* ship) 311 { 312 if (ship == this->target_) 313 { 314 this->forgetTarget(); 315 this->searchNewTargetPosition(); 316 } 292 317 } 293 318 }
Note: See TracChangeset
for help on using the changeset viewer.