- Timestamp:
- Dec 14, 2011, 7:13:09 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/formation/src/orxonox/controllers/ArtificialController.cc
r8978 r8989 24 24 * Co-authors: 25 25 * Dominik Solenicki 26 * 26 * 27 27 */ 28 28 … … 95 95 this->targetDied(); 96 96 } 97 98 //****************************************************************************************** NEW 99 /** 100 @brief DoFire is called when a bot should shoot and decides which weapon is used and whether the bot shoots at all. 101 */ 102 void ArtificialController::doFire() 103 { 104 if(!this->bSetupWorked)//setup: find out which weapons are active ! hard coded: laser is "0", lens flare is "1", ... 105 { 106 this->setupWeapons(); 107 } 108 else if(this->getControllableEntity() && weaponModes_.size()&&this->bShooting_ && this->isCloseAtTarget((1 + 2*botlevel_)*1000) && this->isLookingAtTarget(math::pi / 20.0f)) 109 { 110 int firemode; 111 float random = rnd(1);// 112 if (this->isCloseAtTarget(130) && (firemode = getFiremode("LightningGun")) > -1 ) 113 {//LENSFLARE: short range weapon 114 this->getControllableEntity()->fire(firemode); //ai uses lens flare if they're close enough to the target 115 } 116 else if( this->isCloseAtTarget(400) && (random < this->botlevel_) && (firemode = getFiremode("RocketFire")) > -1 ) 117 {//ROCKET: mid range weapon 118 this->mode_ = ROCKET; //Vector-implementation: mode_.push_back(ROCKET); 119 this->getControllableEntity()->fire(firemode); //launch rocket 120 if(this->getControllableEntity() && this->target_) //after fire(3) is called, getControllableEntity() refers to the rocket! 121 { 122 float speed = this->getControllableEntity()->getVelocity().length() - target_->getVelocity().length(); 123 if(!speed) speed = 0.1f; 124 float distance = target_->getPosition().length() - this->getControllableEntity()->getPosition().length(); 125 this->timeout_= distance/speed*sgn(speed*distance) + 1.8f; //predicted time of target hit (+ tolerance) 126 } 127 else 128 this->timeout_ = 4.0f; //TODO: find better default value 129 } 130 else if ((firemode = getFiremode("HsW01")) > -1 ) //LASER: default weapon 131 this->getControllableEntity()->fire(firemode); 132 } 133 } 134 135 /** 136 @brief Information gathering: Which weapons are ready to use? 137 */ 138 void ArtificialController::setupWeapons() //TODO: Make this function generic!! (at the moment is is based on conventions) 139 { 140 this->bSetupWorked = false; 141 if(this->getControllableEntity()) 142 { 143 Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity()); 144 if(pawn && pawn->isA(Class(SpaceShip))) //fix for First Person Mode: check for SpaceShip 145 { 146 this->weaponModes_.clear(); // reset previous weapon information 147 WeaponSlot* wSlot = 0; 148 for(int l=0; (wSlot = pawn->getWeaponSlot(l)) ; l++) 149 { 150 WeaponMode* wMode = 0; 151 for(int i=0; (wMode = wSlot->getWeapon()->getWeaponmode(i)) ; i++) 152 { 153 std::string wName = wMode->getIdentifier()->getName(); 154 if(this->getFiremode(wName) == -1) //only add a weapon, if it is "new" 155 weaponModes_[wName] = wMode->getMode(); 156 } 157 } 158 if(weaponModes_.size())//at least one weapon detected 159 this->bSetupWorked = true; 160 }//pawn->weaponSystem_->getMunition(SubclassIdentifier< Munition > *identifier)->getNumMunition (WeaponMode *user); 161 } 162 } 163 164 165 void ArtificialController::setBotLevel(float level) 166 { 167 if (level < 0.0f) 168 this->botlevel_ = 0.0f; 169 else if (level > 1.0f) 170 this->botlevel_ = 1.0f; 171 else 172 this->botlevel_ = level; 173 } 174 175 void ArtificialController::setAllBotLevel(float level) 176 { 177 for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it != ObjectList<ArtificialController>::end(); ++it) 178 it->setBotLevel(level); 179 } 180 181 void ArtificialController::setPreviousMode() 182 { 183 this->mode_ = DEFAULT; //Vector-implementation: mode_.pop_back(); 184 } 185 186 /** 187 @brief Manages boost. Switches between boost usage and boost safe mode. 188 */ 189 void ArtificialController::boostControl() 190 { 191 SpaceShip* ship = orxonox_cast<SpaceShip*>(this->getControllableEntity()); 192 if(ship == NULL) return; 193 if(ship->getBoostPower()*1.5f > ship->getInitialBoostPower() ) //upper limit ->boost 194 this->getControllableEntity()->boost(true); 195 else if(ship->getBoostPower()*4.0f < ship->getInitialBoostPower()) //lower limit ->do not boost 196 this->getControllableEntity()->boost(false); 197 } 198 199 int ArtificialController::getFiremode(std::string name) 200 { 201 for (std::map< std::string, int >::iterator it = this->weaponModes_.begin(); it != this->weaponModes_.end(); ++it) 202 { 203 if (it->first == name) 204 return it->second; 205 } 206 return -1; 207 } 208 209 void ArtificialController::addWaypoint(WorldEntity* waypoint) 210 { 211 this->waypoints_.push_back(waypoint); 212 } 213 214 WorldEntity* ArtificialController::getWaypoint(unsigned int index) const 215 { 216 if (index < this->waypoints_.size()) 217 return this->waypoints_[index]; 218 else 219 return 0; 220 } 221 222 /** 223 @brief Adds first waypoint of type name to the waypoint stack, which is within the searchDistance 224 @param name object-name of a point of interest (e.g. "PickupSpawner", "ForceField") 225 */ 226 void ArtificialController::updatePointsOfInterest(std::string name, float searchDistance) 227 { 228 WorldEntity* waypoint = NULL; 229 for (ObjectList<WorldEntity>::iterator it = ObjectList<WorldEntity>::begin(); it != ObjectList<WorldEntity>::end(); ++it) 230 { 231 if((*it)->getIdentifier() == ClassByString(name)) 232 { 233 ControllableEntity* controllable = this->getControllableEntity(); 234 if(!controllable) continue; 235 float actualDistance = ( (*it)->getPosition() - controllable->getPosition() ).length(); 236 if(actualDistance > searchDistance || actualDistance < 5.0f) continue; 237 // TODO: PickupSpawner: adjust waypoint accuracy to PickupSpawner's triggerdistance 238 // TODO: ForceField: analyze is angle between forcefield boost and own flying direction is acceptable 239 else 240 { 241 waypoint = *it; 242 break; 243 } 244 } 245 } 246 if(waypoint) 247 this->waypoints_.push_back(waypoint); 248 } 249 250 /** 251 @brief Adds point of interest depending on context. Further Possibilites: "ForceField", "PortalEndPoint", "MovableEntity", "Dock" 252 */ 253 void ArtificialController::manageWaypoints() 254 { 255 if(!defaultWaypoint_) 256 this->updatePointsOfInterest("PickupSpawner", 200.0f); // long search radius if there is no default goal 257 else 258 this->updatePointsOfInterest("PickupSpawner", 20.0f); // take pickup en passant if there is a default waypoint 259 } 97 260 98 261 }
Note: See TracChangeset
for help on using the changeset viewer.