Changeset 10851 for code/branches/campaignHS15/src/orxonox
- Timestamp:
- Nov 24, 2015, 10:37:28 PM (9 years ago)
- Location:
- code/branches/campaignHS15/src/orxonox/controllers
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/campaignHS15/src/orxonox/controllers/CommonController.cc
r10850 r10851 26 26 * 27 27 */ 28 //bug or feature? Press 4 control keys from {Q,W,E,A,S,D,C} at the same time or 3 keys from {Q,E,A,D}, spaceship goes in free fly mode29 28 #include "controllers/CommonController.h" 30 29 #include "core/XMLPort.h" 31 30 32 #include "weaponsystem/WeaponMode.h" 33 #include "weaponsystem/WeaponPack.h" 34 #include "weaponsystem/Weapon.h" 35 #include "weaponsystem/WeaponSlot.h" 36 #include "weaponsystem/WeaponSlot.h" 37 #include "worldentities/pawns/SpaceShip.h" 38 39 #include "Scene.h" 40 31 //stuff for sameTeam function 41 32 #include "worldentities/pawns/TeamBaseMatchBase.h" 42 33 #include "gametypes/TeamDeathmatch.h" … … 56 47 const float ROTATEFACTOR = 1.0f/0.02f; 57 48 49 //Table of content: 50 //Constructor, Destructor & tick 51 //XML methods 52 //World interaction 53 //Helper methods 54 //Flying methods 55 //Fighting methods 56 //Actionpoint methods 57 58 59 //------------------------------------------------------------------------------ 60 //------------------------Constructor, Destructor & tick------------------------ 61 //------------------------------------------------------------------------------ 62 58 63 CommonController::CommonController( Context* context ): Controller( context ) 59 64 { 60 this->squaredaccuracy_ = 500; 65 this->squaredaccuracy_ = 10000; 66 this->bFirstTick_ = true; 67 this->tolerance_ = 65; 61 68 this->action_ = Action::NONE; 62 69 this->stopLookingAtTarget(); 63 this->attackRange_ = 800;70 this->attackRange_ = 2500; 64 71 RegisterObject( CommonController ); 65 72 } 66 67 68 73 CommonController::~CommonController() 69 74 { 70 //orxout(internal_error) << "I died, my Rank is " << rank_ << endl; 71 } 75 for (size_t i = 0; i < this->actionpoints_.size(); ++i) 76 { 77 if(this->actionpoints_[i]) 78 this->actionpoints_[i]->destroy(); 79 } 80 this->parsedActionpoints_.clear(); 81 this->actionpoints_.clear(); 82 } 83 void CommonController::tick(float dt) 84 { 85 if (this->bHasTargetPosition_) 86 { 87 this->moveToTargetPosition(dt); 88 } 89 else if (this->bLookAtTarget_) 90 { 91 this->lookAtTarget(dt); 92 } 93 if (bShooting_) 94 { 95 this->doFire(); 96 } 97 if (this->bFirstTick_) 98 { 99 std::reverse(parsedActionpoints_.begin(), parsedActionpoints_.end()); 100 std::reverse(actionpoints_.begin(), actionpoints_.end()); 101 } 102 if (this->bFirstTick_) 103 this->bFirstTick_ = false; 104 SUPER(CommonController, tick, dt); 105 } 106 107 //------------------------------------------------------------------------------ 108 //----------------------------------XML methods--------------------------------- 109 //------------------------------------------------------------------------------ 72 110 73 74 111 void CommonController::XMLPort( Element& xmlelement, XMLPort::Mode mode ) 75 112 { … … 77 114 XMLPortParam( CommonController, "formationMode", setFormationModeXML, getFormationModeXML, xmlelement, mode ); 78 115 XMLPortObject(CommonController, WorldEntity, "actionpoints", addActionpoint, getActionpoint, xmlelement, mode); 79 80 }81 82 void CommonController::tick(float dt)83 {84 if (this->bHasTargetPosition_)85 {86 this->moveToTargetPosition(dt);87 }88 else if (this->bLookAtTarget_)89 {90 this->lookAtTarget(dt);91 }92 if (bShooting_)93 {94 this->doFire();95 }96 SUPER(CommonController, tick, dt);97 }98 99 std::string CommonController::getProtectXML ()100 {101 if (!this->getProtect())102 return "noProtectWasSet";103 return CommonController::getName (orxonox_cast<Pawn*>(this->getProtect()));104 }105 std::string CommonController::getName(Pawn* entity)106 {107 std::string name = entity->getName();108 if (name == "")109 {110 const void * address = static_cast<const void*>(entity);111 std::stringstream ss;112 ss << address;113 name = ss.str();114 }115 return name;116 117 }118 void CommonController::setProtect (ControllableEntity* protect)119 {120 this->protect_ = protect;121 }122 ControllableEntity* CommonController::getProtect ()123 {124 return this->protect_;125 }126 127 std::string CommonController::getActionXML()128 {129 switch ( this->action_ )130 {131 case Action::FIGHT:132 {133 return "FIGHT";134 break;135 }136 case Action::FLY:137 {138 return "FLY";139 break;140 }141 case Action::PROTECT:142 {143 return "PROTECT";144 break;145 }146 case Action::NONE:147 {148 return "NONE";149 break;150 }151 case Action::FIGHTALL:152 {153 return "FIGHTALL";154 break;155 }156 case Action::ATTACK:157 {158 return "ATTACK";159 break;160 }161 default:162 return "NONE";163 break;164 }165 116 } 166 117 void CommonController::setFormationModeXML( std::string val ) … … 178 129 ThrowException( ParseError, std::string( "Attempting to set an unknown FormationMode: '" )+ val + "'." ); 179 130 this->setFormationMode( value ); 180 181 131 } 182 132 std::string CommonController::getFormationModeXML() … … 185 135 { 186 136 case FormationMode::WALL: 187 { 188 return "WALL"; 137 { return "WALL"; break; } 138 case FormationMode::FINGER4: 139 { return "FINGER4"; break; } 140 case FormationMode::DIAMOND: 141 { return "DIAMOND"; break; } 142 default: 143 return "DIAMOND"; break; 144 } 145 } 146 void CommonController::setFormationMode(FormationMode::Value val) 147 { 148 this->formationMode_ = val; 149 } 150 FormationMode::Value CommonController::getFormationMode() const 151 { 152 return this->formationMode_; 153 } 154 void CommonController::setRank(Rank::Value val) 155 { 156 this->rank_ = val; 157 } 158 Rank::Value CommonController::getRank() const 159 { 160 return this->rank_; 161 } 162 void CommonController::addActionpoint(WorldEntity* actionpoint) 163 { 164 std::string actionName; 165 Vector3 position; 166 std::string targetName; 167 Point p; 168 if (static_cast<Actionpoint*> (actionpoint)) 169 { 170 Actionpoint* ap = static_cast<Actionpoint*> (actionpoint); 171 actionName = ap->getActionXML(); 172 targetName = ap->getName(); 173 position = ap->getWorldPosition(); 174 175 Action::Value value; 176 177 if ( actionName == "FIGHT" ) 178 { value = Action::FIGHT; } 179 else if ( actionName == "FLY" ) 180 { value = Action::FLY; } 181 else if ( actionName == "PROTECT" ) 182 { value = Action::PROTECT; } 183 else if ( actionName == "NONE" ) 184 { value = Action::NONE; } 185 else if ( actionName == "FIGHTALL" ) 186 { value = Action::FIGHTALL; } 187 else if ( actionName == "ATTACK" ) 188 { value = Action::ATTACK; } 189 else 190 ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ actionName + "'." ); 191 p.action = value; p.name = targetName; p.position = position; 192 parsedActionpoints_.push_back(p); 193 } 194 else 195 { 196 p.action = Action::FLY; p.name = ""; p.position = actionpoint->getWorldPosition(); 197 } 198 parsedActionpoints_.push_back(p); 199 this->actionpoints_.push_back(actionpoint); 200 } 201 WorldEntity* CommonController::getActionpoint(unsigned int index) const 202 { 203 if (index < this->actionpoints_.size()) 204 return this->actionpoints_[index]; 205 else 206 return 0; 207 } 208 209 //------------------------------------------------------------------------------ 210 //-------------------------------World interaction------------------------------ 211 //------------------------------------------------------------------------------ 212 213 //"Virtual" methods 214 bool CommonController::setWingman ( CommonController* wingman ) 215 { return false; } 216 bool CommonController::hasWingman() 217 { return true; } 218 bool CommonController::hasTarget() 219 { 220 if ( this->target_ ) 221 return true; 222 return false; 223 } 224 ControllableEntity* CommonController::getTarget() 225 { 226 return this->target_; 227 } 228 Action::Value CommonController::getAction () 229 { 230 return this->action_; 231 } 232 std::string CommonController::getActionName() 233 { 234 switch ( this->action_ ) 235 { 236 case Action::FIGHT: 237 { return "FIGHT"; break; } 238 case Action::FLY: 239 { return "FLY"; break; } 240 case Action::PROTECT: 241 { return "PROTECT"; break; } 242 case Action::NONE: 243 { return "NONE"; break; } 244 case Action::FIGHTALL: 245 { return "FIGHTALL"; break; } 246 case Action::ATTACK: 247 { return "ATTACK"; break; } 248 default: 249 return "NONE"; 189 250 break; 190 } 191 case FormationMode::FINGER4: 192 { 193 return "FINGER4"; 194 break; 195 } 196 case FormationMode::DIAMOND: 197 { 198 return "DIAMOND"; 199 break; 200 } 201 default: 202 return "DIAMOND"; 203 break; 204 205 } 206 } 207 Action::Value CommonController::getAction () 208 { 209 return this->action_; 251 } 210 252 } 211 253 void CommonController::setAction (Action::Value action) … … 213 255 this->action_ = action; 214 256 } 215 216 257 void CommonController::setAction (Action::Value action, ControllableEntity* target) 217 258 { … … 235 276 this->setTargetPosition (target); 236 277 } 237 238 278 } 239 279 void CommonController::setAction (Action::Value action, const Vector3& target, const Quaternion& orient ) … … 244 284 this->setTargetPosition (target); 245 285 this->setTargetOrientation (orient); 246 } 247 248 } 249 void CommonController::addActionpoint(WorldEntity* actionpoint) 250 { 251 std::string actionName; 252 Vector3 position; 253 std::string targetName; 254 255 if (static_cast<Actionpoint*> (actionpoint)) 256 { 257 Actionpoint* ap = static_cast<Actionpoint*> (actionpoint); 258 259 actionName = ap->getActionXML(); 260 targetName = ap->getName(); 261 position = ap->getWorldPosition(); 262 263 Action::Value value; 264 265 if ( actionName == "FIGHT" ) 286 } 287 } 288 289 //------------------------------------------------------------------------------ 290 //--------------------------------Helper methods-------------------------------- 291 //------------------------------------------------------------------------------ 292 293 float CommonController::randomInRange( float a, float b ) 294 { 295 float random = rnd( 1.0f ); 296 float diff = b - a; 297 float r = random * diff; 298 return a + r; 299 } 300 float CommonController::distance (ControllableEntity* entity1, ControllableEntity* entity2) 301 { 302 if (!entity1 || !entity2) 303 return std::numeric_limits<float>::infinity(); 304 return ( entity1->getPosition() - entity2->getPosition() ).length(); 305 } 306 bool CommonController::sameTeam (ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype) 307 { 308 /*if (!entity1 || !entity2) 309 return false; 310 return entity1->getTeam() == entity2->getTeam();*/ 311 if (entity1 == entity2) 312 return true; 313 314 int team1 = entity1->getTeam(); 315 int team2 = entity2->getTeam(); 316 317 Controller* controller = 0; 318 if (entity1->getController()) 319 controller = entity1->getController(); 320 else 321 controller = entity1->getXMLController(); 322 if (controller) 323 { 324 CommonController* ac = orxonox_cast<CommonController*>(controller); 325 if (ac) 326 team1 = ac->getTeam(); 327 } 328 329 if (entity2->getController()) 330 controller = entity2->getController(); 331 else 332 controller = entity2->getXMLController(); 333 if (controller) 334 { 335 CommonController* ac = orxonox_cast<CommonController*>(controller); 336 if (ac) 337 team2 = ac->getTeam(); 338 } 339 340 TeamGametype* tdm = orxonox_cast<TeamGametype*>(gametype); 341 if (tdm) 342 { 343 if (entity1->getPlayer()) 344 team1 = tdm->getTeam(entity1->getPlayer()); 345 346 if (entity2->getPlayer()) 347 team2 = tdm->getTeam(entity2->getPlayer()); 348 } 349 350 TeamBaseMatchBase* base = 0; 351 base = orxonox_cast<TeamBaseMatchBase*>(entity1); 352 if (base) 353 { 354 switch (base->getState()) 266 355 { 267 value = Action::FIGHT; 268 356 case BaseState::ControlTeam1: 357 team1 = 0; 358 break; 359 case BaseState::ControlTeam2: 360 team1 = 1; 361 break; 362 case BaseState::Uncontrolled: 363 default: 364 team1 = -1; 269 365 } 270 else if ( actionName == "FLY" ) 366 } 367 base = orxonox_cast<TeamBaseMatchBase*>(entity2); 368 if (base) 369 { 370 switch (base->getState()) 271 371 { 272 value = Action::FLY; 273 372 case BaseState::ControlTeam1: 373 team2 = 0; 374 break; 375 case BaseState::ControlTeam2: 376 team2 = 1; 377 break; 378 case BaseState::Uncontrolled: 379 default: 380 team2 = -1; 274 381 } 275 else if ( actionName == "PROTECT" ) 382 } 383 384 DroneController* droneController = 0; 385 droneController = orxonox_cast<DroneController*>(entity1->getController()); 386 if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2) 387 return true; 388 droneController = orxonox_cast<DroneController*>(entity2->getController()); 389 if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1) 390 return true; 391 DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController()); 392 DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController()); 393 if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner()) 394 return true; 395 396 Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype); 397 if (dynamic) 398 { 399 if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;} 400 401 if (entity1->getPlayer()) 402 team1 = dynamic->getParty(entity1->getPlayer()); 403 404 if (entity2->getPlayer()) 405 team2 = dynamic->getParty(entity2->getPlayer()); 406 407 if (team1 ==-1 ||team2 ==-1 ) {return false;} 408 else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;} 409 else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;} 410 else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;} 411 else return true; 412 } 413 414 return (team1 == team2 && team1 != -1); 415 } 416 bool CommonController::isLooking( ControllableEntity* entityThatLooks, ControllableEntity* entityBeingLookedAt, float angle ) 417 { 418 if ( !entityThatLooks || !entityBeingLookedAt ) 419 return false; 420 return ( getAngle( entityThatLooks ->getPosition() , 421 entityThatLooks->getOrientation() * WorldEntity::FRONT, 422 entityBeingLookedAt->getWorldPosition() ) < angle ); 423 } 424 std::string CommonController::getName(Pawn* entity) 425 { 426 std::string name = entity->getName(); 427 if (name == "") 428 { 429 const void * address = static_cast<const void*>(entity); 430 std::stringstream ss; 431 ss << address; 432 name = ss.str(); 433 } 434 return name; 435 } 436 float CommonController::squaredDistanceToTarget() const 437 { 438 if ( !this->getControllableEntity() ) 439 return 0; 440 if ( !this->target_ || !this->getControllableEntity() ) 441 return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->targetPosition_ ) ); 442 else 443 return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->positionOfTarget_ ) ); 444 } 445 bool CommonController::isLookingAtTarget( float angle ) 446 { 447 if ( !this->getControllableEntity() || !this->target_ ) 448 return false; 449 return this->isLooking(this->getControllableEntity(), this->getTarget(), angle); 450 } 451 452 453 //------------------------------------------------------------------------------ 454 //--------------------------------Flying methods-------------------------------- 455 //------------------------------------------------------------------------------ 456 457 void CommonController::stopMoving() 458 { 459 this->bHasTargetPosition_ = false; 460 } 461 void CommonController::stopLookingAtTarget() 462 { 463 this->bLookAtTarget_ = false; 464 } 465 void CommonController::startLookingAtTarget() 466 { 467 this->bLookAtTarget_ = true; 468 } 469 void CommonController::moveToPosition( const Vector3& target, float dt ) 470 { 471 ControllableEntity* entity = this->getControllableEntity(); 472 Vector2 coord = get2DViewCoordinates 473 ( entity->getPosition() , 474 entity->getOrientation() * WorldEntity::FRONT, 475 entity->getOrientation() * WorldEntity::UP, 476 target ); 477 478 float distance = ( target - this->getControllableEntity() ->getPosition() ).length(); 479 float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f ); 480 float rotateY = clamp( coord.y * 10, -1.0f, 1.0f ); 481 482 if ( distance > this->tolerance_ ) 483 { 484 this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt ); 485 this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt ); 486 487 if ( distance < 300 ) 276 488 { 277 value = Action::PROTECT; 278 489 if ( bHasTargetOrientation_ ) 490 { 491 copyTargetOrientation( dt ); 492 } 279 493 } 280 else if ( actionName == "NONE" ) 494 if (distance > 200 || (rotateX > -0.1 && rotateX < 0.1 && rotateY > -0.1 && rotateY < 0.1)) 495 this->getControllableEntity() ->moveFrontBack( SPEED * dt ); 496 } 497 else 498 { 499 bHasTargetPosition_ = false; 500 bHasTargetOrientation_ = false; 501 } 502 } 503 void CommonController::moveToTargetPosition(float dt) 504 { 505 this->moveToPosition (this->targetPosition_, dt); 506 } 507 void CommonController::copyOrientation( const Quaternion& orient, float dt ) 508 { 509 //roll angle difference in radian 510 float diff=orient.getRoll(false).valueRadians() - 511 ( this->getControllableEntity() ->getOrientation() .getRoll( false ).valueRadians() ); 512 while( diff>math::twoPi )diff-=math::twoPi; 513 while( diff<-math::twoPi )diff+=math::twoPi; 514 this->getControllableEntity() ->rotateRoll( diff*ROTATEFACTOR * dt ); 515 } 516 void CommonController::copyTargetOrientation( float dt ) 517 { 518 if ( bHasTargetOrientation_ ) 519 { 520 copyOrientation( targetOrientation_, dt ); 521 } 522 } 523 void CommonController::lookAtTarget(float dt) 524 { 525 ControllableEntity* entity = this->getControllableEntity(); 526 if ( !entity ) 527 return; 528 Vector2 coord = get2DViewCoordinates 529 ( entity->getPosition() , 530 entity->getOrientation() * WorldEntity::FRONT, 531 entity->getOrientation() * WorldEntity::UP, 532 positionOfTarget_ ); 533 534 //rotates should be in range [-1,+1], clamp cuts off all that is not 535 float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f ); 536 float rotateY = clamp( coord.y * 10, -1.0f, 1.0f ); 537 538 //Yaw and Pitch are enough to start facing the target 539 this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt ); 540 this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt ); 541 } 542 void CommonController::setTargetPosition( const Vector3& target ) 543 { 544 this->targetPosition_ = target; 545 this->bHasTargetPosition_ = true; 546 } 547 548 void CommonController::setTargetOrientation( const Quaternion& orient ) 549 { 550 this->targetOrientation_=orient; 551 this->bHasTargetOrientation_=true; 552 } 553 554 void CommonController::setTargetOrientation( ControllableEntity* target ) 555 { 556 if ( target ) 557 setTargetOrientation( target->getOrientation() ); 558 } 559 560 //------------------------------------------------------------------------------ 561 //-------------------------------Fighting methods------------------------------- 562 //------------------------------------------------------------------------------ 563 564 void CommonController::setTarget( ControllableEntity* target ) 565 { 566 this->target_ = target; 567 if ( this->target_ ) 568 { 569 this->setPositionOfTarget( target_->getWorldPosition() ); 570 } 571 } 572 void CommonController::setPositionOfTarget( const Vector3& target ) 573 { 574 this->positionOfTarget_ = target; 575 this->bHasPositionOfTarget_ = true; 576 } 577 void CommonController::setOrientationOfTarget( const Quaternion& orient ) 578 { 579 this->orientationOfTarget_=orient; 580 this->bHasOrientationOfTarget_=true; 581 } 582 void CommonController::setProtect (ControllableEntity* protect) 583 { 584 this->protect_ = protect; 585 } 586 ControllableEntity* CommonController::getProtect () 587 { 588 return this->protect_; 589 } 590 void CommonController::maneuver() 591 { 592 maneuverCounter_++; 593 if (maneuverCounter_ > 5) 594 maneuverCounter_ = 0; 595 596 if ( !this->target_ || !this->getControllableEntity()) 597 return; 598 599 Vector3 thisPosition = this->getControllableEntity()->getWorldPosition(); 600 this->setPositionOfTarget( getPredictedPosition( 601 thisPosition, 602 hardcoded_projectile_speed, 603 this->target_->getWorldPosition() , 604 this->target_->getVelocity() 605 ) ); 606 this->setOrientationOfTarget( this->target_->getOrientation() ); 607 608 Vector3 diffVector = this->positionOfTarget_ - thisPosition; 609 float diffLength = diffVector.length(); 610 Vector3 diffUnit = diffVector/diffLength; 611 612 bool bTargetIsLookingAtThis = this->isLooking ( this->target_, getControllableEntity(), math::pi/10.0f ); 613 614 //too far? well, come closer then 615 if ( diffLength > this->attackRange_ ) 616 { 617 this->setTargetPosition( this->positionOfTarget_ ); 618 } 619 //too close? How do u expect to dodge anything? Just attack! 620 else if ( diffLength < 500 ) 621 { 622 //at this point, just look and shoot 623 if ( diffLength < 250 ) 281 624 { 282 value = Action::NONE; 283 284 } 285 else if ( actionName == "FIGHTALL" ) 286 { 287 value = Action::FIGHTALL; 288 289 } 290 else if ( actionName == "ATTACK" ) 291 { 292 value = Action::ATTACK; 293 294 625 this->stopMoving(); 626 this->startLookingAtTarget(); 295 627 } 296 628 else 297 ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ actionName + "'." ); 298 //this->setAction( value ); 299 Point p = { value, targetName, position }; 300 parsedActionpoints_.push_back(p); 301 orxout(internal_error) << "Pushed " << p.action << endl; 302 } 303 else 304 { 305 Point p = { Action::FLY, "", actionpoint->getWorldPosition() }; 306 parsedActionpoints_.push_back(p); 307 } 308 this->actionpoints_.push_back(actionpoint); 309 310 311 } 312 313 WorldEntity* CommonController::getActionpoint(unsigned int index) const 314 { 315 if (index < this->actionpoints_.size()) 316 return this->actionpoints_[index]; 317 else 318 return 0; 629 { 630 this->setTargetPosition( this->positionOfTarget_ ); 631 } 632 } 633 //Good distance? Check if target looks at us. It doesn't? Go hunt! 634 else if ( !bTargetIsLookingAtThis ) 635 { 636 this->setTargetPosition( this->positionOfTarget_ ); 637 } 638 //That's unfortunate, he is looking and probably shooting... try to dodge what we can... 639 else 640 { 641 if (maneuverCounter_ == 0) 642 { 643 this->setTargetPosition( this->positionOfTarget_ ); 644 return; 645 } 646 dodge( thisPosition, diffUnit ); 647 } 648 } 649 650 void CommonController::dodge(Vector3& thisPosition, Vector3& diffUnit) 651 { 652 float factorX = 0, factorY = 0, factorZ = 0; 653 float rand = randomInRange (0, 1); 654 655 if (rand <= 0.5) 656 { factorX = 1; } 657 else 658 { factorX = -1; } 659 rand = randomInRange (0, 1); 660 if (rand <= 0.5) 661 { factorY = 1; } 662 else 663 { factorY = -1; } 664 rand = randomInRange (0, 1); 665 if (rand <= 0.5) 666 { factorZ = 1; } 667 else 668 { factorZ = -1; } 669 670 Vector3 target = ( diffUnit )* 8000.0f; 671 Vector3* randVector = new Vector3( 672 factorX * randomInRange( 10000, 40000 ), 673 factorY * randomInRange( 10000, 40000 ), 674 factorZ * randomInRange( 10000, 40000 ) 675 ); 676 Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit; 677 *randVector -= projection; 678 target += *randVector; 679 this->setTargetPosition( thisPosition + target ); 680 } 681 bool CommonController::canFire() 682 { 683 //no target? why fire? 684 if ( !this->target_ ) 685 return false; 686 687 Vector3 newPositionOfTarget = getPredictedPosition( this->getControllableEntity() ->getWorldPosition() , 688 hardcoded_projectile_speed, this->target_->getWorldPosition() , this->target_->getVelocity() ); 689 if ( newPositionOfTarget != Vector3::ZERO ) 690 { 691 this->setPositionOfTarget( newPositionOfTarget ); 692 } 693 694 float squaredDistance = squaredDistanceToTarget(); 695 696 if ( squaredDistance < this->attackRange_*this->attackRange_ && this->isLookingAtTarget( math::pi / 20.0f)) 697 { 698 return true; 699 } 700 else 701 { 702 return false; 703 } 704 } 705 void CommonController::doFire() 706 { 707 if ( !this->target_ || !this->getControllableEntity() ) 708 { 709 return; 710 } 711 712 Pawn* pawn = orxonox_cast<Pawn*>( this->getControllableEntity() ); 713 714 if ( pawn ) 715 pawn->setAimPosition( this->positionOfTarget_ ); 716 this->getControllableEntity() ->fire( 0 ); 319 717 } 320 718 void CommonController::setClosestTarget() … … 348 746 return 0; 349 747 } 748 bool CommonController::startAttackingEnemiesThatAreClose() 749 { 750 if (this->action_ != Action::FIGHT && this->action_ != Action::FIGHTALL) 751 { 752 if ( (this->target_ && this->distance (this->getControllableEntity(), this->target_) > this->attackRange_) 753 || !this->target_ ) 754 { 755 Pawn* newTarget = this->closestTarget(); 756 if ( newTarget && 757 this->distance (this->getControllableEntity(), static_cast<ControllableEntity*>(newTarget)) 758 <= this->attackRange_ ) 759 { 760 Point p = { Action::FIGHT, this->getName(newTarget), Vector3::ZERO }; 761 this->parsedActionpoints_.push_back(p); 762 this->executeActionpoint(); 763 return true; 764 } 765 } 766 } 767 return false; 768 } 769 770 //------------------------------------------------------------------------------ 771 //------------------------------Actionpoint methods----------------------------- 772 //------------------------------------------------------------------------------ 773 350 774 //POST: this starts doing what was asked by the last element of parsedActionpoints_, 351 775 //if last element was failed to be parsed, next element will be executed. … … 406 830 if (CommonController::getName(*itP) == targetName) 407 831 { 408 orxout(internal_error) << "Attacking" << endl;409 832 this->setTarget (static_cast<ControllableEntity*>(*itP)); 410 833 } 411 834 } 412 if (!this-> getTarget())835 if (!this->hasTarget()) 413 836 { 414 837 this->nextActionpoint(); … … 420 843 break; 421 844 } 422 423 424 845 } 425 846 else … … 429 850 this->action_ = Action::NONE; 430 851 } 431 orxout(internal_error) << "Executing action " << this->getActionXML() << endl;432 852 } 433 853 void CommonController::nextActionpoint() … … 439 859 this->setAction(Action::NONE); 440 860 } 441 442 void CommonController::maneuver()443 {444 maneuverCounter_++;445 446 if (maneuverCounter_ > 5)447 maneuverCounter_ = 0;448 if ( this->target_ && this->getControllableEntity())449 {450 Vector3 thisPosition = this->getControllableEntity()->getWorldPosition();451 //Quaternion thisOrientation = this->getControllableEntity()->getOrientation();452 453 this->setPositionOfTarget( getPredictedPosition(454 thisPosition,455 hardcoded_projectile_speed,456 this->target_->getWorldPosition() ,457 this->target_->getVelocity()458 ) );459 this->setOrientationOfTarget( this->target_->getOrientation() );460 461 462 Vector3 diffVector = this->positionOfTarget_ - thisPosition;463 float diffLength = diffVector.length();464 Vector3 diffUnit = diffVector/diffLength;465 466 467 468 //bool bThisIsLookingAtTarget = this->isLooking ( getControllableEntity(), this->target_, math::pi/4 );469 bool bTargetIsLookingAtThis = this->isLooking ( this->target_, getControllableEntity(), math::pi/10.0f );470 471 472 473 //too far? well, come closer then474 if ( diffLength > 3000 )475 {476 if (diffLength < 6000)477 {478 479 }480 else481 {482 }483 this->setTargetPosition( this->positionOfTarget_ );484 }485 //too close? How do u expect to dodge anything? Just attack!486 else if ( diffLength < 500 )487 {488 //at this point, just look and shoot489 if ( diffLength < 250 )490 {491 this->stopMoving();492 this->startLookingAtTarget();493 }494 else495 {496 this->setTargetPosition( this->positionOfTarget_ );497 }498 }499 //Good distance? Check if target looks at us. It doesn't? Go hunt!500 else if ( !bTargetIsLookingAtThis )501 {502 this->setTargetPosition( this->positionOfTarget_ );503 /* if (maneuverCounter_ == 0)504 {505 this->setTargetPosition( this->positionOfTarget_ );506 return;507 }508 else509 {510 dodge( thisPosition, diffUnit );511 }*/512 }513 //That's unfortunate, he is looking and probably shooting... try to dodge what we can...514 else515 {516 517 if (maneuverCounter_ == 0)518 {519 this->setTargetPosition( this->positionOfTarget_ );520 return;521 }522 dodge( thisPosition, diffUnit );523 524 }525 }526 527 //orxout ( internal_error ) << "ManeuverType = " << this->maneuverType_ << endl;528 }529 ControllableEntity* CommonController::getTarget()530 {531 return this->target_;532 }533 void CommonController::dodge(Vector3& thisPosition, Vector3& diffUnit)534 {535 float factorX = 0, factorY = 0, factorZ = 0;536 float rand = randomInRange (0, 1);537 if (rand <= 0.5)538 {539 factorX = 1;540 }541 else542 {543 factorX = -1;544 }545 rand = randomInRange (0, 1);546 if (rand <= 0.5)547 {548 factorY = 1;549 }550 else551 {552 factorY = -1;553 }554 rand = randomInRange (0, 1);555 if (rand <= 0.5)556 {557 factorZ = 1;558 }559 else560 {561 factorZ = -1;562 }563 Vector3 target = ( diffUnit )* 8000.0f;564 Vector3* randVector = new Vector3(565 factorX * randomInRange( 10000, 40000 ),566 factorY * randomInRange( 10000, 40000 ),567 factorZ * randomInRange( 10000, 40000 )568 );569 Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit;570 *randVector -= projection;571 target += *randVector;572 this->setTargetPosition( thisPosition + target );573 }574 void CommonController::stopMoving()575 {576 this->bHasTargetPosition_ = false;577 }578 void CommonController::startLookingAtTarget()579 {580 this->bLookAtTarget_ = true;581 }582 void CommonController::stopLookingAtTarget()583 {584 this->bLookAtTarget_ = false;585 }586 void CommonController::lookAtTarget(float dt)587 {588 589 590 ControllableEntity* entity = this->getControllableEntity();591 if ( !entity )592 return;593 Vector2 coord = get2DViewCoordinates594 ( entity->getPosition() ,595 entity->getOrientation() * WorldEntity::FRONT,596 entity->getOrientation() * WorldEntity::UP,597 positionOfTarget_ );598 599 //rotates should be in range [-1,+1], clamp cuts off all that is not600 float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );601 float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );602 603 604 605 //Yaw and Pitch are enough to start facing the target606 this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );607 this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );608 609 610 }611 612 bool CommonController::setWingman ( CommonController* wingman )613 {614 return false;615 }616 617 bool CommonController::hasWingman()618 {619 return true;620 }621 void CommonController::setTarget( ControllableEntity* target )622 {623 this->target_ = target;624 //orxout ( internal_error ) << " TARGET SET " << endl;625 626 if ( this->target_ )627 {628 this->setPositionOfTarget( target_->getWorldPosition() );629 630 }631 }632 bool CommonController::hasTarget()633 {634 if ( this->target_ )635 return true;636 return false;637 }638 void CommonController::setPositionOfTarget( const Vector3& target )639 {640 this->positionOfTarget_ = target;641 this->bHasPositionOfTarget_ = true;642 }643 void CommonController::setOrientationOfTarget( const Quaternion& orient )644 {645 this->orientationOfTarget_=orient;646 this->bHasOrientationOfTarget_=true;647 }648 649 void CommonController::setTargetPosition( const Vector3& target )650 {651 this->targetPosition_ = target;652 this->bHasTargetPosition_ = true;653 }654 655 void CommonController::setTargetOrientation( const Quaternion& orient )656 {657 this->targetOrientation_=orient;658 this->bHasTargetOrientation_=true;659 }660 661 void CommonController::setTargetOrientation( ControllableEntity* target )662 {663 if ( target )664 setTargetOrientation( target->getOrientation() );665 }666 667 668 669 //copy the Roll orientation of given Quaternion.670 void CommonController::copyOrientation( const Quaternion& orient, float dt )671 {672 //roll angle difference in radian673 float diff=orient.getRoll( false ).valueRadians() -( this->getControllableEntity() ->getOrientation() .getRoll( false ).valueRadians() );674 while( diff>math::twoPi )diff-=math::twoPi;675 while( diff<-math::twoPi )diff+=math::twoPi;676 this->getControllableEntity() ->rotateRoll( diff*ROTATEFACTOR * dt );677 }678 void CommonController::copyTargetOrientation( float dt )679 {680 if ( bHasTargetOrientation_ )681 {682 copyOrientation( targetOrientation_, dt );683 }684 }685 686 687 688 689 void CommonController::moveToTargetPosition( float dt )690 {691 this->moveToPosition( this->targetPosition_, dt );692 }693 void CommonController::moveToPosition( const Vector3& target, float dt )694 {695 696 697 //100 is ( so far )the smallest tolerance ( empirically found )that can be reached,698 //with smaller distance spaceships can't reach position and go circles around it instead699 int tolerance = 65;700 701 ControllableEntity* entity = this->getControllableEntity();702 Vector2 coord = get2DViewCoordinates703 ( entity->getPosition() ,704 entity->getOrientation() * WorldEntity::FRONT,705 entity->getOrientation() * WorldEntity::UP,706 target );707 708 float distance = ( target - this->getControllableEntity() ->getPosition() ).length();709 710 //rotates should be in range [-1,+1], clamp cuts off all that is not711 float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );712 float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );713 714 715 if ( distance > tolerance )716 {717 //Yaw and Pitch are enough to start facing the target718 this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );719 this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );720 721 //300 works, maybe less is better722 if ( distance < 400 )723 {724 //Change roll when close. When Spaceship faces target, roll doesn't affect it's trajectory725 //It's important that roll is not changed in the process of changing yaw and pitch726 //Wingmen won't face same direction as Leaders, but when Leaders start moving727 //Yaw and Pitch will adapt.728 if ( bHasTargetOrientation_ )729 {730 copyTargetOrientation( dt );731 }732 }733 734 this->getControllableEntity() ->moveFrontBack( SPEED * dt );735 }736 else737 {738 bHasTargetPosition_ = false;739 bHasTargetOrientation_ = false;740 }741 }742 float CommonController::randomInRange( float a, float b )743 {744 float random = rnd( 1.0f );745 float diff = b - a;746 float r = random * diff;747 return a + r;748 }749 750 751 //to be called in action752 //PRE: relativeTargetPosition is desired position relative to the spaceship,753 //angleRoll is the angle in degrees of Roll that should be applied by the end of the movement754 //POST: target orientation and position are set, so that it can be used by MoveAndRoll()755 void CommonController::moveToPoint( const Vector3& relativeTargetPosition, float angleRoll )756 {757 ControllableEntity* entity = this->getControllableEntity();758 if ( !entity )759 return;760 Quaternion orient = entity->getWorldOrientation();761 Quaternion rotation = Quaternion( Degree( angleRoll ), Vector3::UNIT_Z );762 763 Vector3 target = orient * relativeTargetPosition + entity->getWorldPosition();764 setTargetPosition( target );765 orient = orient * rotation;766 this->setTargetOrientation( orient );767 768 }769 //to be called in tick770 //PRE: MoveToPoint was called771 //POST: spaceship changes its yaw and pitch to point towards targetPosition_,772 //moves towards targetPosition_ by amount depending on dt and its speed,773 //rolls by amount depending on the difference between angleRoll_ and angleRolled_, dt, and774 //angular speed775 //if position reached with a certain tolerance, and angleRolled_ = angleRoll_, returns false,776 //otherwise returns true777 //dt is normally around 0.02f, which makes it 1/0.02 = 50 frames/sec778 bool CommonController::moveAndRoll( float dt )779 {780 float factor = 1;781 if ( !this->getControllableEntity() )782 return false;783 if ( this->rank_ == Rank::DIVISIONLEADER )784 factor = 0.8;785 if ( this->rank_ == Rank::SECTIONLEADER )786 factor = 0.9;787 int tolerance = 60;788 789 ControllableEntity* entity = this->getControllableEntity();790 if ( !entity )791 return true;792 Vector2 coord = get2DViewCoordinates793 ( entity->getPosition() ,794 entity->getOrientation() * WorldEntity::FRONT,795 entity->getOrientation() * WorldEntity::UP,796 targetPosition_ );797 798 float distance = ( targetPosition_ - this->getControllableEntity() ->getPosition() ).length();799 800 //rotates should be in range [-1,+1], clamp cuts off all that is not801 float rotateX = clamp( coord.x * 10, -1.0f, 1.0f );802 float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );803 804 805 if ( distance > tolerance )806 {807 //Yaw and Pitch are enough to start facing the target808 this->getControllableEntity() ->rotateYaw( -2.0f * ROTATEFACTOR * rotateX * dt );809 this->getControllableEntity() ->rotatePitch( 2.0f * ROTATEFACTOR * rotateY * dt );810 811 //Roll812 if ( bHasTargetOrientation_ )813 {814 copyTargetOrientation( dt );815 }816 817 //Move818 this->getControllableEntity() ->moveFrontBack( 1.2f * SPEED * factor * dt );819 //if still moving, return false820 return false;821 }822 else823 {824 825 //if finished, return true;826 return true;827 }828 }829 830 float CommonController::squaredDistanceToTarget() const831 {832 if ( !this->getControllableEntity() )833 return 0;834 if ( !this->target_ || !this->getControllableEntity() )835 return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->targetPosition_ ) );836 else837 return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->positionOfTarget_ ) );838 }839 840 bool CommonController::isLookingAtTarget( float angle )const841 {842 if ( !this->getControllableEntity() || !this->target_ )843 return false;844 845 return ( getAngle( this->getControllableEntity() ->getPosition() ,846 this->getControllableEntity() ->getOrientation() * WorldEntity::FRONT, this->positionOfTarget_ ) < angle );847 }848 bool CommonController::isLooking( ControllableEntity* entityThatLooks, ControllableEntity* entityBeingLookedAt, float angle )849 {850 if ( !entityThatLooks || !entityBeingLookedAt )851 return false;852 return ( getAngle( entityThatLooks ->getPosition() ,853 entityThatLooks->getOrientation() * WorldEntity::FRONT,854 entityBeingLookedAt->getWorldPosition() ) < angle );855 }856 857 bool CommonController::canFire()858 {859 860 //no target? why fire?861 if ( !this->target_ )862 return false;863 864 Vector3 newPositionOfTarget = getPredictedPosition( this->getControllableEntity() ->getWorldPosition() ,865 hardcoded_projectile_speed, this->target_->getWorldPosition() , this->target_->getVelocity() );866 if ( newPositionOfTarget != Vector3::ZERO )867 {868 this->setPositionOfTarget( newPositionOfTarget );869 }870 871 float squaredDistance = squaredDistanceToTarget();872 873 if ( squaredDistance < 9000000.0f && this->isLookingAtTarget( math::pi / 20.0f)) {874 return true;875 }876 else877 {878 return false;879 }880 881 }882 float CommonController::distance (ControllableEntity* entity1, ControllableEntity* entity2)883 {884 if (!entity1 || !entity2)885 return std::numeric_limits<float>::infinity();886 return ( entity1->getPosition() - entity2->getPosition() ).length();887 }888 bool CommonController::sameTeam (ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)889 {890 /*if (!entity1 || !entity2)891 return false;892 return entity1->getTeam() == entity2->getTeam();*/893 if (entity1 == entity2)894 return true;895 896 int team1 = entity1->getTeam();897 int team2 = entity2->getTeam();898 899 Controller* controller = 0;900 if (entity1->getController())901 controller = entity1->getController();902 else903 controller = entity1->getXMLController();904 if (controller)905 {906 CommonController* ac = orxonox_cast<CommonController*>(controller);907 if (ac)908 team1 = ac->getTeam();909 }910 911 if (entity2->getController())912 controller = entity2->getController();913 else914 controller = entity2->getXMLController();915 if (controller)916 {917 CommonController* ac = orxonox_cast<CommonController*>(controller);918 if (ac)919 team2 = ac->getTeam();920 }921 922 TeamGametype* tdm = orxonox_cast<TeamGametype*>(gametype);923 if (tdm)924 {925 if (entity1->getPlayer())926 team1 = tdm->getTeam(entity1->getPlayer());927 928 if (entity2->getPlayer())929 team2 = tdm->getTeam(entity2->getPlayer());930 }931 932 TeamBaseMatchBase* base = 0;933 base = orxonox_cast<TeamBaseMatchBase*>(entity1);934 if (base)935 {936 switch (base->getState())937 {938 case BaseState::ControlTeam1:939 team1 = 0;940 break;941 case BaseState::ControlTeam2:942 team1 = 1;943 break;944 case BaseState::Uncontrolled:945 default:946 team1 = -1;947 }948 }949 base = orxonox_cast<TeamBaseMatchBase*>(entity2);950 if (base)951 {952 switch (base->getState())953 {954 case BaseState::ControlTeam1:955 team2 = 0;956 break;957 case BaseState::ControlTeam2:958 team2 = 1;959 break;960 case BaseState::Uncontrolled:961 default:962 team2 = -1;963 }964 }965 966 DroneController* droneController = 0;967 droneController = orxonox_cast<DroneController*>(entity1->getController());968 if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)969 return true;970 droneController = orxonox_cast<DroneController*>(entity2->getController());971 if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)972 return true;973 DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController());974 DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController());975 if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner())976 return true;977 978 Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype);979 if (dynamic)980 {981 if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;}982 983 if (entity1->getPlayer())984 team1 = dynamic->getParty(entity1->getPlayer());985 986 if (entity2->getPlayer())987 team2 = dynamic->getParty(entity2->getPlayer());988 989 if (team1 ==-1 ||team2 ==-1 ) {return false;}990 else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;}991 else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;}992 else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;}993 else return true;994 }995 996 return (team1 == team2 && team1 != -1);997 }998 void CommonController::doFire()999 {1000 if ( !this->target_ || !this->getControllableEntity() )1001 {1002 return;1003 }1004 1005 Pawn* pawn = orxonox_cast<Pawn*>( this->getControllableEntity() );1006 1007 if ( pawn )1008 //pawn->setAimPosition( this->getControllableEntity() ->getWorldPosition() + 4000*( this->getControllableEntity() ->getOrientation() * WorldEntity::FRONT ));1009 pawn->setAimPosition( this->positionOfTarget_ );1010 1011 this->getControllableEntity() ->fire( 0 );1012 }1013 1014 1015 861 } -
code/branches/campaignHS15/src/orxonox/controllers/CommonController.h
r10849 r10851 39 39 #include "tools/interfaces/Tickable.h" 40 40 #include <limits> 41 #include <algorithm> 41 42 #include "worldentities/Actionpoint.h" 42 43 … … 90 91 virtual void tick(float dt); 91 92 92 //----[XML data]----93 //----[XML methods]---- 93 94 virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); 94 //----[Action data]---- 95 Action::Value getAction (); 96 void setAction (Action::Value action); 97 void setAction (Action::Value action, ControllableEntity* target); 98 void setAction (Action::Value action, const Vector3& target); 99 void setAction (Action::Value action, const Vector3& target, const Quaternion& orient ); 100 void setActionXML( std::string val); 101 std::string getActionXML(); 102 //----[/Action data]---- 103 //----[Formation data]---- 104 virtual void setFormationModeXML(std::string val); 105 virtual std::string getFormationModeXML(); 106 virtual void setFormationMode(FormationMode::Value val) 107 { this->formationMode_ = val; } 108 inline FormationMode::Value getFormationMode() const 109 { return this->formationMode_; } 110 //----[/Formation data]---- 111 //----[Rank data]---- 112 virtual void setRank(Rank::Value val) 113 { this->rank_ = val; } 114 inline Rank::Value getRank() const 115 { return this->rank_; } 116 //----[/Rank data]---- 117 //----[Protect data]---- 118 void setProtectXML( std::string val ); 119 std::string getProtectXML (); 120 void setProtect (ControllableEntity* protect); 121 ControllableEntity* getProtect (); 122 //----[/Protect data]---- 123 //----[Actionpoint data]---- 95 96 void setFormationModeXML(std::string val); 97 std::string getFormationModeXML(); 98 void setFormationMode(FormationMode::Value val); 99 FormationMode::Value getFormationMode() const; 100 101 void setRank(Rank::Value val); 102 Rank::Value getRank() const; 103 124 104 void addActionpoint(WorldEntity* waypoint); 125 105 WorldEntity* getActionpoint(unsigned int index) const; 126 //----[/Actionpoint data]---- 127 //----[/XML data]---- 106 //----[/XML methods]---- 128 107 129 108 //----[Interaction with other Controllers]---- 130 109 virtual bool setWingman(CommonController* wingman); 131 110 virtual bool hasWingman(); 132 133 void setPositionOfTarget(const Vector3& target); 134 void setOrientationOfTarget(const Quaternion& orient); 135 136 void setTarget(ControllableEntity* target); 111 112 bool hasTarget(); 137 113 ControllableEntity* getTarget(); 138 bool hasTarget(); 139 140 void setTargetPosition(const Vector3& target); 141 void setTargetOrientation(const Quaternion& orient); 142 void setTargetOrientation(ControllableEntity* target); 114 115 Action::Value getAction (); 116 std::string getActionName(); 117 118 void setAction (Action::Value action); 119 void setAction (Action::Value action, ControllableEntity* target); 120 void setAction (Action::Value action, const Vector3& target); 121 void setAction (Action::Value action, const Vector3& target, const Quaternion& orient ); 143 122 //----[/Interaction with other Controllers]---- 144 123 145 //----[Helper functions]----124 //----[Helper methods]---- 146 125 float randomInRange(float a, float b); 147 126 static float distance(ControllableEntity* entity1, ControllableEntity* entity2); … … 151 130 152 131 float squaredDistanceToTarget() const; 153 bool isLookingAtTarget(float angle) const; 154 //----[/Helper functions]---- 155 132 bool isLookingAtTarget(float angle); 133 //----[/Helper methods]---- 134 135 //----[Actionpoint information]---- 136 137 std::vector<WeakPtr<WorldEntity> > actionpoints_; 138 float squaredaccuracy_; 139 std::vector<Point > parsedActionpoints_; 140 141 //----[/Actionpoint information]---- 142 //----[Actionpoint methods]---- 143 void executeActionpoint(); 144 void nextActionpoint(); 145 //----[Actionpoint methods]---- 156 146 protected: 157 //----[Flying functionality]----147 //----[Flying methods]---- 158 148 void stopMoving(); 159 160 void moveToPoint(const Vector3& relativeTargetPosition, float angleRoll); 161 bool moveAndRoll(float dt); 149 void stopLookingAtTarget(); 150 void startLookingAtTarget(); 162 151 163 152 void moveToPosition(const Vector3& target, float dt); … … 168 157 169 158 void lookAtTarget(float dt); 170 void stopLookingAtTarget(); 171 void startLookingAtTarget(); 172 173 bool bLookAtTarget_; 174 //----[/Flying functionality]---- 159 160 void setTargetPosition(const Vector3& target); 161 void setTargetOrientation(const Quaternion& orient); 162 void setTargetOrientation(ControllableEntity* target); 163 164 165 //----[/Flying methods]---- 175 166 176 //----[Fighting functionality]---- 167 //----[Fighting methods]---- 168 void setTarget(ControllableEntity* target); 169 170 void setPositionOfTarget(const Vector3& target); 171 void setOrientationOfTarget(const Quaternion& orient); 172 173 void setProtect (ControllableEntity* protect); 174 ControllableEntity* getProtect (); 175 177 176 void maneuver(); 178 177 void dodge(Vector3& thisPosition, Vector3& diffUnit); 179 void aimAtTarget();180 178 bool canFire(); 181 179 void doFire(); 182 180 void setClosestTarget(); 183 181 Pawn* closestTarget(); 184 185 bool bShooting_; 186 int maneuverCounter_; 187 //----[/Fighting functionality]---- 182 bool startAttackingEnemiesThatAreClose(); 183 //----[/Fighting methods]---- 188 184 189 185 //----[where-to-fly information]---- 186 190 187 bool bHasTargetPosition_; 191 188 Vector3 targetPosition_; … … 193 190 Quaternion targetOrientation_; 194 191 195 196 192 //----[/where-to-fly information]---- 197 193 //----[protect information]---- … … 207 203 //----[/who-to-kill information]---- 208 204 209 //----[Actionpoint information]---- 210 std::vector<WeakPtr<WorldEntity> > actionpoints_; 211 float squaredaccuracy_; 212 Point currentActionpoint_; 213 std::vector<Point > parsedActionpoints_; 214 void executeActionpoint(); 215 void nextActionpoint(); 216 //----[/Actionpoint information]---- 205 217 206 //----["Private" variables]---- 218 207 FormationMode::Value formationMode_; … … 222 211 Action::Value action_; 223 212 int attackRange_; 224 213 bool bLookAtTarget_; 214 bool bShooting_; 215 int maneuverCounter_; 216 int tolerance_; 217 bool bFirstTick_; 225 218 //----[/"Private" variables]---- 226 219 }; -
code/branches/campaignHS15/src/orxonox/controllers/DivisionController.cc
r10850 r10851 46 46 this->actionTimer_.setTimer(ACTION_INTERVAL, true, createExecutor(createFunctor(&DivisionController::action, this))); 47 47 this->rank_ = Rank::DIVISIONLEADER; 48 49 50 48 } 51 49 … … 60 58 //XMLPortParam(DivisionController, "target_", setTarget, getTarget, xmlelement, mode).defaultValues(100.0f); 61 59 } 62 63 64 60 void DivisionController::tick(float dt) 65 61 { 66 67 62 if (!this->isActive()) 68 63 return; 69 70 71 64 SUPER(DivisionController, tick, dt); 72 73 65 } 74 66 void DivisionController::action() 75 { 76 //----Whatever ship is doing, if there are targets close to it and its own target is far away, fight them---- 77 //analog to attack move 78 if (this->action_ != Action::FIGHT && this->action_ != Action::FIGHTALL) 79 { 80 if ( (this->target_ && CommonController::distance (this->getControllableEntity(), this->target_) > this->attackRange_) 81 || !this->target_ ) 82 { 83 Pawn* newTarget = this->closestTarget(); 84 if ( newTarget && 85 CommonController::distance (this->getControllableEntity(), static_cast<ControllableEntity*>(newTarget)) 86 <= this->attackRange_ ) 87 { 88 // this->backupAction(); 89 // this->setAction (Action::FIGHT, newTarget); 90 Point p = { Action::FIGHT, CommonController::getName(newTarget), Vector3::ZERO }; 91 this->parsedActionpoints_.push_back(p); 92 this->executeActionpoint(); 93 } 94 } 95 } 96 97 //action is NONE whenever ships finishes current action, 98 //if it was fighting before because enemies were close, resume what it was doing 99 //otherwise try to execute next action 67 { 68 if (this->startAttackingEnemiesThatAreClose()) 69 { 70 Point p = { Action::FIGHT, "", Vector3::ZERO }; 71 72 if (this->myWingman_) 73 { 74 this->myWingman_->parsedActionpoints_.push_back(p); 75 } 76 if (this->myFollower_) 77 { 78 this->myFollower_->parsedActionpoints_.push_back(p); 79 } 80 } 81 100 82 if (this->action_ == Action::NONE) 101 83 { 102 84 this->executeActionpoint(); 103 85 } 104 105 106 //this->action_ is what I am actually executing, this->target_ is what I am107 //actually attacking, etc.108 109 //after action is finished, .pop_back() is to be called.110 86 if (this->action_ == Action::FIGHT || this->action_ == Action::FIGHTALL) 111 87 { … … 116 92 if (this->action_ == Action::FIGHT) 117 93 { 118 if (newTarget && CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_) 94 if (newTarget && 95 CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_) 119 96 { 120 97 this->setAction (Action::FIGHT, newTarget); … … 123 100 { 124 101 this->nextActionpoint(); 102 if (this->myWingman_) 103 { 104 this->myWingman_->nextActionpoint(); 105 } 106 if (this->myFollower_) 107 { 108 this->myFollower_->nextActionpoint(); 109 } 125 110 return; 126 111 } … … 135 120 { 136 121 this->nextActionpoint(); 122 if (this->myWingman_) 123 { 124 this->myWingman_->nextActionpoint(); 125 } 126 if (this->myFollower_) 127 { 128 this->myFollower_->nextActionpoint(); 129 } 137 130 return; 138 131 } … … 144 137 //----fly in formation if far enough---- 145 138 Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition(); 146 147 139 148 140 if (diffVector.length() > this->attackRange_) … … 151 143 { 152 144 this->nextActionpoint(); 145 if (this->myWingman_) 146 { 147 this->myWingman_->nextActionpoint(); 148 } 149 if (this->myFollower_) 150 { 151 this->myFollower_->nextActionpoint(); 152 } 153 153 return; 154 154 } … … 158 158 this->setTargetPositionOfFollower(); 159 159 } 160 161 160 } 162 161 else … … 165 164 if (this->myWingman_) 166 165 { 167 this->myWingman_->setAction ( this->action_, this->target_);166 this->myWingman_->setAction (Action::FIGHT, this->target_); 168 167 } 169 168 if (this->myFollower_) 170 169 { 171 this->myFollower_->setAction (this->action_); 172 } 173 174 } 175 176 } 177 if (this->hasTarget()) 178 { 179 //----choose where to go---- 180 this->maneuver(); 181 //----fire if you can---- 182 this->bShooting_ = this->canFire(); 183 } 184 170 this->myFollower_->setAction (Action::FIGHT); 171 } 172 } 173 } 185 174 } 186 175 else if (this->action_ == Action::FLY) 187 176 { 188 189 177 if (this->squaredDistanceToTarget() <= this->squaredaccuracy_) 190 178 { 191 orxout(internal_error) << "arrived";192 179 this->nextActionpoint(); 180 if (this->myWingman_) 181 { 182 this->myWingman_->nextActionpoint(); 183 } 184 if (this->myFollower_) 185 { 186 this->myFollower_->nextActionpoint(); 187 } 193 188 return; 194 189 } … … 201 196 { 202 197 this->nextActionpoint(); 198 if (this->myWingman_) 199 { 200 this->myWingman_->nextActionpoint(); 201 } 202 if (this->myFollower_) 203 { 204 this->myFollower_->nextActionpoint(); 205 } 203 206 return; 204 207 } 205 /* if (this->myWingman_) 206 this->myWingman_->setAction (Action::PROTECT, this->getProtect()); 207 if (this->myFollower_) 208 this->myFollower_->setAction (Action::PROTECT, this->getProtect()); 209 */ 208 210 209 Vector3* targetRelativePosition; 211 210 212 targetRelativePosition = new Vector3 (0, 0, 500);211 targetRelativePosition = new Vector3 (0, 300, 300); 213 212 214 213 Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) + … … 225 224 { 226 225 this->nextActionpoint(); 226 if (this->myWingman_) 227 { 228 this->myWingman_->nextActionpoint(); 229 } 230 if (this->myFollower_) 231 { 232 this->myFollower_->nextActionpoint(); 233 } 227 234 return; 228 235 } … … 239 246 if (this->myWingman_) 240 247 { 241 this->myWingman_->setAction ( this->action_, this->target_);248 this->myWingman_->setAction (Action::FIGHT, this->target_); 242 249 } 243 250 if (this->myFollower_) 244 251 { 245 this->myFollower_->setAction (this->action_); 246 } 247 248 } 249 252 this->myFollower_->setAction (Action::FIGHT); 253 } 254 } 255 } 256 if (this->hasTarget()) 257 { 250 258 //----choose where to go---- 251 259 this->maneuver(); … … 253 261 this->bShooting_ = this->canFire(); 254 262 } 255 256 } 257 263 } 258 264 259 260 265 void DivisionController::setTargetPositionOfWingman() 261 266 { … … 321 326 myFollower_->setAction ( Action::FLY, targetAbsolutePositionOfFollower, orient ); 322 327 } 323 324 325 328 bool DivisionController::setWingman(CommonController* cwingman) 326 329 { … … 336 339 return false; 337 340 } 338 339 341 } 340 342 bool DivisionController::setFollower(LeaderController* myFollower) … … 364 366 return false; 365 367 } 366 367 368 369 370 371 368 } -
code/branches/campaignHS15/src/orxonox/controllers/SectionController.cc
r10843 r10851 44 44 this->myDivisionLeader_ = 0; 45 45 this->rank_ = Rank::SECTIONLEADER; 46 46 this->bFirstAction_ = true; 47 47 //orxout(internal_error) << this << "Was created" << endl; 48 48 … … 72 72 void SectionController::action() 73 73 { 74 74 75 //----If no leader, find one---- 75 76 if (!myDivisionLeader_) … … 83 84 { 84 85 } 85 86 //----action was set to fight---- 87 if (this->action_ == Action::FIGHT) 88 { 89 if (!this->hasTarget()) 90 { 91 if (this->myDivisionLeader_) 92 { 93 this->chooseTarget(); 94 } 95 else 96 { 97 this->setClosestTarget(); 98 } 99 } 100 else 101 { 86 if (!myDivisionLeader_) 87 { 88 if (this->startAttackingEnemiesThatAreClose()) 89 { 90 Point p = { Action::FIGHT, "", Vector3::ZERO }; 102 91 92 if (this->myWingman_) 93 { 94 this->myWingman_->parsedActionpoints_.push_back(p); 95 } 96 } 97 if (this->action_ == Action::NONE) 98 { 99 this->executeActionpoint(); 100 } 101 if (this->action_ == Action::FIGHT || this->action_ == Action::FIGHTALL) 102 { 103 if (!this->hasTarget()) 104 { 105 //----find a target---- 106 ControllableEntity* newTarget = this->closestTarget(); 107 if (this->action_ == Action::FIGHT) 108 { 109 if (newTarget && 110 CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_) 111 { 112 this->setAction (Action::FIGHT, newTarget); 113 } 114 else 115 { 116 this->nextActionpoint(); 117 if (this->myWingman_) 118 { 119 this->myWingman_->nextActionpoint(); 120 } 121 122 return; 123 } 124 } 125 else if (this->action_ == Action::FIGHTALL) 126 { 127 if (newTarget && newTarget->getController()) 128 { 129 this->setAction (Action::FIGHTALL, newTarget); 130 } 131 else 132 { 133 this->nextActionpoint(); 134 if (this->myWingman_) 135 { 136 this->myWingman_->nextActionpoint(); 137 } 138 return; 139 } 140 } 141 142 } 143 else if (this->hasTarget()) 144 { 145 //----fly in formation if far enough---- 146 Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition(); 147 148 if (diffVector.length() > this->attackRange_) 149 { 150 if (this->action_ == Action::FIGHT) 151 { 152 this->nextActionpoint(); 153 if (this->myWingman_) 154 { 155 this->myWingman_->nextActionpoint(); 156 } 157 return; 158 } 159 else 160 { 161 this->setTargetPositionOfWingman(); 162 } 163 } 164 else 165 { 166 //----wingmans shall support the fire of their leaders---- 167 if (this->myWingman_) 168 { 169 this->myWingman_->setAction (Action::FIGHT, this->target_); 170 } 171 172 } 173 } 174 } 175 else if (this->action_ == Action::FLY) 176 { 177 if (this->squaredDistanceToTarget() <= this->squaredaccuracy_) 178 { 179 this->nextActionpoint(); 180 if (this->myWingman_) 181 { 182 this->myWingman_->nextActionpoint(); 183 } 184 return; 185 } 186 this->setTargetPositionOfWingman(); 187 } 188 else if (this->action_ == Action::PROTECT) 189 { 190 if (!this->getProtect()) 191 { 192 this->nextActionpoint(); 193 if (this->myWingman_) 194 { 195 this->myWingman_->nextActionpoint(); 196 } 197 return; 198 } 199 200 Vector3* targetRelativePosition; 201 202 targetRelativePosition = new Vector3 (0, 300, 300); 203 204 Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) + 205 (this->getProtect()->getWorldOrientation()* (*targetRelativePosition))); 206 this->setTargetPosition(targetAbsolutePosition); 207 208 this->setTargetPositionOfWingman(); 209 210 } 211 else if (this->action_ == Action::ATTACK) 212 { 213 if (!this->hasTarget()) 214 { 215 this->nextActionpoint(); 216 if (this->myWingman_) 217 { 218 this->myWingman_->nextActionpoint(); 219 } 220 return; 221 } 103 222 //----fly in formation if far enough---- 104 223 Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition(); 105 if (diffVector.length() > 3000)224 if (diffVector.length() > this->attackRange_) 106 225 { 107 226 this->setTargetPositionOfWingman(); 108 } 227 } 109 228 else 110 229 { … … 112 231 if (this->myWingman_) 113 232 { 114 this->myWingman_->setAction (Action::FIGHT, this->target_); 115 } 116 } 233 this->myWingman_->setAction (Action::FIGHT, this->target_); 234 } 235 236 } 117 237 } 118 238 if (this->hasTarget()) … … 124 244 } 125 245 } 126 127 //----action was set to fly---- 128 else if (this->action_ == Action::FLY) 129 { 130 this->setTargetPositionOfWingman(); 131 } 132 133 //----action was set to protect---- 134 else if (this->action_ == Action::PROTECT) 135 { 136 /* if (this->myWingman_) 137 this->myWingman_->setAction (Action::PROTECT, this->getProtect()); 138 */ 139 this->setTargetPositionOfWingman(); 140 141 } 142 143 246 //----If have leader---- 247 else 248 { 249 //----action was set to fight---- 250 if (this->action_ == Action::FIGHT) 251 { 252 if (!this->hasTarget()) 253 { 254 this->chooseTarget(); 255 } 256 else 257 { 258 //----fly in formation if far enough---- 259 Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition(); 260 if (diffVector.length() > this->attackRange_) 261 { 262 this->setTargetPositionOfWingman(); 263 } 264 else 265 { 266 //----wingmans shall support the fire of their leaders---- 267 if (this->myWingman_) 268 { 269 this->myWingman_->setAction (Action::FIGHT, this->target_); 270 } 271 } 272 } 273 if (this->hasTarget()) 274 { 275 //----choose where to go---- 276 this->maneuver(); 277 //----fire if you can---- 278 this->bShooting_ = this->canFire(); 279 } 280 } 281 282 //----action was set to fly---- 283 else if (this->action_ == Action::FLY) 284 { 285 this->setTargetPositionOfWingman(); 286 Pawn* newTarget = this->closestTarget(); 287 if ( newTarget && this->distance (this->getControllableEntity(), 288 static_cast<ControllableEntity*>(newTarget)) <= this->attackRange_ ) 289 { 290 this->setAction (Action::FIGHT, static_cast<ControllableEntity*>(newTarget)); 291 } 292 } 293 } 294 if (this->bFirstAction_ && this->myDivisionLeader_) 295 { 296 this->parsedActionpoints_ = this->myDivisionLeader_->parsedActionpoints_; 297 this->bFirstAction_ = false; 298 } 144 299 } 145 300 //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT … … 267 422 } 268 423 return 0; 269 270 424 } 271 425 bool SectionController::setWingman(CommonController* cwingman) … … 291 445 return false; 292 446 } 293 294 295 296 297 298 447 } -
code/branches/campaignHS15/src/orxonox/controllers/SectionController.h
r10843 r10851 67 67 //----private variables----- 68 68 Timer actionTimer_; //<! Regularly calls action(). 69 bool bFirstAction_; 69 70 70 71 -
code/branches/campaignHS15/src/orxonox/controllers/WingmanController.cc
r10843 r10851 42 42 this->myLeader_ = 0; 43 43 this->rank_ = Rank::WINGMAN; 44 this->bFirstAction_ = true; 45 44 46 } 45 47 … … 69 71 void WingmanController::action() 70 72 { 73 71 74 //----If no leader, find one---- 72 75 if (!this->myLeader_) … … 79 82 else 80 83 { 81 this->action_ = this->myLeader_->getAction(); 82 } 83 84 85 //----action was set to fight---- 86 if (this->action_ == Action::FIGHT) 87 { 88 //----If no leader found, attack someone---- 89 if (!this->hasTarget() && !this->myLeader_) 90 { 91 this->setClosestTarget(); 84 85 } 86 if (!this->myLeader_) 87 { 88 bool b = this->startAttackingEnemiesThatAreClose(); 89 90 if (this->action_ == Action::NONE) 91 { 92 this->executeActionpoint(); 93 } 94 if (this->action_ == Action::FIGHT || this->action_ == Action::FIGHTALL) 95 { 96 if (!this->hasTarget()) 97 { 98 //----find a target---- 99 ControllableEntity* newTarget = this->closestTarget(); 100 if (this->action_ == Action::FIGHT) 101 { 102 if (newTarget && 103 CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_) 104 { 105 this->setAction (Action::FIGHT, newTarget); 106 } 107 else 108 { 109 this->nextActionpoint(); 110 return; 111 } 112 } 113 else if (this->action_ == Action::FIGHTALL) 114 { 115 if (newTarget && newTarget->getController()) 116 { 117 this->setAction (Action::FIGHTALL, newTarget); 118 } 119 else 120 { 121 this->nextActionpoint(); 122 return; 123 } 124 } 125 126 } 127 else if (this->hasTarget()) 128 { 129 //----fly in formation if far enough---- 130 Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition(); 131 132 if (diffVector.length() > this->attackRange_) 133 { 134 if (this->action_ == Action::FIGHT) 135 { 136 this->nextActionpoint(); 137 return; 138 } 139 } 140 } 141 } 142 else if (this->action_ == Action::FLY) 143 { 144 if (this->squaredDistanceToTarget() <= this->squaredaccuracy_) 145 { 146 this->nextActionpoint(); 147 return; 148 } 149 } 150 else if (this->action_ == Action::PROTECT) 151 { 152 if (!this->getProtect()) 153 { 154 this->nextActionpoint(); 155 return; 156 } 157 158 Vector3* targetRelativePosition; 159 160 targetRelativePosition = new Vector3 (0, 300, 300); 161 162 Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) + 163 (this->getProtect()->getWorldOrientation()* (*targetRelativePosition))); 164 this->setTargetPosition(targetAbsolutePosition); 165 166 167 } 168 else if (this->action_ == Action::ATTACK) 169 { 170 if (!this->hasTarget()) 171 { 172 this->nextActionpoint(); 173 return; 174 } 175 92 176 } 93 177 if (this->hasTarget()) … … 99 183 } 100 184 } 101 //----action was set to fly, leader handles the logic---- 102 else if (this->action_ == Action::FLY) 103 { 104 105 } 106 //----gani-TODO: implement protect---- 107 else if (this->action_ == Action::PROTECT) 108 { 109 110 } 111 185 else 186 { 187 //----action was set to fight---- 188 if (this->action_ == Action::FIGHT) 189 { 190 //----If no leader found, attack someone---- 191 if (!this->hasTarget()) 192 { 193 this->setClosestTarget(); 194 } 195 if (this->hasTarget()) 196 { 197 //----choose where to go---- 198 this->maneuver(); 199 //----fire if you can---- 200 this->bShooting_ = this->canFire(); 201 } 202 } 203 //----action was set to fly, leader handles the logic---- 204 else if (this->action_ == Action::FLY) 205 { 206 207 } 208 } 209 if (this->bFirstAction_ && this->myLeader_) 210 { 211 this->parsedActionpoints_ = this->myLeader_->parsedActionpoints_; 212 this->bFirstAction_ = false; 213 } 112 214 } 113 215 -
code/branches/campaignHS15/src/orxonox/controllers/WingmanController.h
r10843 r10851 63 63 WeakPtr<CommonController> myLeader_; 64 64 Timer actionTimer_; //<! Regularly calls action(). 65 65 bool bFirstAction_; 66 66 67 }; 67 68 }
Note: See TracChangeset
for help on using the changeset viewer.