Changeset 7163 for code/trunk/src/orxonox/controllers
- Timestamp:
- Aug 11, 2010, 8:55:13 AM (14 years ago)
- Location:
- code/trunk
- Files:
-
- 10 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/orxonox/controllers/AIController.cc
r5929 r7163 23 23 * Fabian 'x3n' Landau 24 24 * Co-authors: 25 * ...25 * Dominik Solenicki 26 26 * 27 27 */ … … 33 33 #include "core/Executor.h" 34 34 #include "worldentities/ControllableEntity.h" 35 #include "worldentities/pawns/Pawn.h" 35 36 36 37 namespace orxonox … … 56 57 float maxrand = 100.0f / ACTION_INTERVAL; 57 58 58 // search enemy 59 random = rnd(maxrand); 60 if (random < 15 && (!this->target_)) 61 this->searchNewTarget(); 62 63 // forget enemy 64 random = rnd(maxrand); 65 if (random < 5 && (this->target_)) 66 this->forgetTarget(); 67 68 // next enemy 69 random = rnd(maxrand); 70 if (random < 10 && (this->target_)) 71 this->searchNewTarget(); 72 73 // fly somewhere 74 random = rnd(maxrand); 75 if (random < 50 && (!this->bHasTargetPosition_ && !this->target_)) 76 this->searchRandomTargetPosition(); 77 78 // stop flying 79 random = rnd(maxrand); 80 if (random < 10 && (this->bHasTargetPosition_ && !this->target_)) 81 this->bHasTargetPosition_ = false; 82 83 // fly somewhere else 84 random = rnd(maxrand); 85 if (random < 30 && (this->bHasTargetPosition_ && !this->target_)) 86 this->searchRandomTargetPosition(); 87 88 // shoot 89 random = rnd(maxrand); 90 if (random < 75 && (this->target_ && !this->bShooting_)) 91 this->bShooting_ = true; 92 93 // stop shooting 94 random = rnd(maxrand); 95 if (random < 25 && (this->bShooting_)) 96 this->bShooting_ = false; 59 if (this->state_ == FREE) 60 { 61 62 if (this->formationFlight_) 63 { 64 // return to Master after being forced free 65 if (this->freedomCount_ == 1) 66 { 67 this->state_ = SLAVE; 68 this->freedomCount_ = 0; 69 } 70 71 random = rnd(maxrand); 72 if (random < 90 && (((!this->target_) || (random < 50 && this->target_)) && !this->forcedFree())) 73 this->searchNewMaster(); 74 } 75 76 // search enemy 77 random = rnd(maxrand); 78 if (random < 15 && (!this->target_)) 79 this->searchNewTarget(); 80 81 // forget enemy 82 random = rnd(maxrand); 83 if (random < 5 && (this->target_)) 84 this->forgetTarget(); 85 86 // next enemy 87 random = rnd(maxrand); 88 if (random < 10 && (this->target_)) 89 this->searchNewTarget(); 90 91 // fly somewhere 92 random = rnd(maxrand); 93 if (random < 50 && (!this->bHasTargetPosition_ && !this->target_)) 94 this->searchRandomTargetPosition(); 95 96 // stop flying 97 random = rnd(maxrand); 98 if (random < 10 && (this->bHasTargetPosition_ && !this->target_)) 99 this->bHasTargetPosition_ = false; 100 101 // fly somewhere else 102 random = rnd(maxrand); 103 if (random < 30 && (this->bHasTargetPosition_ && !this->target_)) 104 this->searchRandomTargetPosition(); 105 106 // shoot 107 random = rnd(maxrand); 108 if (!(this->passive_) && random < 75 && (this->target_ && !this->bShooting_)) 109 this->bShooting_ = true; 110 111 // stop shooting 112 random = rnd(maxrand); 113 if (random < 25 && (this->bShooting_)) 114 this->bShooting_ = false; 115 116 } 117 118 if (this->state_ == SLAVE) 119 { 120 121 } 122 123 if (this->state_ == MASTER) 124 { 125 126 127 this->commandSlaves(); 128 129 if (this->specificMasterAction_ != NONE) 130 this->specificMasterActionHold(); 131 132 else { 133 134 // make 180 degree turn - a specific Master Action 135 random = rnd(1000.0f); 136 if (random < 5) 137 this->turn180Init(); 138 139 // spin around - a specific Master Action 140 random = rnd(1000.0f); 141 if (random < 5) 142 this->spinInit(); 143 144 // follow a randomly chosen human - a specific Master Action 145 random = rnd(1000.0f); 146 if (random < 1) 147 this->followRandomHumanInit(); 148 149 // lose master status (only if less than 4 slaves in formation) 150 random = rnd(maxrand); 151 if(random < 15/(this->slaves_.size()+1) && this->slaves_.size() < 4 ) 152 this->loseMasterState(); 153 154 // look out for outher masters if formation is small 155 random = rnd(maxrand); 156 if(this->slaves_.size() < 3 && random < 20) 157 this->searchNewMaster(); 158 159 // search enemy 160 random = rnd(maxrand); 161 if (random < 15 && (!this->target_)) 162 this->searchNewTarget(); 163 164 // forget enemy 165 random = rnd(maxrand); 166 if (random < 5 && (this->target_)) 167 this->forgetTarget(); 168 169 // next enemy 170 random = rnd(maxrand); 171 if (random < 10 && (this->target_)) 172 this->searchNewTarget(); 173 174 // fly somewhere 175 random = rnd(maxrand); 176 if (random < 50 && (!this->bHasTargetPosition_ && !this->target_)) 177 this->searchRandomTargetPosition(); 178 179 180 // fly somewhere else 181 random = rnd(maxrand); 182 if (random < 30 && (this->bHasTargetPosition_ && !this->target_)) 183 this->searchRandomTargetPosition(); 184 185 // shoot 186 random = rnd(maxrand); 187 if (!(this->passive_) && random < 9 && (this->target_ && !this->bShooting_)) 188 { 189 this->bShooting_ = true; 190 this->forceFreeSlaves(); 191 } 192 193 // stop shooting 194 random = rnd(maxrand); 195 if (random < 25 && (this->bShooting_)) 196 this->bShooting_ = false; 197 198 } 199 } 200 97 201 } 98 202 … … 102 206 return; 103 207 104 if (this->target_) 105 this->aimAtTarget(); 106 107 if (this->bHasTargetPosition_) 108 this->moveToTargetPosition(); 109 110 if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(1000) && this->isLookingAtTarget(Ogre::Math::PI / 20.0f)) 111 this->getControllableEntity()->fire(0); 208 if (this->state_ == MASTER) 209 { 210 if (this->specificMasterAction_ == NONE) 211 { 212 if (this->target_) 213 { 214 if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */ 215 this->forgetTarget(); 216 else this->aimAtTarget(); 217 } 218 219 if (this->bHasTargetPosition_) 220 this->moveToTargetPosition(); 221 222 if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(1000) && this->isLookingAtTarget(Ogre::Math::PI / 20.0f)) 223 this->getControllableEntity()->fire(0); 224 } 225 226 if (this->specificMasterAction_ == TURN180) 227 this->turn180(); 228 229 if (this->specificMasterAction_ == SPIN) 230 this->spin(); 231 if (this->specificMasterAction_ == FOLLOW) 232 this->follow(); 233 } 234 235 if (this->state_ == SLAVE) 236 { 237 238 if (this->bHasTargetPosition_) 239 this->moveToTargetPosition(); 240 241 } 242 243 if (this->state_ == FREE) 244 { 245 if (this->target_) 246 { 247 if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */ 248 this->forgetTarget(); 249 else this->aimAtTarget(); 250 } 251 252 if (this->bHasTargetPosition_) 253 this->moveToTargetPosition(); 254 255 if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(1000) && this->isLookingAtTarget(Ogre::Math::PI / 20.0f)) 256 this->getControllableEntity()->fire(0); 257 } 112 258 113 259 SUPER(AIController, tick, dt); -
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 } -
code/trunk/src/orxonox/controllers/ArtificialController.h
r6417 r7163 23 23 * Fabian 'x3n' Landau 24 24 * Co-authors: 25 * ...25 * Dominik Solenicki 26 26 * 27 27 */ … … 32 32 #include "OrxonoxPrereqs.h" 33 33 34 #include <vector> 35 34 36 #include "util/Math.h" 35 37 #include "Controller.h" 38 #include "controllers/NewHumanController.h" 36 39 37 40 namespace orxonox … … 43 46 virtual ~ArtificialController(); 44 47 48 virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); 49 45 50 void abandonTarget(Pawn* target); 46 51 52 inline void setTeam(int team) 53 { this->team_ = team; } 54 inline int getTeam() const 55 { return this->team_; } 56 57 inline void setFormationFlight(bool formation) 58 { this->formationFlight_ = formation; } 59 inline bool getFormationFlight() const 60 { return this->formationFlight_; } 61 62 inline void setFormationSize(int size) 63 { this->maxFormationSize_ = size; } 64 inline int getFormationSize() const 65 { return this->maxFormationSize_; } 66 67 inline void setPassive(bool passive) 68 { this->passive_ = passive; } 69 inline bool getPassive() const 70 { return this->passive_; } 71 72 virtual void changedControllableEntity(); 73 74 static void formationflight(const bool form); 75 static void masteraction(const int action); 76 static void followme(); 77 static void passivebehaviour(const bool passive); 78 static void formationsize(const int size); 79 47 80 protected: 48 void targetDied(); 81 82 int team_; 83 bool formationFlight_; 84 bool passive_; 85 unsigned int maxFormationSize_; 86 int freedomCount_; 87 enum State {SLAVE, MASTER, FREE}; 88 State state_; 89 std::vector<ArtificialController*> slaves_; 90 ArtificialController *myMaster_; 91 enum SpecificMasterAction {NONE, HOLD, SPIN, TURN180, FOLLOW}; 92 SpecificMasterAction specificMasterAction_; 93 int specificMasterActionHoldCount_; 94 float speedCounter_; //for speed adjustment when following 49 95 50 96 void moveToPosition(const Vector3& target); 51 97 void moveToTargetPosition(); 98 99 void removeFromFormation(); 100 void unregisterSlave(); 101 void searchNewMaster(); 102 void commandSlaves(); 103 void setNewMasterWithinFormation(); 104 105 void freeSlaves(); 106 void forceFreeSlaves(); 107 void loseMasterState(); 108 void forceFreedom(); 109 bool forcedFree(); 110 111 void specificMasterActionHold(); 112 void turn180Init(); 113 void turn180(); 114 void spinInit(); 115 void spin(); 116 void followInit(Pawn* pawn, const bool always = false, const int secondsToFollow = 100); 117 void followRandomHumanInit(); 118 void follow(); 119 void followForSlaves(const Vector3& target); 52 120 53 121 void setTargetPosition(const Vector3& target); … … 61 129 bool isCloseAtTarget(float distance) const; 62 130 bool isLookingAtTarget(float angle) const; 131 132 void targetDied(); 63 133 64 134 static bool sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype); // hack -
code/trunk/src/orxonox/controllers/CMakeLists.txt
r6417 r7163 8 8 WaypointController.cc 9 9 WaypointPatrolController.cc 10 DroneController.cc 10 11 ) -
code/trunk/src/orxonox/controllers/HumanController.cc
r6417 r7163 35 35 #include "gametypes/Gametype.h" 36 36 #include "infos/PlayerInfo.h" 37 #include "overlays/Map.h"38 37 #include "Radar.h" 39 38 #include "Scene.h" … … 116 115 void HumanController::yaw(const Vector2& value) 117 116 { 118 //Hack to enable mouselook in map119 if ( Map::getSingletonPtr() && Map::getSingletonPtr()->getVisibility() && HumanController::localController_s->controllableEntity_->isInMouseLook() )120 {121 Map::getSingletonPtr()->rotateYaw(value);122 return;123 }124 117 if (HumanController::localController_s && HumanController::localController_s->controllableEntity_) 125 118 HumanController::localController_s->controllableEntity_->rotateYaw(value); … … 128 121 void HumanController::pitch(const Vector2& value) 129 122 { 130 //Hack to enable mouselook in map131 if ( Map::getSingletonPtr() && Map::getSingletonPtr()->getVisibility() && HumanController::localController_s->controllableEntity_->isInMouseLook() )132 {133 Map::getSingletonPtr()->rotatePitch(value);134 return;135 }136 123 if (HumanController::localController_s && HumanController::localController_s->controllableEntity_) 137 124 HumanController::localController_s->controllableEntity_->rotatePitch(value); -
code/trunk/src/orxonox/controllers/NewHumanController.cc
r6598 r7163 217 217 if (this->getControllableEntity() && (this->getControllableEntity()->isExactlyA(ClassByString("SpaceShip")) || this->getControllableEntity()->isExactlyA(ClassByString("Rocket")))) 218 218 this->showOverlays(); 219 else if (this->getControllableEntity() && this->getControllableEntity()->isExactlyA(ClassByString("FpsPlayer"))) 220 { 221 this->showOverlays(); 222 this->hideArrows(); 223 } 219 224 220 225 this->crossHairOverlay_->setPosition(Vector2(static_cast<float>(this->currentYaw_)/2*-1+.5f-overlaySize_/2, static_cast<float>(this->currentPitch_)/2*-1+.5f-overlaySize_/2)); … … 364 369 Ogre::RaySceneQueryResult& result = rsq->execute(); 365 370 Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity()); 371 WorldEntity* myWe = static_cast<WorldEntity*>(this->getControllableEntity()); 366 372 367 373 Ogre::RaySceneQueryResult::iterator itr; 368 374 for (itr = result.begin(); itr != result.end(); ++itr) 369 375 { 370 if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" && itr->distance > 500) 376 // CCOUT(0) << "testing object as target" << endl; 377 if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" /*&& itr->distance > 500*/) 371 378 { 372 379 // Try to cast the user pointer 373 WorldEntity* wePtr = dynamic_cast<WorldEntity*>(Ogre::any_cast<OrxonoxClass*>(itr->movable->getUserAny())); 380 WorldEntity* wePtr; 381 try 382 { 383 wePtr = dynamic_cast<WorldEntity*>(Ogre::any_cast<OrxonoxClass*>(itr->movable->getUserAny())); 384 } 385 catch (...) 386 { 387 continue; 388 } 389 390 // make sure we don't shoot ourselves 391 if( wePtr==myWe ) 392 continue; 393 374 394 if (wePtr) 375 395 { … … 379 399 while (parent) 380 400 { 381 if (this->targetMask_.isExcluded(parent->getIdentifier()) )401 if (this->targetMask_.isExcluded(parent->getIdentifier()) || parent==myWe) 382 402 { 383 403 parent = parent->getParent(); … … 430 450 HumanController::yaw(value); 431 451 432 this->currentYaw_ = value.x; 452 if (this->getControllableEntity() && !this->getControllableEntity()->isExactlyA(ClassByString("FpsPlayer"))) 453 this->currentYaw_ = value.x; 433 454 } 434 455 … … 439 460 HumanController::pitch(value); 440 461 441 this->currentPitch_ = value.x; 462 if (this->getControllableEntity() && !this->getControllableEntity()->isExactlyA(ClassByString("FpsPlayer"))) 463 this->currentPitch_ = value.x; 442 464 } 443 465 … … 579 601 } 580 602 } 603 604 605 606 607 581 608 } -
code/trunk/src/orxonox/controllers/NewHumanController.h
r6417 r7163 67 67 virtual void doResumeControl(); 68 68 69 69 70 protected: 70 71 void updateTarget(); -
code/trunk/src/orxonox/controllers/WaypointPatrolController.cc
r6502 r7163 42 42 RegisterObject(WaypointPatrolController); 43 43 44 this->team_ = 0;44 //this->team_ = 0; 45 45 this->alertnessradius_ = 500; 46 46 … … 53 53 54 54 XMLPortParam(WaypointPatrolController, "alertnessradius", setAlertnessRadius, getAlertnessRadius, xmlelement, mode).defaultValues(500.0f); 55 XMLPortParam(WaypointPatrolController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(0);55 // XMLPortParam(WaypointPatrolController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(0); 56 56 } 57 57 -
code/trunk/src/orxonox/controllers/WaypointPatrolController.h
r5929 r7163 46 46 virtual void tick(float dt); 47 47 48 inline void setTeam(int team)48 /* inline void setTeam(int team) 49 49 { this->team_ = team; } 50 50 inline int getTeam() const 51 { return this->team_; } 51 { return this->team_; } */ 52 52 53 53 inline void setAlertnessRadius(float radius) … … 59 59 void searchEnemy(); 60 60 61 int team_;61 //int team_; 62 62 float alertnessradius_; 63 63 Timer patrolTimer_;
Note: See TracChangeset
for help on using the changeset viewer.