- Timestamp:
- Aug 11, 2010, 8:55:13 AM (15 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/orxonox/controllers/ArtificialController.cc
r6502 r7163 23 23 * Fabian 'x3n' Landau 24 24 * Co-authors: 25 * ...25 * Dominik Solenicki 26 26 * 27 27 */ … … 29 29 #include "ArtificialController.h" 30 30 31 #include <vector> 32 #include <climits> 33 34 #include "util/Math.h" 35 #include "core/ConsoleCommand.h" 31 36 #include "core/CoreIncludes.h" 37 #include "core/XMLPort.h" 32 38 #include "worldentities/ControllableEntity.h" 33 39 #include "worldentities/pawns/Pawn.h" 34 40 #include "worldentities/pawns/TeamBaseMatchBase.h" 35 41 #include "gametypes/TeamDeathmatch.h" 42 #include "gametypes/Dynamicmatch.h" 36 43 #include "controllers/WaypointPatrolController.h" 44 #include "controllers/NewHumanController.h" 45 #include "controllers/DroneController.h" 37 46 38 47 namespace orxonox 39 48 { 49 SetConsoleCommand(ArtificialController, formationflight, true); 50 SetConsoleCommand(ArtificialController, masteraction, true); 51 SetConsoleCommand(ArtificialController, followme, true); 52 SetConsoleCommand(ArtificialController, passivebehaviour, true); 53 SetConsoleCommand(ArtificialController, formationsize, true); 54 55 static const unsigned int STANDARD_MAX_FORMATION_SIZE = 7; 56 static const int RADIUS_TO_SEARCH_FOR_MASTERS = 5000; 57 static const int FORMATION_LENGTH = 130; 58 static const int FORMATION_WIDTH = 110; 59 static const int FREEDOM_COUNT = 4; //seconds the slaves in a formation will be set free when master attacks an enemy 60 static const float SPEED_MASTER = 0.6f; 61 static const float ROTATEFACTOR_MASTER = 0.2f; 62 static const float SPEED_FREE = 0.8f; 63 static const float ROTATEFACTOR_FREE = 0.8f; 64 65 40 66 ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator) 41 67 { … … 43 69 44 70 this->target_ = 0; 71 this->formationFlight_ = true; 72 this->passive_ = false; 73 this->maxFormationSize_ = STANDARD_MAX_FORMATION_SIZE; 74 this->myMaster_ = 0; 75 this->freedomCount_ = 0; 76 this->team_ = -1; 77 this->state_ = FREE; 78 this->specificMasterAction_ = NONE; 79 this->specificMasterActionHoldCount_ = 0; 45 80 this->bShooting_ = false; 46 81 this->bHasTargetPosition_ = false; 82 this->speedCounter_ = 0.2f; 47 83 this->targetPosition_ = Vector3::ZERO; 48 84 … … 52 88 ArtificialController::~ArtificialController() 53 89 { 90 if (this->isInitialized()) 91 { 92 this->removeFromFormation(); 93 94 for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it; ++it) 95 { 96 if (*it != this) 97 { 98 if (it->myMaster_ == this) 99 { 100 COUT(1) << "error: " << this << " is still master in " << (*it) << std::endl; 101 it->myMaster_ = 0; 102 } 103 104 while (true) 105 { 106 std::vector<ArtificialController*>::iterator it2 = std::find(it->slaves_.begin(), it->slaves_.end(), this); 107 if (it2 != it->slaves_.end()) 108 { 109 COUT(1) << "error: " << this << " is still slave in " << (*it) << std::endl; 110 it->slaves_.erase(it2); 111 } 112 else 113 break; 114 } 115 } 116 } 117 } 118 } 119 120 void ArtificialController::XMLPort(Element& xmlelement, XMLPort::Mode mode) 121 { 122 SUPER(ArtificialController, XMLPort, xmlelement, mode); 123 124 XMLPortParam(ArtificialController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(-1); 125 XMLPortParam(ArtificialController, "formationFlight", setFormationFlight, getFormationFlight, xmlelement, mode).defaultValues(false); 126 XMLPortParam(ArtificialController, "formationSize", setFormationSize, getFormationSize, xmlelement, mode).defaultValues(STANDARD_MAX_FORMATION_SIZE); 127 XMLPortParam(ArtificialController, "passive", setPassive, getPassive, xmlelement, mode).defaultValues(false); 128 } 129 130 // Documentation only here to get a faster overview for creating a useful documentation... 131 132 /** 133 @brief Activates / deactivates formationflight behaviour 134 @param form activate formflight if form is true 135 */ 136 void ArtificialController::formationflight(const bool form) 137 { 138 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 139 { 140 Controller* controller = 0; 141 142 if (it->getController()) 143 controller = it->getController(); 144 else if (it->getXMLController()) 145 controller = it->getXMLController(); 146 147 if (!controller) 148 continue; 149 150 ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller); 151 152 if (aiController) 153 { 154 aiController->formationFlight_ = form; 155 if (!form) 156 { 157 aiController->removeFromFormation(); 158 } 159 } 160 } 161 } 162 163 /** 164 @brief Get all masters to do a "specific master action" 165 @param action which action to perform (integer, so it can be called with a console command (tmp solution)) 166 */ 167 void ArtificialController::masteraction(const int action) 168 { 169 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 170 { 171 Controller* controller = 0; 172 173 if (it->getController()) 174 controller = it->getController(); 175 else if (it->getXMLController()) 176 controller = it->getXMLController(); 177 178 if (!controller) 179 continue; 180 181 ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller); 182 183 if(aiController && aiController->state_ == MASTER) 184 { 185 if (action == 1) 186 aiController->spinInit(); 187 if (action == 2) 188 aiController->turn180Init(); 189 } 190 } 191 } 192 193 /** 194 @brief A human player gets followed by its nearest master. Initiated by console command, so far intended for demonstration puproses (possible future pickup). 195 */ 196 void ArtificialController::followme() 197 { 198 199 Pawn *humanPawn = NULL; 200 NewHumanController *currentHumanController = NULL; 201 std::vector<ArtificialController*> allMasters; 202 203 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 204 { 205 Controller* controller = 0; 206 207 if (it->getController()) 208 controller = it->getController(); 209 else if (it->getXMLController()) 210 controller = it->getXMLController(); 211 212 if (!controller) 213 continue; 214 215 currentHumanController = orxonox_cast<NewHumanController*>(controller); 216 217 if(currentHumanController) humanPawn = *it; 218 219 ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller); 220 221 if(aiController && aiController->state_ == MASTER) 222 allMasters.push_back(aiController); 223 224 } 225 226 if((humanPawn != NULL) && (allMasters.size() != 0)) 227 { 228 float posHuman = humanPawn->getPosition().length(); 229 float distance = 0.0f; 230 float minDistance = FLT_MAX; 231 int index = 0; 232 int i = 0; 233 234 for(std::vector<ArtificialController*>::iterator it = allMasters.begin(); it != allMasters.end(); it++, i++) 235 { 236 if (!ArtificialController::sameTeam((*it)->getControllableEntity(), humanPawn, (*it)->getGametype())) continue; 237 distance = posHuman - (*it)->getControllableEntity()->getPosition().length(); 238 if(distance < minDistance) index = i; 239 } 240 allMasters[index]->followInit(humanPawn); 241 } 242 243 } 244 245 /** 246 @brief Sets shooting behaviour of pawns. 247 @param passive if true, bots won't shoot. 248 */ 249 void ArtificialController::passivebehaviour(const bool passive) 250 { 251 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 252 { 253 Controller* controller = 0; 254 255 if (it->getController()) 256 controller = it->getController(); 257 else if (it->getXMLController()) 258 controller = it->getXMLController(); 259 260 if (!controller) 261 continue; 262 263 ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller); 264 265 if(aiController) 266 { 267 aiController->passive_ = passive; 268 } 269 } 270 } 271 272 273 /** 274 @brief Sets maximal formation size 275 @param size maximal formation size. 276 */ 277 void ArtificialController::formationsize(const int size) 278 { 279 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 280 { 281 Controller* controller = 0; 282 283 if (it->getController()) 284 controller = it->getController(); 285 else if (it->getXMLController()) 286 controller = it->getXMLController(); 287 288 if (!controller) 289 continue; 290 291 ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller); 292 293 if(aiController) 294 { 295 aiController->maxFormationSize_ = size; 296 } 297 } 298 } 299 300 /** 301 @brief Gets called when ControllableEntity is being changed. Resets the bot when it dies. 302 */ 303 void ArtificialController::changedControllableEntity() 304 { 305 if (!this->getControllableEntity()) 306 this->removeFromFormation(); 307 } 308 309 void ArtificialController::removeFromFormation() 310 { 311 if (this->state_ == SLAVE || this->myMaster_) // slaves can also be temporary free, so check if myMaster_ is set 312 this->unregisterSlave(); 313 else if (this->state_ == MASTER) 314 this->setNewMasterWithinFormation(); 54 315 } 55 316 … … 59 320 return; 60 321 322 // Slave uses special movement if its master is in FOLLOW mode 323 if(this->state_ == SLAVE && this->myMaster_ && this->myMaster_->specificMasterAction_ == FOLLOW) 324 { 325 // this->followForSlaves(target); 326 // return; 327 } 328 61 329 Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target); 62 330 float distance = (target - this->getControllableEntity()->getPosition()).length(); 63 331 64 if (this->target_ || distance > 10) 65 { 66 // Multiply with 0.8 to make them a bit slower 67 this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x); 68 this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y); 69 } 70 71 if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength()) 72 this->getControllableEntity()->moveFrontBack(-0.5f); // They don't brake with full power to give the player a chance 332 333 if(this->state_ == FREE) 334 { 335 if (this->target_ || distance > 10) 336 { 337 // Multiply with ROTATEFACTOR_FREE to make them a bit slower 338 this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x); 339 this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y); 340 } 341 342 if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength()) 343 { 344 this->getControllableEntity()->moveFrontBack(-0.05f); // They don't brake with full power to give the player a chance 345 } else this->getControllableEntity()->moveFrontBack(SPEED_FREE); 346 } 347 348 349 350 if(this->state_ == MASTER) 351 { 352 if (this->target_ || distance > 10) 353 { 354 this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x); 355 this->getControllableEntity()->rotatePitch(ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y); 356 } 357 358 if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength()) 359 { 360 this->getControllableEntity()->moveFrontBack(-0.05f); 361 } else this->getControllableEntity()->moveFrontBack(SPEED_MASTER); 362 } 363 364 365 366 if(this->state_ == SLAVE) 367 { 368 369 this->getControllableEntity()->rotateYaw(-2.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x); 370 this->getControllableEntity()->rotatePitch(2.0f * ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y); 371 372 if (distance < 300) 373 { 374 if (distance < 40) 375 { 376 this->getControllableEntity()->moveFrontBack(0.8f*SPEED_MASTER); 377 } else this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER); 378 379 } else { 380 this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER + distance/300.0f); 381 } 382 } 383 } 384 385 void ArtificialController::moveToTargetPosition() 386 { 387 this->moveToPosition(this->targetPosition_); 388 } 389 390 391 /** 392 @brief Unregisters a slave from its master. Initiated by a slave. 393 */ 394 void ArtificialController::unregisterSlave() 395 { 396 if (this->myMaster_) 397 { 398 std::vector<ArtificialController*>::iterator it = std::find(this->myMaster_->slaves_.begin(), this->myMaster_->slaves_.end(), this); 399 if (it != this->myMaster_->slaves_.end()) 400 this->myMaster_->slaves_.erase(it); 401 } 402 403 this->myMaster_ = 0; 404 this->state_ = FREE; 405 } 406 407 void ArtificialController::searchNewMaster() 408 { 409 410 if (!this->getControllableEntity()) 411 return; 412 413 this->targetPosition_ = this->getControllableEntity()->getPosition(); 414 this->forgetTarget(); 415 int teamSize = 0; 416 //go through all pawns 417 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 418 { 419 //same team? 420 if (!ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype())) 421 continue; 422 423 //has it an ArtificialController? 424 Controller* controller = 0; 425 426 if (it->getController()) 427 controller = it->getController(); 428 else if (it->getXMLController()) 429 controller = it->getXMLController(); 430 431 if (!controller) 432 continue; 433 434 //is pawn oneself? 435 if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity()) 436 continue; 437 438 teamSize++; 439 440 ArtificialController *newMaster = orxonox_cast<ArtificialController*>(controller); 441 442 //is it a master? 443 if (!newMaster || newMaster->state_ != MASTER) 444 continue; 445 446 float distance = (it->getPosition() - this->getControllableEntity()->getPosition()).length(); 447 448 // is pawn in range? 449 if (distance < RADIUS_TO_SEARCH_FOR_MASTERS) 450 { 451 if(newMaster->slaves_.size() > this->maxFormationSize_) continue; 452 453 for(std::vector<ArtificialController*>::iterator itSlave = this->slaves_.begin(); itSlave != this->slaves_.end(); itSlave++) 454 { 455 (*itSlave)->myMaster_ = newMaster; 456 newMaster->slaves_.push_back(*itSlave); 457 } 458 this->slaves_.clear(); 459 this->state_ = SLAVE; 460 461 this->myMaster_ = newMaster; 462 newMaster->slaves_.push_back(this); 463 464 break; 465 } 466 } 467 468 if (this->state_ != SLAVE && teamSize != 0) 469 { 470 this->state_ = MASTER; 471 this->myMaster_ = 0; 472 } 473 } 474 475 /** 476 @brief Commands the slaves of a master into a formation. Sufficiently fast not to be called within tick. Initiated by a master. 477 */ 478 void ArtificialController::commandSlaves() 479 { 480 if(this->state_ != MASTER) return; 481 482 Quaternion orient = this->getControllableEntity()->getOrientation(); 483 Vector3 dest = this->getControllableEntity()->getPosition(); 484 485 // 1 slave: follow 486 if (this->slaves_.size() == 1) 487 { 488 dest += 4*orient*WorldEntity::BACK; 489 this->slaves_.front()->setTargetPosition(dest); 490 } 73 491 else 74 this->getControllableEntity()->moveFrontBack(0.8f); 75 } 76 77 void ArtificialController::moveToTargetPosition() 78 { 79 this->moveToPosition(this->targetPosition_); 80 } 492 { 493 dest += 1.0f*orient*WorldEntity::BACK; 494 Vector3 pos = Vector3::ZERO; 495 int i = 1; 496 497 for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++) 498 { 499 pos = Vector3::ZERO; 500 if (i <= 1) pos += dest + FORMATION_WIDTH*(orient*WorldEntity::LEFT); 501 if (i == 2) pos += dest + FORMATION_WIDTH*(orient*WorldEntity::RIGHT); 502 if (i == 3) pos += dest + FORMATION_WIDTH*(orient*WorldEntity::UP); 503 if (i >= 4) 504 { 505 pos += dest + FORMATION_WIDTH*(orient*WorldEntity::DOWN); 506 i = 1; 507 dest += FORMATION_LENGTH*(orient*WorldEntity::BACK); 508 (*it)->setTargetPosition(pos); 509 continue; 510 } 511 i++; 512 (*it)->setTargetPosition(pos); 513 } 514 } 515 } 516 517 /** 518 @brief Sets a new master within the formation. Called by a master. 519 */ 520 void ArtificialController::setNewMasterWithinFormation() 521 { 522 if(this->state_ != MASTER) return; 523 524 if (!this->slaves_.empty()) 525 { 526 ArtificialController *newMaster = this->slaves_.back(); 527 this->slaves_.pop_back(); 528 529 newMaster->state_ = MASTER; 530 newMaster->slaves_ = this->slaves_; 531 newMaster->myMaster_ = 0; 532 533 for(std::vector<ArtificialController*>::iterator it = newMaster->slaves_.begin(); it != newMaster->slaves_.end(); it++) 534 { 535 (*it)->myMaster_ = newMaster; 536 } 537 } 538 539 this->slaves_.clear(); 540 this->specificMasterAction_ = NONE; 541 this->state_ = FREE; 542 } 543 544 /** 545 @brief Frees all slaves form a master. Initiated by a master. 546 */ 547 void ArtificialController::freeSlaves() 548 { 549 if(this->state_ != MASTER) return; 550 551 for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++) 552 { 553 (*it)->state_ = FREE; 554 (*it)->myMaster_ = 0; 555 } 556 this->slaves_.clear(); 557 } 558 559 /** 560 @brief Master sets its slaves free for @var FREEDOM_COUNT seconds. 561 */ 562 void ArtificialController::forceFreeSlaves() 563 { 564 if(this->state_ != MASTER) return; 565 566 for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++) 567 { 568 (*it)->state_ = FREE; 569 (*it)->forceFreedom(); 570 (*it)->targetPosition_ = this->targetPosition_; 571 (*it)->bShooting_ = true; 572 // (*it)->getControllableEntity()->fire(0);// fire once for fun 573 } 574 } 575 576 void ArtificialController::loseMasterState() 577 { 578 this->freeSlaves(); 579 this->state_ = FREE; 580 } 581 582 583 void ArtificialController::forceFreedom() 584 { 585 this->freedomCount_ = FREEDOM_COUNT; 586 } 587 588 /** 589 @brief Checks wether caller has been forced free, decrements time to stay forced free. 590 @return true if forced free. 591 */ 592 bool ArtificialController::forcedFree() 593 { 594 if(this->freedomCount_ > 0) 595 { 596 this->freedomCount_--; 597 return true; 598 } else return false; 599 } 600 601 /** 602 @brief Used to continue a "specific master action" for a certain time and resuming normal behaviour after. 603 */ 604 void ArtificialController::specificMasterActionHold() 605 { 606 if(this->state_ != MASTER) return; 607 608 if (specificMasterActionHoldCount_ == 0) 609 { 610 this->specificMasterAction_ = NONE; 611 this->searchNewTarget(); 612 } 613 else specificMasterActionHoldCount_--; 614 } 615 616 /** 617 @brief Master initializes a 180 degree turn. Leads to a "specific master action". 618 */ 619 void ArtificialController::turn180Init() 620 { 621 if(this->state_ != MASTER) return; 622 623 Quaternion orient = this->getControllableEntity()->getOrientation(); 624 625 this->setTargetPosition(this->getControllableEntity()->getPosition() + 1000.0f*orient*WorldEntity::BACK); 626 627 this->specificMasterActionHoldCount_ = 4; 628 629 this->specificMasterAction_ = TURN180; 630 } 631 632 /** 633 @brief Execute the 180 degree turn. Called within tick. 634 */ 635 void ArtificialController::turn180() 636 { 637 Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->targetPosition_); 638 639 this->getControllableEntity()->rotateYaw(-2.0f * sgn(coord.x) * coord.x*coord.x); 640 this->getControllableEntity()->rotatePitch(2.0f * sgn(coord.y) * coord.y*coord.y); 641 642 this->getControllableEntity()->moveFrontBack(SPEED_MASTER); 643 } 644 645 /** 646 @brief Master initializes a spin around its looking direction axis. Leads to a "specific master action". 647 */ 648 void ArtificialController::spinInit() 649 { 650 if(this->state_ != MASTER) return; 651 this->specificMasterAction_ = SPIN; 652 this->specificMasterActionHoldCount_ = 10; 653 } 654 655 /** 656 @brief Execute the spin. Called within tick. 657 */ 658 void ArtificialController::spin() 659 { 660 this->moveToTargetPosition(); 661 this->getControllableEntity()->rotateRoll(0.8f); 662 } 663 664 /** 665 @brief Master begins to follow a pawn. Is a "specific master action". 666 @param pawn pawn to follow. 667 @param alaways follows pawn forever if true (false if omitted). 668 @param secondsToFollow seconds to follow the pawn if always is false. Will follow pawn 100 seconds if omitted (set in header). 669 */ 670 void ArtificialController::followInit(Pawn* pawn, const bool always, const int secondsToFollow) 671 { 672 if (pawn == NULL || this->state_ != MASTER) 673 return; 674 this->specificMasterAction_ = FOLLOW; 675 676 this->setTarget(pawn); 677 if (!always) 678 this->specificMasterActionHoldCount_ = secondsToFollow; 679 else 680 this->specificMasterActionHoldCount_ = INT_MAX; //for now... 681 682 } 683 684 685 /** 686 @brief Master begins to follow a randomly chosen human player of the same team. Is a "specific master action". 687 */ 688 void ArtificialController::followRandomHumanInit() 689 { 690 691 Pawn *humanPawn = NULL; 692 NewHumanController *currentHumanController = NULL; 693 694 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 695 { 696 if (!it->getController()) 697 continue; 698 699 currentHumanController = orxonox_cast<NewHumanController*>(it->getController()); 700 if(currentHumanController) 701 { 702 if (!ArtificialController::sameTeam(this->getControllableEntity(), *it, this->getGametype())) continue; 703 humanPawn = *it; 704 break; 705 } 706 } 707 708 if((humanPawn != NULL)) 709 this->followInit(humanPawn); 710 } 711 712 /** 713 @brief Master follows target with adjusted speed. Called within tick. 714 */ 715 void ArtificialController::follow() 716 { 717 if (this->target_) 718 this->moveToPosition(this->target_->getPosition()); 719 else 720 this->specificMasterActionHoldCount_ = 0; 721 /* 722 if (!this->getControllableEntity()) 723 return; 724 725 float distance = (this->target_->getPosition() - this->getControllableEntity()->getPosition()).length(); 726 727 Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->target_->getPosition()); 728 729 730 this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x); 731 this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y); 732 733 float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->target_->getVelocity().squaredLength(); 734 735 COUT(0) << "~follow distance: " << distance << "SpeedCounter: " << this->speedCounter_ << "~speedDiv: " << speedDiv << std::endl; 736 if (distance < 800) 737 { 738 if (distance < 200) 739 { 740 this->speedCounter_ -= 0.5f; 741 if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f; 742 this->getControllableEntity()->moveFrontBack(speedCounter_); 743 } else { 744 if(speedDiv < 0) 745 this->speedCounter_ += 0.01f; 746 else 747 this->speedCounter_ -= 0.05f; 748 this->getControllableEntity()->moveFrontBack(speedCounter_); 749 } 750 751 } else { 752 this->speedCounter_ += 0.05f; 753 this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f); 754 } 755 // if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0; 756 757 */ 758 } 759 760 761 /** 762 @brief Slave moving behaviour when master is following a pawn, gets redirected from moveToPosition(const Vector3& target)). Called within tick. 763 */ 764 void ArtificialController::followForSlaves(const Vector3& target) 765 { 766 767 /* 768 if (!this->getControllableEntity() && !this->myMaster_ && this->myMaster_->state_ != FOLLOW && !this->myMaster_->target_) 769 return; 770 771 float distance = (target - this->getControllableEntity()->getPosition()).length(); 772 773 Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target); 774 775 776 this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x); 777 this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y); 778 779 780 float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->myMaster_->target_->getVelocity().squaredLength(); 781 782 783 if (distance < 800) 784 { 785 if (distance < 200) 786 { 787 this->speedCounter_ -= 5.0f; 788 if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f; 789 this->getControllableEntity()->moveFrontBack(speedCounter_); 790 } else { 791 if(speedDiv < 0) 792 this->speedCounter_ += 0.01f; 793 else 794 this->speedCounter_ -= 0.05f; 795 this->getControllableEntity()->moveFrontBack(speedCounter_); 796 } 797 798 } else { 799 this->speedCounter_ += 0.05f; 800 this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f); 801 } 802 // if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0; 803 */ 804 } 805 81 806 82 807 void ArtificialController::setTargetPosition(const Vector3& target) … … 111 836 { 112 837 if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype())) 838 continue; 839 840 /* So AI won't choose invisible Spaceships as target */ 841 if (!it->getRadarVisibility()) 113 842 continue; 114 843 … … 144 873 this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO); 145 874 146 Pawn* pawn = dynamic_cast<Pawn*>(this->getControllableEntity());875 Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity()); 147 876 if (pawn) 148 877 pawn->setAimPosition(this->targetPosition_); … … 188 917 int team2 = -1; 189 918 190 if (entity1->getXMLController()) 191 { 192 WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity1->getXMLController()); 193 if (wpc) 194 team1 = wpc->getTeam(); 195 } 196 if (entity2->getXMLController()) 197 { 198 WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity2->getXMLController()); 199 if (wpc) 200 team2 = wpc->getTeam(); 919 Controller* controller = 0; 920 if (entity1->getController()) 921 controller = entity1->getController(); 922 else 923 controller = entity1->getXMLController(); 924 if (controller) 925 { 926 ArtificialController* ac = orxonox_cast<ArtificialController*>(controller); 927 if (ac) 928 team1 = ac->getTeam(); 929 } 930 931 if (entity2->getController()) 932 controller = entity2->getController(); 933 else 934 controller = entity2->getXMLController(); 935 if (controller) 936 { 937 ArtificialController* ac = orxonox_cast<ArtificialController*>(controller); 938 if (ac) 939 team2 = ac->getTeam(); 201 940 } 202 941 … … 245 984 } 246 985 986 DroneController* droneController = 0; 987 droneController = orxonox_cast<DroneController*>(entity1->getController()); 988 if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2) 989 return true; 990 droneController = orxonox_cast<DroneController*>(entity2->getController()); 991 if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1) 992 return true; 993 DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController()); 994 DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController()); 995 if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner()) 996 return true; 997 998 Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype); 999 if (dynamic) 1000 { 1001 if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;} 1002 1003 if (entity1->getPlayer()) 1004 team1 = dynamic->getParty(entity1->getPlayer()); 1005 1006 if (entity2->getPlayer()) 1007 team2 = dynamic->getParty(entity2->getPlayer()); 1008 1009 if (team1 ==-1 ||team2 ==-1 ) {return false;} 1010 else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;} 1011 else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;} 1012 else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;} 1013 else return true; 1014 } 1015 247 1016 return (team1 == team2 && team1 != -1); 248 1017 }
Note: See TracChangeset
for help on using the changeset viewer.