Changeset 9016 for code/trunk/src/orxonox/controllers
- Timestamp:
- Feb 15, 2012, 11:51:58 PM (13 years ago)
- Location:
- code/trunk
- Files:
-
- 12 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/orxonox/controllers/AIController.cc
r8891 r9016 59 59 if (this->state_ == FREE) 60 60 { 61 61 62 62 if (this->formationFlight_) 63 63 { 64 65 //changed order -> searchNewMaster MUSTN'T be called in SLAVE-state (bugfix for internal-error messages at quit) 66 random = rnd(maxrand); 67 if (random < 90 && (((!this->target_) || (random < 50 && this->target_)) && !this->forcedFree())) 68 this->searchNewMaster(); 69 64 70 // return to Master after being forced free 65 71 if (this->freedomCount_ == 1) … … 68 74 this->freedomCount_ = 0; 69 75 } 70 71 random = rnd(maxrand); 72 if (random < 90 && (((!this->target_) || (random < 50 && this->target_)) && !this->forcedFree())) 73 this->searchNewMaster(); 74 } 75 76 } 77 78 this->defaultBehaviour(maxrand); 79 80 } 81 82 if (this->state_ == SLAVE && this->formationMode_ == ATTACK) 83 { 76 84 // search enemy 77 85 random = rnd(maxrand); 78 if (random < ( 15 + botlevel_* 20) && (!this->target_))86 if (random < (botlevel_*100) && (!this->target_)) 79 87 this->searchNewTarget(); 80 88 81 // forget enemy82 random = rnd(maxrand);83 if (random < ((1-botlevel_)*6) && (this->target_))84 this->forgetTarget();85 86 89 // next enemy 87 90 random = rnd(maxrand); 88 if (random < (botlevel_* 20) && (this->target_))91 if (random < (botlevel_*30) && (this->target_)) 89 92 this->searchNewTarget(); 90 93 91 // fly somewhere92 random = rnd(maxrand);93 if (random < 50 && (!this->bHasTargetPosition_ && !this->target_))94 this->searchRandomTargetPosition();95 96 // stop flying97 random = rnd(maxrand);98 if (random < 10 && (this->bHasTargetPosition_ && !this->target_))99 this->bHasTargetPosition_ = false;100 101 // fly somewhere else102 random = rnd(maxrand);103 if (random < 30 && (this->bHasTargetPosition_ && !this->target_))104 this->searchRandomTargetPosition();105 106 94 // shoot 107 95 random = rnd(maxrand); 108 if (!(this->passive_) && random < ( 75 + botlevel_*25) && (this->target_ && !this->bShooting_))96 if (!(this->passive_) && random < (botlevel_*100) && (this->target_ && !this->bShooting_)) 109 97 this->bShooting_ = true; 110 98 111 99 // stop shooting 112 100 random = rnd(maxrand); 113 if (random < ( (1 - botlevel_)*25)&& (this->bShooting_))101 if (random < (1-botlevel_)*50 && (this->bShooting_)) 114 102 this->bShooting_ = false; 115 103 116 // boost117 random = rnd(maxrand);118 if (random < botlevel_*100 )119 this->boostControl();120 121 // update Checkpoints122 /*random = rnd(maxrand);123 if (this->defaultWaypoint_ && random > (maxrand-10))124 this->manageWaypoints();125 else //if(random > maxrand-10) //CHECK USABILITY!!*/126 if (this->waypoints_.size() == 0 )127 this->manageWaypoints();128 129 }130 131 if (this->state_ == SLAVE)132 {133 134 104 } 135 105 136 106 if (this->state_ == MASTER) 137 107 { 138 139 140 108 this->commandSlaves(); 141 109 … … 155 123 this->spinInit(); 156 124 157 / / follow a randomly chosen human - a specific Master Action125 /*// follow a randomly chosen human - a specific Master Action 158 126 random = rnd(1000.0f); 159 127 if (random < 1) 160 128 this->followRandomHumanInit(); 161 129 */ 162 130 // lose master status (only if less than 4 slaves in formation) 163 131 random = rnd(maxrand); … … 170 138 this->searchNewMaster(); 171 139 172 // search enemy 173 random = rnd(maxrand); 174 if (random < (botlevel_)*25 && (!this->target_)) 175 this->searchNewTarget(); 176 177 // forget enemy 178 random = rnd(maxrand); 179 if (random < (1-botlevel_)*6 && (this->target_)) 180 this->forgetTarget(); 181 182 // next enemy 183 random = rnd(maxrand); 184 if (random < 10 && (this->target_)) 185 this->searchNewTarget(); 186 187 // fly somewhere 188 random = rnd(maxrand); 189 if (random < 50 && (!this->bHasTargetPosition_ && !this->target_)) 190 this->searchRandomTargetPosition(); 191 192 193 // fly somewhere else 194 random = rnd(maxrand); 195 if (random < 30 && (this->bHasTargetPosition_ && !this->target_)) 196 this->searchRandomTargetPosition(); 197 198 // shoot 199 random = rnd(maxrand); 200 if (!(this->passive_) && random < 25*(botlevel_)+1 && (this->target_ && !this->bShooting_)) 201 { 202 this->bShooting_ = true; 203 this->forceFreeSlaves(); 204 } 205 206 // stop shooting 207 random = rnd(maxrand); 208 if (random < ( (1- botlevel_)*25 ) && (this->bShooting_)) 209 this->bShooting_ = false; 210 211 // boost 212 random = rnd(maxrand); 213 if (random < botlevel_*100 ) 214 this->boostControl(); 215 216 // update Checkpoints 217 /*random = rnd(maxrand); 218 if (this->defaultWaypoint_ && random > (maxrand-10)) 219 this->manageWaypoints(); 220 else //if(random > maxrand-10) //CHECK USABILITY!!*/ 221 if (this->waypoints_.size() == 0 ) 222 this->manageWaypoints(); 140 this->defaultBehaviour(maxrand); 141 223 142 } 224 143 } … … 234 153 float maxrand = 100.0f / ACTION_INTERVAL; 235 154 ControllableEntity* controllable = this->getControllableEntity(); 236 155 //DOES: Either move to the waypoint or search for a Point of interest 237 156 if (controllable && this->mode_ == DEFAULT)// bot is ready to move to a target 238 157 { … … 256 175 } 257 176 } 258 if(this->mode_ == DEFAULT) 259 { 177 178 if (this->mode_ == DEFAULT) 179 { 260 180 if (this->state_ == MASTER) 261 181 { … … 270 190 this->aimAtTarget(); 271 191 random = rnd(maxrand); 272 if(this->botlevel_* 100 > random && !this->isCloseAtTarget(20))192 if(this->botlevel_*70 > random && !this->isCloseAtTarget(100)) 273 193 this->follow(); //If a bot is shooting a player, it shouldn't let him go away easily. 274 194 } … … 277 197 if (this->bHasTargetPosition_) 278 198 this->moveToTargetPosition(); 279 280 199 this->doFire(); 281 200 } … … 290 209 } 291 210 292 if (this->state_ == SLAVE )211 if (this->state_ == SLAVE && this->formationMode_ != ATTACK) 293 212 { 294 213 if (this->bHasTargetPosition_) … … 296 215 } 297 216 298 if (this->state_ == FREE )217 if (this->state_ == FREE || (this->state_==SLAVE && this->formationMode_ == ATTACK) ) 299 218 { 300 219 if (this->target_) … … 302 221 if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */ 303 222 this->forgetTarget(); 304 else 305 { 306 this->aimAtTarget(); 307 random = rnd(maxrand); 308 309 if(this->botlevel_*100 > random && !this->isCloseAtTarget(20)) 310 this->follow();//If a bot is shooting a player, it shouldn't let him go away easily. 311 } 223 else this->aimAtTarget(); 312 224 } 313 225 … … 315 227 this->moveToTargetPosition(); 316 228 317 this->doFire();318 } 319 } //END_OF DEFAULT MODE229 this->doFire(); 230 } 231 } 320 232 else if (this->mode_ == ROCKET)//Rockets do not belong to a group of bots -> bot states are not relevant. 321 233 { //Vector-implementation: mode_.back() == ROCKET; 322 234 if(controllable) 323 { 324 if(controllable->getRocket())//Check wether the bot is controlling the rocket and if the timeout is over. 235 {//Check wether the bot is controlling the rocket and if the timeout is over. 236 if(controllable->getIdentifier() == ClassByString("Rocket")) 237 325 238 { 326 239 this->follow(); … … 341 254 SUPER(AIController, tick, dt); 342 255 } 256 //**********************************************NEW 257 void AIController::defaultBehaviour(float maxrand) 258 { float random; 259 // search enemy 260 random = rnd(maxrand); 261 if (random < (botlevel_* 100) && (!this->target_)) 262 this->searchNewTarget(); 263 264 // forget enemy 265 random = rnd(maxrand); 266 if (random < ((1-botlevel_)*20) && (this->target_)) 267 this->forgetTarget(); 268 269 // next enemy 270 random = rnd(maxrand); 271 if (random < (botlevel_*30) && (this->target_)) 272 this->searchNewTarget(); 273 274 // fly somewhere 275 random = rnd(maxrand); 276 if (random < 50 && (!this->bHasTargetPosition_ && !this->target_)) 277 this->searchRandomTargetPosition(); 278 279 // stop flying 280 random = rnd(maxrand); 281 if (random < 10 && (this->bHasTargetPosition_ && !this->target_)) 282 this->bHasTargetPosition_ = false; 283 284 // fly somewhere else 285 random = rnd(maxrand); 286 if (random < 30 && (this->bHasTargetPosition_ && !this->target_)) 287 this->searchRandomTargetPosition(); 288 289 if (this->state_ == MASTER) // master: shoot 290 { 291 random = rnd(maxrand); 292 if (!(this->passive_) && random < (100*botlevel_) && (this->target_ && !this->bShooting_)) 293 { 294 this->bShooting_ = true; 295 this->forceFreeSlaves(); 296 } 297 } 298 else 299 { 300 // shoot 301 random = rnd(maxrand); 302 if (!(this->passive_) && random < (botlevel_*100) && (this->target_ && !this->bShooting_)) 303 this->bShooting_ = true; 304 } 305 306 // stop shooting 307 random = rnd(maxrand); 308 if (random < ((1 - botlevel_)*50) && (this->bShooting_)) 309 this->bShooting_ = false; 310 311 // boost 312 random = rnd(maxrand); 313 if (random < botlevel_*50 ) 314 this->boostControl(); 315 316 // update Checkpoints 317 /*random = rnd(maxrand); 318 if (this->defaultWaypoint_ && random > (maxrand-10)) 319 this->manageWaypoints(); 320 else //if(random > maxrand-10) //CHECK USABILITY!!*/ 321 if (this->waypoints_.size() == 0 ) 322 this->manageWaypoints(); 323 } 343 324 344 325 } -
code/trunk/src/orxonox/controllers/AIController.h
r8729 r9016 44 44 virtual ~AIController(); 45 45 46 virtual void tick(float dt); 46 virtual void tick(float dt); //<! Carrying out the targets set in action(). 47 47 48 48 protected: 49 virtual void action(); 49 virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour ~ setting targets. 50 void defaultBehaviour(float maxrand); //<! Helper function for code reusage. Some concrete commands for a bot. 50 51 51 52 private: 52 53 static const float ACTION_INTERVAL; 53 54 54 Timer actionTimer_; 55 Timer actionTimer_; //<! Regularly calls action(). 55 56 }; 56 57 } -
code/trunk/src/orxonox/controllers/ArtificialController.cc
r8892 r9016 24 24 * Co-authors: 25 25 * Dominik Solenicki 26 * 26 * 27 27 */ 28 28 29 29 #include "ArtificialController.h" 30 31 #include <vector>32 #include <climits>33 34 #include "util/Math.h"35 30 #include "core/CoreIncludes.h" 36 #include "core/XMLPort.h"37 31 #include "core/command/ConsoleCommand.h" 38 #include "worldentities/ControllableEntity.h"39 32 #include "worldentities/pawns/Pawn.h" 40 #include "worldentities/pawns/TeamBaseMatchBase.h"41 33 #include "worldentities/pawns/SpaceShip.h" 42 #include "gametypes/TeamDeathmatch.h" 43 #include "gametypes/Dynamicmatch.h" 44 #include "controllers/WaypointPatrolController.h" 45 #include "controllers/NewHumanController.h" 46 #include "controllers/DroneController.h" 34 47 35 #include "weaponsystem/WeaponMode.h" 48 36 #include "weaponsystem/WeaponPack.h" … … 51 39 #include "weaponsystem/WeaponSlot.h" 52 40 41 53 42 namespace orxonox 54 43 { 55 SetConsoleCommand("ArtificialController", "formationflight", &ArtificialController::formationflight);56 SetConsoleCommand("ArtificialController", "masteraction", &ArtificialController::masteraction);57 SetConsoleCommand("ArtificialController", "followme", &ArtificialController::followme);58 SetConsoleCommand("ArtificialController", "passivebehaviour", &ArtificialController::passivebehaviour);59 SetConsoleCommand("ArtificialController", "formationsize", &ArtificialController::formationsize);60 44 SetConsoleCommand("ArtificialController", "setbotlevel", &ArtificialController::setAllBotLevel); 61 45 62 static const unsigned int STANDARD_MAX_FORMATION_SIZE = 7; 63 static const int RADIUS_TO_SEARCH_FOR_MASTERS = 5000; 64 static const int FORMATION_LENGTH = 130; 65 static const int FORMATION_WIDTH = 110; 66 static const int FREEDOM_COUNT = 4; //seconds the slaves in a formation will be set free when master attacks an enemy 67 static const float SPEED_MASTER = 0.6f; 68 static const float ROTATEFACTOR_MASTER = 0.2f; 69 static const float SPEED_FREE = 0.8f; 70 static const float ROTATEFACTOR_FREE = 0.8f; 71 72 73 ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator) 74 { 75 RegisterObject(ArtificialController); 76 77 this->target_ = 0; 78 this->formationFlight_ = false; 79 this->passive_ = false; 80 this->maxFormationSize_ = STANDARD_MAX_FORMATION_SIZE; 81 this->myMaster_ = 0; 82 this->freedomCount_ = 0; 83 this->team_ = -1; 84 this->state_ = FREE; 85 this->specificMasterAction_ = NONE; 86 this->specificMasterActionHoldCount_ = 0; 87 this->bShooting_ = false; 88 this->bHasTargetPosition_ = false; 89 this->speedCounter_ = 0.2f; 90 this->targetPosition_ = Vector3::ZERO; 91 92 this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this)); 46 ArtificialController::ArtificialController(BaseObject* creator) : FormationController(creator) 47 { 93 48 this->bSetupWorked = false; 94 this->botlevel_ = 0.2f; 95 this->mode_ = DEFAULT;////Vector-implementation: mode_.push_back(DEFAULT); 49 this->botlevel_ = 0.5f; 96 50 this->timeout_ = 0; 97 51 this->currentWaypoint_ = 0; 98 52 this->setAccuracy(5); 99 53 this->defaultWaypoint_ = NULL; 54 this->mode_ = DEFAULT;//Vector-implementation: mode_.push_back(DEFAULT); 100 55 } 101 56 … … 105 60 {//Vector-implementation: mode_.erase(mode_.begin(),mode_.end()); 106 61 this->waypoints_.clear(); 107 this->removeFromFormation();108 62 this->weaponModes_.clear(); 109 for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it; ++it) 110 { 111 if (*it != this) 112 { 113 if (it->myMaster_ == this) 114 { 115 orxout(internal_error) << this << " is still master in " << (*it) << endl; 116 it->myMaster_ = 0; 117 } 118 119 while (true) 120 { 121 std::vector<ArtificialController*>::iterator it2 = std::find(it->slaves_.begin(), it->slaves_.end(), this); 122 if (it2 != it->slaves_.end()) 123 { 124 orxout(internal_error) << this << " is still slave in " << (*it) << endl; 125 it->slaves_.erase(it2); 126 } 127 else 128 break; 129 } 130 } 131 } 132 } 133 } 134 135 void ArtificialController::XMLPort(Element& xmlelement, XMLPort::Mode mode) 136 { 137 SUPER(ArtificialController, XMLPort, xmlelement, mode); 138 139 XMLPortParam(ArtificialController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(-1); 140 XMLPortParam(ArtificialController, "formationFlight", setFormationFlight, getFormationFlight, xmlelement, mode).defaultValues(false); 141 XMLPortParam(ArtificialController, "formationSize", setFormationSize, getFormationSize, xmlelement, mode).defaultValues(STANDARD_MAX_FORMATION_SIZE); 142 XMLPortParam(ArtificialController, "passive", setPassive, getPassive, xmlelement, mode).defaultValues(false); 143 } 144 145 // Documentation only here to get a faster overview for creating a useful documentation... 146 147 /** 148 @brief Activates / deactivates formationflight behaviour 149 @param form activate formflight if form is true 150 */ 151 void ArtificialController::formationflight(const bool form) 152 { 153 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 154 { 155 Controller* controller = 0; 156 157 if (it->getController()) 158 controller = it->getController(); 159 else if (it->getXMLController()) 160 controller = it->getXMLController(); 161 162 if (!controller) 163 continue; 164 165 ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller); 166 167 if (aiController) 168 { 169 aiController->formationFlight_ = form; 170 if (!form) 171 { 172 aiController->removeFromFormation(); 173 } 174 } 175 } 176 } 177 178 /** 179 @brief Get all masters to do a "specific master action" 180 @param action which action to perform (integer, so it can be called with a console command (tmp solution)) 181 */ 182 void ArtificialController::masteraction(const int action) 183 { 184 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 185 { 186 Controller* controller = 0; 187 188 if (it->getController()) 189 controller = it->getController(); 190 else if (it->getXMLController()) 191 controller = it->getXMLController(); 192 193 if (!controller) 194 continue; 195 196 ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller); 197 198 if(aiController && aiController->state_ == MASTER) 199 { 200 if (action == 1) 201 aiController->spinInit(); 202 if (action == 2) 203 aiController->turn180Init(); 204 } 205 } 206 } 207 208 /** 209 @brief A human player gets followed by its nearest master. Initiated by console command, so far intended for demonstration puproses (possible future pickup). 210 */ 211 void ArtificialController::followme() 212 { 213 214 Pawn *humanPawn = NULL; 215 NewHumanController *currentHumanController = NULL; 216 std::vector<ArtificialController*> allMasters; 217 218 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 219 { 220 Controller* controller = 0; 221 222 if (it->getController()) 223 controller = it->getController(); 224 else if (it->getXMLController()) 225 controller = it->getXMLController(); 226 227 if (!controller) 228 continue; 229 230 currentHumanController = orxonox_cast<NewHumanController*>(controller); 231 232 if(currentHumanController) humanPawn = *it; 233 234 ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller); 235 236 if(aiController && aiController->state_ == MASTER) 237 allMasters.push_back(aiController); 238 239 } 240 241 if((humanPawn != NULL) && (allMasters.size() != 0)) 242 { 243 float posHuman = humanPawn->getPosition().length(); 244 float distance = 0.0f; 245 float minDistance = FLT_MAX; 246 int index = 0; 247 int i = 0; 248 249 for(std::vector<ArtificialController*>::iterator it = allMasters.begin(); it != allMasters.end(); it++, i++) 250 { 251 if (!ArtificialController::sameTeam((*it)->getControllableEntity(), humanPawn, (*it)->getGametype())) continue; 252 distance = posHuman - (*it)->getControllableEntity()->getPosition().length(); 253 if(distance < minDistance) index = i; 254 } 255 allMasters[index]->followInit(humanPawn); 256 } 257 258 } 259 260 /** 261 @brief Sets shooting behaviour of pawns. 262 @param passive if true, bots won't shoot. 263 */ 264 void ArtificialController::passivebehaviour(const bool passive) 265 { 266 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 267 { 268 Controller* controller = 0; 269 270 if (it->getController()) 271 controller = it->getController(); 272 else if (it->getXMLController()) 273 controller = it->getXMLController(); 274 275 if (!controller) 276 continue; 277 278 ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller); 279 280 if(aiController) 281 { 282 aiController->passive_ = passive; 283 } 284 } 285 } 286 287 288 /** 289 @brief Sets maximal formation size 290 @param size maximal formation size. 291 */ 292 void ArtificialController::formationsize(const int size) 293 { 294 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 295 { 296 Controller* controller = 0; 297 298 if (it->getController()) 299 controller = it->getController(); 300 else if (it->getXMLController()) 301 controller = it->getXMLController(); 302 303 if (!controller) 304 continue; 305 306 ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller); 307 308 if(aiController) 309 { 310 aiController->maxFormationSize_ = size; 311 } 312 } 313 } 63 } 64 } 65 314 66 315 67 /** … … 320 72 if (!this->getControllableEntity()) 321 73 this->removeFromFormation(); 322 this->bSetupWorked = false; // reset weapon information 323 this->setupWeapons(); 324 } 325 326 void ArtificialController::removeFromFormation() 327 { 328 if (this->state_ == SLAVE || this->myMaster_) // slaves can also be temporary free, so check if myMaster_ is set 329 this->unregisterSlave(); 330 else if (this->state_ == MASTER) 331 this->setNewMasterWithinFormation(); 332 } 333 334 void ArtificialController::moveToPosition(const Vector3& target) 335 { 336 if (!this->getControllableEntity()) 337 return; 338 339 // Slave uses special movement if its master is in FOLLOW mode 340 if(this->state_ == SLAVE && this->myMaster_ && this->myMaster_->specificMasterAction_ == FOLLOW) 341 { 342 // this->followForSlaves(target); 343 // return; 344 } 345 346 Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target); 347 float distance = (target - this->getControllableEntity()->getPosition()).length(); 348 349 350 if(this->state_ == FREE) 351 { 352 if (this->target_ || distance > 10) 353 { 354 // Multiply with ROTATEFACTOR_FREE to make them a bit slower 355 this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x); 356 this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y); 357 } 358 359 if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength()) 360 { 361 this->getControllableEntity()->moveFrontBack(-0.05f); // They don't brake with full power to give the player a chance 362 } else this->getControllableEntity()->moveFrontBack(SPEED_FREE); 363 } 364 365 366 367 if(this->state_ == MASTER) 368 { 369 if (this->target_ || distance > 10) 370 { 371 this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x); 372 this->getControllableEntity()->rotatePitch(ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y); 373 } 374 375 if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength()) 376 { 377 this->getControllableEntity()->moveFrontBack(-0.05f); 378 } else this->getControllableEntity()->moveFrontBack(SPEED_MASTER); 379 } 380 381 382 383 if(this->state_ == SLAVE) 384 { 385 386 this->getControllableEntity()->rotateYaw(-2.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x); 387 this->getControllableEntity()->rotatePitch(2.0f * ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y); 388 389 if (distance < 300) 390 { 391 if (distance < 40) 392 { 393 this->getControllableEntity()->moveFrontBack(0.8f*SPEED_MASTER); 394 } else this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER); 395 396 } else { 397 this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER + distance/300.0f); 398 } 399 } 400 401 if (distance < 10) 402 { 403 this->positionReached(); 404 } 405 } 406 407 void ArtificialController::absoluteMoveToPosition(const Vector3& target) 408 { 409 float minDistance = 40.0f; 410 if (!this->getControllableEntity()) 411 return; 412 413 Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target); 414 float distance = (target - this->getControllableEntity()->getPosition()).length(); 415 416 if (this->target_ || distance > minDistance) 417 { 418 // Multiply with ROTATEFACTOR_FREE to make them a bit slower 419 this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x); 420 this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y); 421 this->getControllableEntity()->moveFrontBack(SPEED_FREE); 422 } 423 424 425 if (distance < minDistance) 426 { 427 this->positionReached(); 428 } 429 } 430 431 432 void ArtificialController::moveToTargetPosition() 433 { 434 this->moveToPosition(this->targetPosition_); 435 } 436 437 /** 438 @brief Unregisters a slave from its master. Initiated by a slave. 439 */ 440 void ArtificialController::unregisterSlave() 441 { 442 if (this->myMaster_) 443 { 444 std::vector<ArtificialController*>::iterator it = std::find(this->myMaster_->slaves_.begin(), this->myMaster_->slaves_.end(), this); 445 if (it != this->myMaster_->slaves_.end()) 446 this->myMaster_->slaves_.erase(it); 447 } 448 449 this->myMaster_ = 0; 450 this->state_ = FREE; 451 } 452 453 void ArtificialController::searchNewMaster() 454 { 455 456 if (!this->getControllableEntity()) 457 return; 458 459 this->targetPosition_ = this->getControllableEntity()->getPosition(); 460 this->forgetTarget(); 461 int teamSize = 0; 462 //go through all pawns 463 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 464 { 465 //same team? 466 if (!ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype())) 467 continue; 468 469 //has it an ArtificialController? 470 Controller* controller = 0; 471 472 if (it->getController()) 473 controller = it->getController(); 474 else if (it->getXMLController()) 475 controller = it->getXMLController(); 476 477 if (!controller) 478 continue; 479 480 //is pawn oneself? 481 if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity()) 482 continue; 483 484 teamSize++; 485 486 ArtificialController *newMaster = orxonox_cast<ArtificialController*>(controller); 487 488 //is it a master? 489 if (!newMaster || newMaster->state_ != MASTER) 490 continue; 491 492 float distance = (it->getPosition() - this->getControllableEntity()->getPosition()).length(); 493 494 // is pawn in range? 495 if (distance < RADIUS_TO_SEARCH_FOR_MASTERS) 496 { 497 if(newMaster->slaves_.size() > this->maxFormationSize_) continue; 498 499 for(std::vector<ArtificialController*>::iterator itSlave = this->slaves_.begin(); itSlave != this->slaves_.end(); itSlave++) 500 { 501 (*itSlave)->myMaster_ = newMaster; 502 newMaster->slaves_.push_back(*itSlave); 503 } 504 this->slaves_.clear(); 505 this->state_ = SLAVE; 506 507 this->myMaster_ = newMaster; 508 newMaster->slaves_.push_back(this); 509 510 break; 511 } 512 } 513 514 if (this->state_ != SLAVE && teamSize != 0) 515 { 516 this->state_ = MASTER; 517 this->myMaster_ = 0; 518 } 519 } 520 521 /** 522 @brief Commands the slaves of a master into a formation. Sufficiently fast not to be called within tick. Initiated by a master. 523 */ 524 void ArtificialController::commandSlaves() 525 { 526 if(this->state_ != MASTER) return; 527 528 Quaternion orient = this->getControllableEntity()->getOrientation(); 529 Vector3 dest = this->getControllableEntity()->getPosition(); 530 531 // 1 slave: follow 532 if (this->slaves_.size() == 1) 533 { 534 dest += 4*orient*WorldEntity::BACK; 535 this->slaves_.front()->setTargetPosition(dest); 536 } 537 else 538 { 539 dest += 1.0f*orient*WorldEntity::BACK; 540 Vector3 pos = Vector3::ZERO; 541 int i = 1; 542 543 for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++) 544 { 545 pos = Vector3::ZERO; 546 if (i <= 1) pos += dest + (float)FORMATION_WIDTH*(orient*WorldEntity::LEFT); 547 if (i == 2) pos += dest + (float)FORMATION_WIDTH*(orient*WorldEntity::RIGHT); 548 if (i == 3) pos += dest + (float)FORMATION_WIDTH*(orient*WorldEntity::UP); 549 if (i >= 4) 550 { 551 pos += dest + (float)FORMATION_WIDTH*(orient*WorldEntity::DOWN); 552 i = 1; 553 dest += (float)FORMATION_LENGTH*(orient*WorldEntity::BACK); 554 (*it)->setTargetPosition(pos); 555 continue; 556 } 557 i++; 558 (*it)->setTargetPosition(pos); 559 } 560 } 561 } 562 563 /** 564 @brief Sets a new master within the formation. Called by a master. 565 */ 566 void ArtificialController::setNewMasterWithinFormation() 567 { 568 if(this->state_ != MASTER) return; 569 570 if (!this->slaves_.empty()) 571 { 572 ArtificialController *newMaster = this->slaves_.back(); 573 this->slaves_.pop_back(); 574 575 newMaster->state_ = MASTER; 576 newMaster->slaves_ = this->slaves_; 577 newMaster->myMaster_ = 0; 578 579 for(std::vector<ArtificialController*>::iterator it = newMaster->slaves_.begin(); it != newMaster->slaves_.end(); it++) 580 { 581 (*it)->myMaster_ = newMaster; 582 } 583 } 584 585 this->slaves_.clear(); 586 this->specificMasterAction_ = NONE; 587 this->state_ = FREE; 588 } 589 590 /** 591 @brief Frees all slaves form a master. Initiated by a master. 592 */ 593 void ArtificialController::freeSlaves() 594 { 595 if(this->state_ != MASTER) return; 596 597 for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++) 598 { 599 (*it)->state_ = FREE; 600 (*it)->myMaster_ = 0; 601 } 602 this->slaves_.clear(); 603 } 604 605 /** 606 @brief Master sets its slaves free for @ref FREEDOM_COUNT seconds. 607 */ 608 void ArtificialController::forceFreeSlaves() 609 { 610 if(this->state_ != MASTER) return; 611 612 for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++) 613 { 614 (*it)->state_ = FREE; 615 (*it)->forceFreedom(); 616 (*it)->targetPosition_ = this->targetPosition_; 617 (*it)->bShooting_ = true; 618 // (*it)->getControllableEntity()->fire(0);// fire once for fun 619 } 620 } 621 622 void ArtificialController::loseMasterState() 623 { 624 this->freeSlaves(); 625 this->state_ = FREE; 626 } 627 628 629 void ArtificialController::forceFreedom() 630 { 631 this->freedomCount_ = FREEDOM_COUNT; 632 } 633 634 /** 635 @brief Checks wether caller has been forced free, decrements time to stay forced free. 636 @return true if forced free. 637 */ 638 bool ArtificialController::forcedFree() 639 { 640 if(this->freedomCount_ > 0) 641 { 642 this->freedomCount_--; 643 return true; 644 } else return false; 645 } 646 647 /** 648 @brief Used to continue a "specific master action" for a certain time and resuming normal behaviour after. 649 */ 650 void ArtificialController::specificMasterActionHold() 651 { 652 if(this->state_ != MASTER) return; 653 654 if (specificMasterActionHoldCount_ == 0) 655 { 656 this->specificMasterAction_ = NONE; 657 this->searchNewTarget(); 658 } 659 else specificMasterActionHoldCount_--; 660 } 661 662 /** 663 @brief Master initializes a 180 degree turn. Leads to a "specific master action". 664 */ 665 void ArtificialController::turn180Init() 666 { 667 if(this->state_ != MASTER) return; 668 669 Quaternion orient = this->getControllableEntity()->getOrientation(); 670 671 this->setTargetPosition(this->getControllableEntity()->getPosition() + 1000.0f*orient*WorldEntity::BACK); 672 673 this->specificMasterActionHoldCount_ = 4; 674 675 this->specificMasterAction_ = TURN180; 676 } 677 678 /** 679 @brief Execute the 180 degree turn. Called within tick. 680 */ 681 void ArtificialController::turn180() 682 { 683 Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->targetPosition_); 684 685 this->getControllableEntity()->rotateYaw(-2.0f * sgn(coord.x) * coord.x*coord.x); 686 this->getControllableEntity()->rotatePitch(2.0f * sgn(coord.y) * coord.y*coord.y); 687 688 this->getControllableEntity()->moveFrontBack(SPEED_MASTER); 689 } 690 691 /** 692 @brief Master initializes a spin around its looking direction axis. Leads to a "specific master action". 693 */ 694 void ArtificialController::spinInit() 695 { 696 if(this->state_ != MASTER) return; 697 this->specificMasterAction_ = SPIN; 698 this->specificMasterActionHoldCount_ = 10; 699 } 700 701 /** 702 @brief Execute the spin. Called within tick. 703 */ 704 void ArtificialController::spin() 705 { 706 this->moveToTargetPosition(); 707 this->getControllableEntity()->rotateRoll(0.8f); 708 } 709 710 /** 711 @brief Master begins to follow a pawn. Is a "specific master action". 712 @param pawn pawn to follow. 713 @param always follows pawn forever if true (false if omitted). 714 @param secondsToFollow seconds to follow the pawn if always is false. Will follow pawn 100 seconds if omitted (set in header). 715 */ 716 void ArtificialController::followInit(Pawn* pawn, const bool always, const int secondsToFollow) 717 { 718 if (pawn == NULL || this->state_ != MASTER) 719 return; 720 this->specificMasterAction_ = FOLLOW; 721 722 this->setTarget(pawn); 723 if (!always) 724 this->specificMasterActionHoldCount_ = secondsToFollow; 725 else 726 this->specificMasterActionHoldCount_ = INT_MAX; //for now... 727 728 } 729 730 731 /** 732 @brief Master begins to follow a randomly chosen human player of the same team. Is a "specific master action". 733 */ 734 void ArtificialController::followRandomHumanInit() 735 { 736 737 Pawn *humanPawn = NULL; 738 NewHumanController *currentHumanController = NULL; 739 740 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 741 { 742 if (!it->getController()) 743 continue; 744 745 currentHumanController = orxonox_cast<NewHumanController*>(it->getController()); 746 if(currentHumanController) 747 { 748 if (!ArtificialController::sameTeam(this->getControllableEntity(), *it, this->getGametype())) continue; 749 humanPawn = *it; 750 break; 751 } 752 } 753 754 if((humanPawn != NULL)) 755 this->followInit(humanPawn); 756 } 757 758 /** 759 @brief Master follows target with adjusted speed. Called within tick. 760 */ 761 void ArtificialController::follow() 762 { 763 if (this->target_) 764 this->moveToPosition(this->target_->getPosition()); 765 else 766 this->specificMasterActionHoldCount_ = 0; 767 /* 768 if (!this->getControllableEntity()) 769 return; 770 771 float distance = (this->target_->getPosition() - this->getControllableEntity()->getPosition()).length(); 772 773 Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->target_->getPosition()); 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 float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->target_->getVelocity().squaredLength(); 780 781 orxout() << "~follow distance: " << distance << "SpeedCounter: " << this->speedCounter_ << "~speedDiv: " << speedDiv << endl; 782 if (distance < 800) 783 { 784 if (distance < 200) 785 { 786 this->speedCounter_ -= 0.5f; 787 if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f; 788 this->getControllableEntity()->moveFrontBack(speedCounter_); 789 } else { 790 if(speedDiv < 0) 791 this->speedCounter_ += 0.01f; 792 else 793 this->speedCounter_ -= 0.05f; 794 this->getControllableEntity()->moveFrontBack(speedCounter_); 795 } 796 797 } else { 798 this->speedCounter_ += 0.05f; 799 this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f); 800 } 801 // if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0; 802 803 */ 804 } 805 806 807 /** 808 @brief Slave moving behaviour when master is following a pawn, gets redirected from moveToPosition(const Vector3& target)). Called within tick. 809 */ 810 void ArtificialController::followForSlaves(const Vector3& target) 811 { 812 813 /* 814 if (!this->getControllableEntity() && !this->myMaster_ && this->myMaster_->state_ != FOLLOW && !this->myMaster_->target_) 815 return; 816 817 float distance = (target - this->getControllableEntity()->getPosition()).length(); 818 819 Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target); 820 821 822 this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x); 823 this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y); 824 825 826 float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->myMaster_->target_->getVelocity().squaredLength(); 827 828 829 if (distance < 800) 830 { 831 if (distance < 200) 832 { 833 this->speedCounter_ -= 5.0f; 834 if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f; 835 this->getControllableEntity()->moveFrontBack(speedCounter_); 836 } else { 837 if(speedDiv < 0) 838 this->speedCounter_ += 0.01f; 839 else 840 this->speedCounter_ -= 0.05f; 841 this->getControllableEntity()->moveFrontBack(speedCounter_); 842 } 843 844 } else { 845 this->speedCounter_ += 0.05f; 846 this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f); 847 } 848 // if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0; 849 */ 850 } 851 852 853 void ArtificialController::setTargetPosition(const Vector3& target) 854 { 855 this->targetPosition_ = target; 856 this->bHasTargetPosition_ = true; 857 } 858 859 void ArtificialController::searchRandomTargetPosition() 860 { 861 this->targetPosition_ = Vector3(rnd(-2000,2000), rnd(-2000,2000), rnd(-2000,2000)); 862 this->bHasTargetPosition_ = true; 863 } 864 865 void ArtificialController::setTarget(Pawn* target) 866 { 867 this->target_ = target; 868 869 if (target) 870 this->targetPosition_ = target->getPosition(); 871 } 872 873 void ArtificialController::searchNewTarget() 874 { 875 if (!this->getControllableEntity()) 876 return; 877 878 this->targetPosition_ = this->getControllableEntity()->getPosition(); 879 this->forgetTarget(); 880 881 for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it) 882 { 883 if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype())) 884 continue; 885 886 /* So AI won't choose invisible Spaceships as target */ 887 if (!it->getRadarVisibility()) 888 continue; 889 890 if (static_cast<ControllableEntity*>(*it) != this->getControllableEntity()) 891 { 892 float speed = this->getControllableEntity()->getVelocity().length(); 893 Vector3 distanceCurrent = this->targetPosition_ - this->getControllableEntity()->getPosition(); 894 Vector3 distanceNew = it->getPosition() - this->getControllableEntity()->getPosition(); 895 if (!this->target_ || it->getPosition().squaredDistance(this->getControllableEntity()->getPosition()) * (1.5f + acos((this->getControllableEntity()->getOrientation() * WorldEntity::FRONT).dotProduct(distanceNew) / speed / distanceNew.length()) / math::twoPi) 896 < this->targetPosition_.squaredDistance(this->getControllableEntity()->getPosition()) * (1.5f + acos((this->getControllableEntity()->getOrientation() * WorldEntity::FRONT).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / math::twoPi) + rnd(-250, 250)) 897 { 898 this->target_ = (*it); 899 this->targetPosition_ = it->getPosition(); 900 } 901 } 902 } 903 } 904 905 void ArtificialController::forgetTarget() 906 { 907 this->target_ = 0; 908 this->bShooting_ = false; 909 } 74 } 75 910 76 911 77 void ArtificialController::aimAtTarget() … … 947 113 if (target == this->target_) 948 114 this->targetDied(); 949 }950 951 void ArtificialController::targetDied()952 {953 this->forgetTarget();954 this->searchRandomTargetPosition();955 }956 957 bool ArtificialController::sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)958 {959 if(!entity1 || !entity2)960 return true;961 if (entity1 == entity2)962 return true;963 964 int team1 = -1;965 int team2 = -1;966 967 Controller* controller = 0;968 if (entity1->getController())969 controller = entity1->getController();970 else971 controller = entity1->getXMLController();972 if (controller)973 {974 ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);975 if (ac)976 team1 = ac->getTeam();977 }978 979 if (entity2->getController())980 controller = entity2->getController();981 else982 controller = entity2->getXMLController();983 if (controller)984 {985 ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);986 if (ac)987 team2 = ac->getTeam();988 }989 990 TeamDeathmatch* tdm = orxonox_cast<TeamDeathmatch*>(gametype);991 if (tdm)992 {993 if (entity1->getPlayer())994 team1 = tdm->getTeam(entity1->getPlayer());995 996 if (entity2->getPlayer())997 team2 = tdm->getTeam(entity2->getPlayer());998 }999 1000 TeamBaseMatchBase* base = 0;1001 base = orxonox_cast<TeamBaseMatchBase*>(entity1);1002 if (base)1003 {1004 switch (base->getState())1005 {1006 case BaseState::ControlTeam1:1007 team1 = 0;1008 break;1009 case BaseState::ControlTeam2:1010 team1 = 1;1011 break;1012 case BaseState::Uncontrolled:1013 default:1014 team1 = -1;1015 }1016 }1017 base = orxonox_cast<TeamBaseMatchBase*>(entity2);1018 if (base)1019 {1020 switch (base->getState())1021 {1022 case BaseState::ControlTeam1:1023 team2 = 0;1024 break;1025 case BaseState::ControlTeam2:1026 team2 = 1;1027 break;1028 case BaseState::Uncontrolled:1029 default:1030 team2 = -1;1031 }1032 }1033 1034 DroneController* droneController = 0;1035 droneController = orxonox_cast<DroneController*>(entity1->getController());1036 if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)1037 return true;1038 droneController = orxonox_cast<DroneController*>(entity2->getController());1039 if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)1040 return true;1041 DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController());1042 DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController());1043 if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner())1044 return true;1045 1046 Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype);1047 if (dynamic)1048 {1049 if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;}1050 1051 if (entity1->getPlayer())1052 team1 = dynamic->getParty(entity1->getPlayer());1053 1054 if (entity2->getPlayer())1055 team2 = dynamic->getParty(entity2->getPlayer());1056 1057 if (team1 ==-1 ||team2 ==-1 ) {return false;}1058 else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;}1059 else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;}1060 else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;}1061 else return true;1062 }1063 1064 return (team1 == team2 && team1 != -1);1065 115 } 1066 116 … … 1110 160 { 1111 161 Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity()); 1112 if(pawn )162 if(pawn && pawn->isA(Class(SpaceShip))) //fix for First Person Mode: check for SpaceShip 1113 163 { 1114 164 this->weaponModes_.clear(); // reset previous weapon information … … 1217 267 1218 268 /** 1219 @brief Adds point of interest depending on context. Further Possibilites: "ForceField", "PortalEndPoint", "MovableEntity", "Dock"269 @brief Adds point of interest depending on context. TODO: Further Possibilites: "ForceField", "PortalEndPoint", "MovableEntity", "Dock" 1220 270 */ 1221 271 void ArtificialController::manageWaypoints() … … 1226 276 this->updatePointsOfInterest("PickupSpawner", 20.0f); // take pickup en passant if there is a default waypoint 1227 277 } 1228 278 1229 279 } -
code/trunk/src/orxonox/controllers/ArtificialController.h
r8891 r9016 31 31 32 32 #include "OrxonoxPrereqs.h" 33 #include "controllers/FormationController.h" 33 34 34 #include <map>35 36 #include "util/Math.h"37 #include "Controller.h"38 #include "controllers/NewHumanController.h"39 #include "weaponsystem/WeaponSystem.h"40 35 41 36 namespace orxonox 42 37 { 43 class _OrxonoxExport ArtificialController : public Controller38 class _OrxonoxExport ArtificialController : public FormationController 44 39 { 45 40 public: … … 47 42 virtual ~ArtificialController(); 48 43 49 virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);50 51 44 void abandonTarget(Pawn* target); 52 45 53 inline void setTeam(int team)54 { this->team_ = team; }55 inline int getTeam() const56 { return this->team_; }57 58 inline void setFormationFlight(bool formation)59 { this->formationFlight_ = formation; }60 inline bool getFormationFlight() const61 { return this->formationFlight_; }62 63 inline void setFormationSize(int size)64 { this->maxFormationSize_ = size; }65 inline int getFormationSize() const66 { return this->maxFormationSize_; }67 68 inline void setPassive(bool passive)69 { this->passive_ = passive; }70 inline bool getPassive() const71 { return this->passive_; }72 73 46 virtual void changedControllableEntity(); 74 75 static void formationflight(const bool form);76 static void masteraction(const int action);77 static void followme();78 static void passivebehaviour(const bool passive);79 static void formationsize(const int size);80 47 81 48 virtual void doFire(); … … 95 62 void manageWaypoints(); 96 63 64 65 97 66 protected: 98 99 int team_; 100 bool formationFlight_; 101 bool passive_; 102 unsigned int maxFormationSize_; 103 int freedomCount_; 104 enum State {SLAVE, MASTER, FREE}; 105 State state_; 106 std::vector<ArtificialController*> slaves_; 107 ArtificialController *myMaster_; 108 enum SpecificMasterAction {NONE, HOLD, SPIN, TURN180, FOLLOW}; 109 SpecificMasterAction specificMasterAction_; 110 int specificMasterActionHoldCount_; 111 float speedCounter_; //for speed adjustment when following 112 113 void moveToPosition(const Vector3& target); 114 void moveToTargetPosition(); 115 void absoluteMoveToPosition(const Vector3& target); 116 117 virtual void positionReached() {} 118 119 void removeFromFormation(); 120 void unregisterSlave(); 121 void searchNewMaster(); 122 void commandSlaves(); 123 void setNewMasterWithinFormation(); 124 125 void freeSlaves(); 126 void forceFreeSlaves(); 127 void loseMasterState(); 128 void forceFreedom(); 129 bool forcedFree(); 130 131 void specificMasterActionHold(); 132 void turn180Init(); 133 void turn180(); 134 void spinInit(); 135 void spin(); 136 void followInit(Pawn* pawn, const bool always = false, const int secondsToFollow = 100); 137 void followRandomHumanInit(); 138 void follow(); 139 void followForSlaves(const Vector3& target); 140 141 void setTargetPosition(const Vector3& target); 142 void searchRandomTargetPosition(); 143 144 void setTarget(Pawn* target); 145 void searchNewTarget(); 146 void forgetTarget(); 67 147 68 void aimAtTarget(); 148 69 149 70 bool isCloseAtTarget(float distance) const; 150 71 bool isLookingAtTarget(float angle) const; 151 152 void targetDied();153 154 static bool sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype); // hack155 void boostControl(); //<! Sets and resets the boost parameter of the spaceship. Bots alternate between boosting and saving boost.156 157 bool bHasTargetPosition_;158 Vector3 targetPosition_;159 WeakPtr<Pawn> target_;160 bool bShooting_;161 72 162 73 float botlevel_; //<! Makes the level of a bot configurable. … … 165 76 void setPreviousMode(); 166 77 78 167 79 //WEAPONSYSTEM DATA 168 std::map<std::string, int> weaponModes_; //<! Links each "weapon" to it's weaponmode - managed by setupWeapons()80 std::map<std::string, int> weaponModes_; //<! Links each "weapon" to it's weaponmode - managed by setupWeapons() 169 81 //std::vector<int> projectiles_; //<! Displays amount of projectiles of each weapon. - managed by setupWeapons() 170 82 float timeout_; //<! Timeout for rocket usage. (If a rocket misses, a bot should stop using it.) … … 173 85 int getFiremode(std::string name); 174 86 87 175 88 //WAYPOINT DATA 176 89 std::vector<WeakPtr<WorldEntity> > waypoints_; … … 178 91 float squaredaccuracy_; 179 92 WorldEntity* defaultWaypoint_; 93 94 void boostControl(); //<! Sets and resets the boost parameter of the spaceship. Bots alternate between boosting and saving boost. 95 96 private: 180 97 }; 181 98 } -
code/trunk/src/orxonox/controllers/CMakeLists.txt
r7163 r9016 9 9 WaypointPatrolController.cc 10 10 DroneController.cc 11 FormationController.cc 11 12 ) -
code/trunk/src/orxonox/controllers/HumanController.cc
r8858 r9016 50 50 SetConsoleCommand("HumanController", "rotatePitch", &HumanController::rotatePitch ).addShortcut().setAsInputCommand(); 51 51 SetConsoleCommand("HumanController", "rotateRoll", &HumanController::rotateRoll ).addShortcut().setAsInputCommand(); 52 SetConsoleCommand("HumanController", "toggleFormationFlight", &HumanController::toggleFormationFlight).addShortcut().keybindMode(KeybindMode::OnPress); 53 SetConsoleCommand("HumanController", "FFChangeMode", &HumanController::FFChangeMode).addShortcut().keybindMode(KeybindMode::OnPress); 52 54 SetConsoleCommand("HumanController", __CC_fire_name, &HumanController::fire ).addShortcut().keybindMode(KeybindMode::OnHold); 53 55 SetConsoleCommand("HumanController", "reload", &HumanController::reload ).addShortcut(); … … 69 71 /*static*/ const float HumanController::BOOSTING_TIME = 0.1f; 70 72 71 HumanController::HumanController(BaseObject* creator) : Controller(creator)73 HumanController::HumanController(BaseObject* creator) : FormationController(creator) 72 74 { 73 75 RegisterObject(HumanController); … … 76 78 this->boosting_ = false; 77 79 this->boosting_ = false; 78 79 80 HumanController::localController_s = this; 80 81 this->boostingTimeout_.setTimer(HumanController::BOOSTING_TIME, false, createExecutor(createFunctor(&HumanController::terminateBoosting, this))); … … 84 85 HumanController::~HumanController() 85 86 { 87 if (HumanController::localController_s) 88 { 89 HumanController::localController_s->removeFromFormation(); 90 } 86 91 HumanController::localController_s = 0; 87 92 } … … 95 100 orxout(internal_warning) << "HumanController, Warning: Using a ControllableEntity without Camera" << endl; 96 101 } 102 103 // commandslaves when Master of a formation 104 if (HumanController::localController_s && HumanController::localController_s->state_==MASTER) 105 { 106 if (HumanController::localController_s->formationMode_ != ATTACK) 107 HumanController::localController_s->commandSlaves(); 108 } 97 109 } 98 110 … … 160 172 { 161 173 if (HumanController::localController_s && HumanController::localController_s->controllableEntity_) 174 { 162 175 HumanController::localController_s->controllableEntity_->fire(firemode); 176 //if human fires, set slaves free. See FormationController::forceFreeSlaves() 177 if (HumanController::localController_s->state_==MASTER && HumanController::localController_s->formationMode_ == NORMAL) 178 { 179 HumanController::localController_s->forceFreeSlaves(); 180 } 181 } 163 182 } 164 183 … … 195 214 this->boosting_ = true; 196 215 this->boostingTimeout_.startTimer(); 197 198 this->controllableEntity_->boost(this->boosting_);216 if(this->controllableEntity_) 217 this->controllableEntity_->boost(this->boosting_); 199 218 // orxout() << "Start boosting" << endl; 200 219 } … … 209 228 this->boosting_ = false; 210 229 this->boostingTimeout_.stopTimer(); 211 212 this->controllableEntity_->boost(this->boosting_);230 if(this->controllableEntity_) 231 this->controllableEntity_->boost(this->boosting_); 213 232 // orxout() << "Stop boosting" << endl; 214 233 } … … 262 281 } 263 282 283 /** 284 @brief 285 toggle the formation. Not usable, if formationflight is disabled generally (formationFlight_) 286 */ 287 void HumanController::toggleFormationFlight() 288 { 289 if (HumanController::localController_s) 290 { 291 if (!HumanController::localController_s->formationFlight_) 292 { 293 return; //dont use when formationFlight is disabled 294 } 295 if (HumanController::localController_s->state_==MASTER) 296 { 297 HumanController::localController_s->loseMasterState(); 298 orxout(message) <<"FormationFlight disabled "<< endl; 299 } else //SLAVE or FREE 300 { 301 HumanController::localController_s->takeLeadOfFormation(); 302 orxout(message) <<"FormationFlight enabled "<< endl; 303 } 304 305 } 306 307 } 308 309 /** 310 @brief 311 Switch through the different Modes of formationflight. You must be a master of a formation to use. 312 */ 313 void HumanController::FFChangeMode() 314 { 315 if (HumanController::localController_s && HumanController::localController_s->state_==MASTER) 316 { 317 switch (HumanController::localController_s->getFormationMode()) { 318 case NORMAL: 319 HumanController::localController_s->setFormationMode(DEFEND); 320 orxout(message) <<"Mode: DEFEND "<< endl; 321 break; 322 case DEFEND: 323 HumanController::localController_s->setFormationMode(ATTACK); 324 orxout(message) <<"Mode: ATTACK "<< endl; 325 break; 326 case ATTACK: 327 HumanController::localController_s->setFormationMode(NORMAL); 328 orxout(message) <<"Mode: NORMAL "<< endl; 329 break; 330 } 331 } 332 } 333 334 335 //used, when slaves are in DEFEND mode. 336 void HumanController::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage) 337 { 338 if (!this->formationFlight_ || this->state_!=MASTER || this->formationMode_!=DEFEND) return; 339 this->masterAttacked(originator); 340 } 341 264 342 void HumanController::addBots(unsigned int amount) 265 343 { -
code/trunk/src/orxonox/controllers/HumanController.h
r8706 r9016 34 34 #include "tools/Timer.h" 35 35 #include "tools/interfaces/Tickable.h" 36 #include " Controller.h"36 #include "FormationController.h" 37 37 38 38 // tolua_begin … … 41 41 class _OrxonoxExport HumanController 42 42 // tolua_end 43 : public Controller, public Tickable43 : public FormationController, public Tickable 44 44 { // tolua_export 45 45 public: … … 74 74 void keepBoosting(void); 75 75 void terminateBoosting(void); 76 76 77 77 78 static void greet(); 78 79 static void switchCamera(); … … 84 85 static void toggleGodMode(); 85 86 static void myposition(); 87 88 static void toggleFormationFlight(); 89 static void FFChangeMode(); 90 virtual void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage); 91 86 92 87 93 static void addBots(unsigned int amount); -
code/trunk/src/orxonox/controllers/NewHumanController.cc
r8858 r9016 291 291 } 292 292 else 293 HumanController::localController_s->getControllableEntity()->fire(firemode); 294 293 HumanController::doFire(firemode); //call for formationflight 295 294 } 296 295 297 296 void NewHumanController::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage) 298 297 { 298 //Used in HumanController for formationFlight 299 HumanController::hit(originator,contactpoint,damage); 300 299 301 if (this->showDamageOverlay_ && !this->controlPaused_ && this->controllableEntity_ && !this->controllableEntity_->isInMouseLook()) 300 302 { -
code/trunk/src/orxonox/controllers/NewHumanController.h
r7859 r9016 69 69 virtual void doResumeControl(); 70 70 71 float getCurrentYaw(){ return this->currentYaw_; } 72 float getCurrentPitch(){ return this->currentPitch_; } 73 71 74 72 75 protected: -
code/trunk/src/orxonox/controllers/WaypointPatrolController.cc
r7184 r9016 42 42 RegisterObject(WaypointPatrolController); 43 43 44 //this->team_ = 0;45 44 this->alertnessradius_ = 500; 46 45 … … 53 52 54 53 XMLPortParam(WaypointPatrolController, "alertnessradius", setAlertnessRadius, getAlertnessRadius, xmlelement, mode).defaultValues(500.0f); 55 // XMLPortParam(WaypointPatrolController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(0);56 54 } 57 55 -
code/trunk/src/orxonox/controllers/WaypointPatrolController.h
r7163 r9016 46 46 virtual void tick(float dt); 47 47 48 /* inline void setTeam(int team)49 { this->team_ = team; }50 inline int getTeam() const51 { return this->team_; } */52 53 48 inline void setAlertnessRadius(float radius) 54 49 { this->alertnessradius_ = radius; } … … 59 54 void searchEnemy(); 60 55 61 //int team_;62 56 float alertnessradius_; 63 57 Timer patrolTimer_;
Note: See TracChangeset
for help on using the changeset viewer.