- Timestamp:
- Nov 28, 2015, 10:30:56 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/campaignHS15/src/orxonox/controllers/FightingController.cc
r10883 r10885 21 21 * 22 22 * Author: 23 * Fabian 'x3n' Landau23 * Gani Aliguzhinov 24 24 * Co-authors: 25 * Dominik Solenicki25 * Fabian 'x3n' Landau, Dominik Solenicki 26 26 * 27 27 */ … … 31 31 32 32 33 #include "worldentities/pawns/SpaceShip.h" 34 35 #include "weaponsystem/WeaponMode.h" 36 #include "weaponsystem/WeaponPack.h" 37 #include "weaponsystem/Weapon.h" 38 #include "weaponsystem/WeaponSlot.h" 39 #include "weaponsystem/WeaponSlot.h" 33 40 namespace orxonox 34 41 { … … 38 45 FightingController::FightingController( Context* context ): FlyingController( context ) 39 46 { 40 this->attackRange_ = 2000;47 this->attackRange_ = 3000; 41 48 this->stopLookingAtTarget(); 42 49 this->bSetupWorked = false; 50 this->timeout_ = 0; 43 51 RegisterObject( FightingController ); 44 52 } … … 78 86 this->bLookAtTarget_ = true; 79 87 } 80 bool FightingController::hasTarget() 88 bool FightingController::hasTarget() const 81 89 { 82 90 if ( this->target_ ) … … 106 114 void FightingController::maneuver() 107 115 { 116 if ( !this->target_ || !this->getControllableEntity()) 117 return; 108 118 maneuverCounter_++; 109 119 if (maneuverCounter_ > 5) 110 120 maneuverCounter_ = 0; 111 121 112 if ( !this->target_ || !this->getControllableEntity())113 return;114 115 122 Vector3 thisPosition = this->getControllableEntity()->getWorldPosition(); 116 this->setPositionOfTarget( getPredictedPosition( 117 thisPosition, 118 hardcoded_projectile_speed, 119 this->target_->getWorldPosition() , 120 this->target_->getVelocity() 121 ) ); 122 this->setOrientationOfTarget( this->target_->getOrientation() ); 123 123 this->setPositionOfTarget(this->target_->getWorldPosition()); 124 //this->setOrientationOfTarget(this->target_->getOrientation()); 124 125 Vector3 diffVector = this->positionOfTarget_ - thisPosition; 125 126 float diffLength = diffVector.length(); 126 127 Vector3 diffUnit = diffVector/diffLength; 127 128 bool bTargetIsLookingAtThis = CommonController::isLooking ( this->target_, getControllableEntity(), math::pi/20.0f ); 128 bool bTargetIsLookingAtThis = CommonController::isLooking (this->target_, this->getControllableEntity(), math::pi/20.0f); 129 129 130 130 //too far? well, come closer then … … 135 135 this->bKeepFormation_ = true; 136 136 137 this->setTargetPosition( this->positionOfTarget_);137 this->setTargetPosition(this->positionOfTarget_ - diffUnit * 200.0f); 138 138 } 139 139 //too close? How do u expect to dodge anything? Just attack! 140 else if ( diffLength < 500)140 else if (diffLength < 500) 141 141 { 142 142 this->bKeepFormation_ = false; 143 143 144 144 //at this point, just look and shoot 145 if ( diffLength < 250)145 if (diffLength < 250) 146 146 { 147 147 this->stopMoving(); … … 150 150 else 151 151 { 152 this->setTargetPosition( this->positionOfTarget_);152 this->setTargetPosition(this->positionOfTarget_ - diffUnit * 200.0f); 153 153 } 154 154 } 155 155 //Good distance? Check if target looks at us. It doesn't? Go hunt! 156 else if ( !bTargetIsLookingAtThis)156 else if (!bTargetIsLookingAtThis) 157 157 { 158 158 this->bKeepFormation_ = false; 159 this->setTargetPosition( this->positionOfTarget_);159 this->setTargetPosition(this->positionOfTarget_ - diffUnit * 200.0f); 160 160 } 161 161 //That's unfortunate, he is looking and probably shooting... try to dodge what we can... … … 165 165 if (maneuverCounter_ == 0) 166 166 { 167 this->setTargetPosition( this->positionOfTarget_);167 this->setTargetPosition(this->positionOfTarget_ - diffUnit * 200.0f); 168 168 return; 169 169 } 170 dodge( thisPosition, diffUnit);170 dodge(thisPosition, diffUnit); 171 171 } 172 172 } 173 173 174 void FightingController::dodge(Vector3& thisPosition, Vector3& diffUnit) 175 { 176 float factorX = 0, factorY = 0, factorZ = 0; 177 float rand = CommonController::randomInRange (0, 1); 178 179 if (rand <= 0.5) 180 { factorX = 1; } 174 void FightingController::dodge(const Vector3& thisPosition, Vector3& diffUnit) 175 { 176 //d.x*x + d.y*y + d.z*z == 0 177 //z = 1/d.z * (-d.y*y - d.x * x) 178 float x = CommonController::randomInRange (1000, 10000) * (CommonController::randomInRange(0,1) <= 0.5 ? 1 : -1); 179 float y = CommonController::randomInRange (1000, 10000) * (CommonController::randomInRange(0,1) <= 0.5 ? 1 : -1); 180 float z = (1/diffUnit.z) * (-x * diffUnit.x - y * diffUnit.y); 181 this->setTargetPosition(thisPosition + Vector3(x,y,z) + diffUnit * 1000.0f); 182 this->boostControl(); 183 184 } 185 bool FightingController::canFire() 186 { 187 //no target? why fire? 188 if (!this->target_) 189 return false; 190 Vector3 newPositionOfTarget = getPredictedPosition(this->getControllableEntity()->getWorldPosition(), 191 hardcoded_projectile_speed, this->target_->getWorldPosition(), 192 this->target_->getVelocity()); 193 if (!newPositionOfTarget.isNaN()) 194 { 195 this->setPositionOfTarget(newPositionOfTarget); 196 } 197 return squaredDistanceToTarget() < this->attackRange_*this->attackRange_ && this->isLookingAtTarget(math::pi / 20.0f); 198 } 199 // void FightingController::doFire() 200 // { 201 // if ( !this->target_ || !this->getControllableEntity() ) 202 // { 203 // return; 204 // } 205 206 // Pawn* pawn = orxonox_cast<Pawn*>( this->getControllableEntity() ); 207 208 // if ( pawn ) 209 // pawn->setAimPosition( this->positionOfTarget_ ); 210 // float distance = CommonController::distance (this->getControllableEntity(), this->target_); 211 // this->getControllableEntity() ->fire(distance < 1500 ? (distance < 1000 && distance > 700 ? 3 : 0) : (1)); 212 // } 213 214 215 float FightingController::squaredDistanceToTarget() const 216 { 217 if (!this->getControllableEntity()) 218 return 0; 219 if (!this->target_ || !this->getControllableEntity()) 220 return (this->getControllableEntity()->getPosition().squaredDistance(this->targetPosition_)); 181 221 else 182 { factorX = -1; } 183 rand = CommonController::randomInRange (0, 1); 184 if (rand <= 0.5) 185 { factorY = 1; } 186 else 187 { factorY = -1; } 188 rand = CommonController::randomInRange (0, 1); 189 if (rand <= 0.5) 190 { factorZ = 1; } 191 else 192 { factorZ = -1; } 193 194 Vector3 target = ( diffUnit )* 8000.0f; 195 Vector3* randVector = new Vector3( 196 factorX * CommonController::randomInRange( 10000, 40000 ), 197 factorY * CommonController::randomInRange( 10000, 40000 ), 198 factorZ * CommonController::randomInRange( 10000, 40000 ) 199 ); 200 Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit; 201 Vector3 randV = *randVector; 202 delete randVector; 203 randV -= projection; 204 target += randV; 205 this->setTargetPosition( thisPosition + target ); 206 } 207 bool FightingController::canFire() 208 { 209 //no target? why fire? 210 if ( !this->target_ ) 211 return false; 212 213 Vector3 newPositionOfTarget = getPredictedPosition( this->getControllableEntity() ->getWorldPosition() , 214 hardcoded_projectile_speed, this->target_->getWorldPosition() , this->target_->getVelocity() ); 215 if ( newPositionOfTarget != Vector3::ZERO ) 216 { 217 this->setPositionOfTarget( newPositionOfTarget ); 218 } 219 220 float squaredDistance = squaredDistanceToTarget(); 221 222 if ( squaredDistance < this->attackRange_*this->attackRange_ && this->isLookingAtTarget( math::pi / 20.0f)) 223 { 224 return true; 225 } 226 else 227 { 228 return false; 229 } 230 } 231 void FightingController::doFire() 232 { 233 if ( !this->target_ || !this->getControllableEntity() ) 234 { 235 return; 236 } 237 238 Pawn* pawn = orxonox_cast<Pawn*>( this->getControllableEntity() ); 239 240 if ( pawn ) 241 pawn->setAimPosition( this->positionOfTarget_ ); 242 this->getControllableEntity() ->fire( 0 ); 243 } 244 float FightingController::squaredDistanceToTarget() const 245 { 246 if ( !this->getControllableEntity() ) 247 return 0; 248 if ( !this->target_ || !this->getControllableEntity() ) 249 return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->targetPosition_ ) ); 250 else 251 return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->positionOfTarget_ ) ); 252 } 253 bool FightingController::isLookingAtTarget( float angle ) 222 return (this->getControllableEntity()->getPosition().squaredDistance(this->positionOfTarget_)); 223 } 224 bool FightingController::isLookingAtTarget( float angle ) const 254 225 { 255 226 if ( !this->getControllableEntity() || !this->target_ ) … … 257 228 return CommonController::isLooking(this->getControllableEntity(), this->getTarget(), angle); 258 229 } 259 230 void FightingController::setClosestTarget() 260 231 { 261 232 this->setTarget (static_cast<ControllableEntity*>( closestTarget() ) ); 262 233 } 263 234 264 Pawn* FightingController::closestTarget() 235 Pawn* FightingController::closestTarget() const 265 236 { 266 237 if (!this->getControllableEntity()) … … 288 259 return 0; 289 260 } 261 //I checked it out, rockets DO NOT cause any problems! this->getControllableEntity() is always a SpaceShip 262 void FightingController::doFire() 263 { 264 if (!this->bSetupWorked) 265 { 266 this->setupWeapons(); 267 } 268 if (!this->target_ || !this->getControllableEntity()) 269 { 270 return; 271 } 272 Pawn* pawn = orxonox_cast<Pawn*> (this->getControllableEntity()); 273 if (pawn) 274 pawn->setAimPosition (this->positionOfTarget_); 275 276 int firemode; 277 float distance = CommonController::distance (this->getControllableEntity(), this->target_); 278 279 // firemode = distance < 1500 ? (distance > 800 && distance < 1200 ? 280 // (this->rocketsLeft_ > 0 && !this->bFiredRocket_ ? getFiremode("RocketFire") : getFiremode ("HsW01")) 281 // : getFiremode("HsW01")) : 282 // (distance < 2500 ? getFiremode("LightningGun") : getFiremode("HsW01")); 283 if (distance < 800) 284 { 285 if (this->rocketsLeft_ > 0) 286 { 287 firemode = getFiremode ("SimpleRocketFire"); 288 } 289 else 290 { 291 if (distance > 450) 292 firemode = getFiremode ("LightningGun"); 293 else 294 firemode = getFiremode ("HsW01"); 295 } 296 297 } 298 else if (distance < 1200) 299 { 300 if (this->rocketsLeft_ > 0 && !this->bFiredRocket_) 301 { 302 firemode = getFiremode ("RocketFire"); 303 } 304 else 305 { 306 firemode = getFiremode ("HsW01"); 307 } 308 } 309 else if (distance < 1500) 310 { 311 firemode = getFiremode ("LightningGun"); 312 } 313 else 314 { 315 firemode = getFiremode ("HsW01"); 316 } 317 if (firemode < 0) 318 { 319 firemode = getFiremode ("HsW01"); 320 } 321 if (firemode == getFiremode("RocketFire")) 322 { 323 this->timeout_ = 1.0f; 324 this->rocketsLeft_--; 325 this->bFiredRocket_ = true; 326 } 327 if (firemode == getFiremode("SimpleRocketFire")) 328 { 329 this->rocketsLeft_--; 330 } 331 332 this->getControllableEntity()->fire(firemode); 333 334 } 335 void FightingController::setupWeapons() //TODO: Make this function generic!! (at the moment is is based on conventions) 336 { 337 this->bSetupWorked = false; 338 if(this->getControllableEntity()) 339 { 340 Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity()); 341 if(pawn && pawn->isA(Class(SpaceShip))) //fix for First Person Mode: check for SpaceShip 342 { 343 this->weaponModes_.clear(); // reset previous weapon information 344 WeaponSlot* wSlot = 0; 345 for(int l=0; (wSlot = pawn->getWeaponSlot(l)) ; l++) 346 { 347 WeaponMode* wMode = 0; 348 for(int i=0; (wMode = wSlot->getWeapon()->getWeaponmode(i)) ; i++) 349 { 350 std::string wName = wMode->getIdentifier()->getName(); 351 if (wName == "RocketFire") 352 this->rocketsLeft_ = 10; 353 if(this->getFiremode(wName) == -1) //only add a weapon, if it is "new" 354 weaponModes_[wName] = wMode->getMode(); 355 } 356 } 357 if(weaponModes_.size())//at least one weapon detected 358 this->bSetupWorked = true; 359 }//pawn->weaponSystem_->getMunition(SubclassIdentifier< Munition > *identifier)->getNumMunition (WeaponMode *user); 360 } 361 } 362 363 int FightingController::getFiremode(std::string name) 364 { 365 for (std::map< std::string, int >::iterator it = this->weaponModes_.begin(); it != this->weaponModes_.end(); ++it) 366 { 367 if (it->first == name) 368 return it->second; 369 } 370 return -1; 371 } 290 372 }
Note: See TracChangeset
for help on using the changeset viewer.