- Timestamp:
- Oct 12, 2011, 7:50:43 PM (14 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
-
code/trunk/src/orxonox/controllers/ArtificialController.cc
r8858 r8891 39 39 #include "worldentities/pawns/Pawn.h" 40 40 #include "worldentities/pawns/TeamBaseMatchBase.h" 41 #include "worldentities/pawns/SpaceShip.h" 41 42 #include "gametypes/TeamDeathmatch.h" 42 43 #include "gametypes/Dynamicmatch.h" … … 44 45 #include "controllers/NewHumanController.h" 45 46 #include "controllers/DroneController.h" 47 #include "weaponsystem/WeaponMode.h" 48 #include "weaponsystem/WeaponPack.h" 49 #include "weaponsystem/Weapon.h" 50 #include "weaponsystem/WeaponSlot.h" 51 #include "weaponsystem/WeaponSlot.h" 46 52 47 53 namespace orxonox … … 52 58 SetConsoleCommand("ArtificialController", "passivebehaviour", &ArtificialController::passivebehaviour); 53 59 SetConsoleCommand("ArtificialController", "formationsize", &ArtificialController::formationsize); 60 SetConsoleCommand("ArtificialController", "setbotlevel", &ArtificialController::setAllBotLevel); 54 61 55 62 static const unsigned int STANDARD_MAX_FORMATION_SIZE = 7; … … 84 91 85 92 this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this)); 93 this->bSetupWorked = false; 94 this->botlevel_ = 0.5f; 95 this->mode_ = DEFAULT;////Vector-implementation: mode_.push_back(DEFAULT); 96 this->timeout_ = 0; 97 this->currentWaypoint_ = 0; 98 this->setAccuracy(5); 99 this->defaultWaypoint_ = NULL; 86 100 } 87 101 … … 89 103 { 90 104 if (this->isInitialized()) 91 { 105 {//Vector-implementation: mode_.erase(mode_.begin(),mode_.end()); 106 this->waypoints_.clear(); 92 107 this->removeFromFormation(); 93 108 this->weaponModes_.clear(); 94 109 for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it; ++it) 95 110 { … … 305 320 if (!this->getControllableEntity()) 306 321 this->removeFromFormation(); 322 this->bSetupWorked = false; // reset weapon information 323 this->setupWeapons(); 307 324 } 308 325 … … 387 404 } 388 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 389 431 390 432 void ArtificialController::moveToTargetPosition() … … 915 957 bool ArtificialController::sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype) 916 958 { 959 if(!entity1 || !entity2) 960 return true; 917 961 if (entity1 == entity2) 918 962 return true; … … 1020 1064 return (team1 == team2 && team1 != -1); 1021 1065 } 1066 1067 /** 1068 @brief DoFire is called when a bot should shoot and decides which weapon is used and whether the bot shoots at all. 1069 */ 1070 void ArtificialController::doFire() 1071 { 1072 if(!this->bSetupWorked)//setup: find out which weapons are active ! hard coded: laser is "0", lens flare is "1", ... 1073 { 1074 this->setupWeapons(); 1075 } 1076 else if(this->getControllableEntity() && weaponModes_.size()&&this->bShooting_ && this->isCloseAtTarget((1 + 2*botlevel_)*1000) && this->isLookingAtTarget(math::pi / 20.0f)) 1077 { 1078 int firemode; 1079 float random = rnd(1);// 1080 if (this->isCloseAtTarget(130) && (firemode = getFiremode("LightningGun")) > -1 ) 1081 {//LENSFLARE: short range weapon 1082 this->getControllableEntity()->fire(firemode); //ai uses lens flare if they're close enough to the target 1083 } 1084 else if( this->isCloseAtTarget(400) && (random < this->botlevel_) && (firemode = getFiremode("RocketFire")) > -1 ) 1085 {//ROCKET: mid range weapon 1086 this->mode_ = ROCKET; //Vector-implementation: mode_.push_back(ROCKET); 1087 this->getControllableEntity()->fire(firemode); //launch rocket 1088 if(this->getControllableEntity() && this->target_) //after fire(3) is called, getControllableEntity() refers to the rocket! 1089 { 1090 float speed = this->getControllableEntity()->getVelocity().length() - target_->getVelocity().length(); 1091 if(!speed) speed = 0.1f; 1092 float distance = target_->getPosition().length() - this->getControllableEntity()->getPosition().length(); 1093 this->timeout_= distance/speed*sgn(speed*distance) + 1.8f; //predicted time of target hit (+ tolerance) 1094 } 1095 else 1096 this->timeout_ = 4.0f; //TODO: find better default value 1097 } 1098 else if ((firemode = getFiremode("HsW01")) > -1 ) //LASER: default weapon 1099 this->getControllableEntity()->fire(firemode); 1100 } 1101 } 1102 1103 /** 1104 @brief Information gathering: Which weapons are ready to use? 1105 */ 1106 void ArtificialController::setupWeapons() //TODO: Make this function generic!! (at the moment is is based on conventions) 1107 { 1108 this->bSetupWorked = false; 1109 if(this->getControllableEntity()) 1110 { 1111 Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity()); 1112 if(pawn) 1113 { 1114 this->weaponModes_.clear(); // reset previous weapon information 1115 WeaponSlot* wSlot = 0; 1116 for(int l=0; (wSlot = pawn->getWeaponSlot(l)) ; l++) 1117 { 1118 WeaponMode* wMode = 0; 1119 for(int i=0; (wMode = wSlot->getWeapon()->getWeaponmode(i)) ; i++) 1120 { 1121 std::string wName = wMode->getIdentifier()->getName(); 1122 if(this->getFiremode(wName) == -1) //only add a weapon, if it is "new" 1123 weaponModes_[wName] = wMode->getMode(); 1124 } 1125 } 1126 if(weaponModes_.size())//at least one weapon detected 1127 this->bSetupWorked = true; 1128 }//pawn->weaponSystem_->getMunition(SubclassIdentifier< Munition > *identifier)->getNumMunition (WeaponMode *user); 1129 } 1130 } 1131 1132 1133 void ArtificialController::setBotLevel(float level) 1134 { 1135 if (level < 0.0f) 1136 this->botlevel_ = 0.0f; 1137 else if (level > 1.0f) 1138 this->botlevel_ = 1.0f; 1139 else 1140 this->botlevel_ = level; 1141 } 1142 1143 void ArtificialController::setAllBotLevel(float level) 1144 { 1145 for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it != ObjectList<ArtificialController>::end(); ++it) 1146 it->setBotLevel(level); 1147 } 1148 1149 void ArtificialController::setPreviousMode() 1150 { 1151 this->mode_ = DEFAULT; //Vector-implementation: mode_.pop_back(); 1152 } 1153 1154 /** 1155 @brief Manages boost. Switches between boost usage and boost safe mode. 1156 */ 1157 void ArtificialController::boostControl() 1158 { 1159 SpaceShip* ship = orxonox_cast<SpaceShip*>(this->getControllableEntity()); 1160 if(ship == NULL) return; 1161 if(ship->getBoostPower()*1.5f > ship->getInitialBoostPower() ) //upper limit ->boost 1162 this->getControllableEntity()->boost(true); 1163 else if(ship->getBoostPower()*4.0f < ship->getInitialBoostPower()) //lower limit ->do not boost 1164 this->getControllableEntity()->boost(false); 1165 } 1166 1167 int ArtificialController::getFiremode(std::string name) 1168 { 1169 for (std::map< std::string, int >::iterator it = this->weaponModes_.begin(); it != this->weaponModes_.end(); ++it) 1170 { 1171 if (it->first == name) 1172 return it->second; 1173 } 1174 return -1; 1175 } 1176 1177 void ArtificialController::addWaypoint(WorldEntity* waypoint) 1178 { 1179 this->waypoints_.push_back(waypoint); 1180 } 1181 1182 WorldEntity* ArtificialController::getWaypoint(unsigned int index) const 1183 { 1184 if (index < this->waypoints_.size()) 1185 return this->waypoints_[index]; 1186 else 1187 return 0; 1188 } 1189 1190 /** 1191 @brief Adds first waypoint of type name to the waypoint stack, which is within the searchDistance 1192 @param name object-name of a point of interest (e.g. "PickupSpawner", "ForceField") 1193 */ 1194 void ArtificialController::updatePointsOfInterest(std::string name, float searchDistance) 1195 { 1196 WorldEntity* waypoint = NULL; 1197 for (ObjectList<WorldEntity>::iterator it = ObjectList<WorldEntity>::begin(); it != ObjectList<WorldEntity>::end(); ++it) 1198 { 1199 if((*it)->getIdentifier() == ClassByString(name)) 1200 { 1201 ControllableEntity* controllable = this->getControllableEntity(); 1202 if(!controllable) continue; 1203 float actualDistance = ( (*it)->getPosition() - controllable->getPosition() ).length(); 1204 if(actualDistance > searchDistance || actualDistance < 5.0f) continue; 1205 // TODO: PickupSpawner: adjust waypoint accuracy to PickupSpawner's triggerdistance 1206 // TODO: ForceField: analyze is angle between forcefield boost and own flying direction is acceptable 1207 else 1208 { 1209 waypoint = *it; 1210 break; 1211 } 1212 } 1213 } 1214 if(waypoint) 1215 this->waypoints_.push_back(waypoint); 1216 } 1217 1218 /** 1219 @brief Adds point of interest depending on context. Further Possibilites: "ForceField", "PortalEndPoint", "MovableEntity", "Dock" 1220 */ 1221 void ArtificialController::manageWaypoints() 1222 { 1223 if(!defaultWaypoint_) 1224 this->updatePointsOfInterest("PickupSpawner", 200.0f); // long search radius if there is no default goal 1225 else 1226 this->updatePointsOfInterest("PickupSpawner", 20.0f); // take pickup en passant if there is a default waypoint 1227 } 1228 1022 1229 }
Note: See TracChangeset
for help on using the changeset viewer.