Exemplo n.º 1
0
/**\brief Update the Projectile
 *
 * Projectiles do all the normal Sprite things like moving.
 * Projectiles check for collisions with nearby Ships, and if they collide,
 * they deal damage to that ship. Note that since each projectile knows which ship fired it and will never collide with them.
 *
 * Projectiles have a life time limit (in milli-seconds).  Each tick they need
 * to check if they've lived to long and need to disappear.
 *
 * Projectiles have the ability to track down a specific target.  This only
 * means that they will turn slightly to head towards their target.
 */
void Projectile::Update( void ) {
	Sprite::Update(); // update momentum and other generic sprite attributes
	SpriteManager *sprites = SpriteManager::Instance();

	// Check for projectile collisions
	Sprite* impact = sprites->GetNearestSprite( (Sprite*)this, 100,DRAW_ORDER_SHIP|DRAW_ORDER_PLAYER );
	if( (impact != NULL) && (impact->GetID() != ownerID) && ((this->GetWorldPosition() - impact->GetWorldPosition()).GetMagnitude() < impact->GetRadarSize() )) {
		((Ship*)impact)->Damage( (weapon->GetPayload())*damageBoost );
		sprites->Delete( (Sprite*)this );
		
		// Create a fire burst where this projectile hit the ship's shields.
		// TODO: This shows how much we need to improve our collision detection.
		Effect* hit = new Effect(this->GetWorldPosition(), "Resources/Animations/shield.ani", 0);
		hit->SetAngle( -this->GetAngle() );
		hit->SetMomentum( impact->GetMomentum() );
		sprites->Add( hit );
	}

	// Expire the projectile after a time period
	if (( Timer::GetTicks() > secondsOfLife + start )) {
		sprites->Delete( (Sprite*)this );
	}

	// Track the target
	Sprite* target = sprites->GetSpriteByID( targetID );
	float tracking = weapon->GetTracking();
	if( target != NULL && tracking > 0.00000001f ) {
		float angleTowards = normalizeAngle( ( target->GetWorldPosition() - this->GetWorldPosition() ).GetAngle() - GetAngle() );
		SetMomentum( GetMomentum().RotateBy( angleTowards*tracking ) );
		SetAngle( GetMomentum().GetAngle() );
	}
}
Exemplo n.º 2
0
/**\brief The last function call to the ship before it get's deleted
 *
 * At this point, the ship still exists. It has not been removed from the Universe
 *
 * \note We don't want to make this a destructor call because we want the rest
 * of the system to still treat the ship normally.
 */
void AI::Killed( lua_State *L ) {
	LogMsg( WARN, "AI %s has been killed\n", GetName().c_str() );
	SpriteManager *sprites = Simulation_Lua::GetSimulation(L)->GetSpriteManager();

	Sprite* killer = sprites->GetSpriteByID( target );
	if(killer != NULL) {
		if( killer->GetDrawOrder() == DRAW_ORDER_PLAYER ) {
			((Player*)killer)->UpdateFavor( this->GetAlliance()->GetName(), -1 );
		}
	}
}
Exemplo n.º 3
0
/**\brief chooses who the AI should target given the list of the AI's enemies
 *
 */
int AI::ChooseTarget( lua_State *L ){
	//printf("choosing target\n");
	SpriteManager *sprites = Simulation_Lua::GetSimulation(L)->GetSpriteManager();
	list<Sprite*> *nearbySprites = sprites->GetSpritesNear(this->GetWorldPosition(), COMBAT_RANGE, DRAW_ORDER_SHIP);
	
	nearbySprites->sort(CompareAI);
	list<Sprite*>::iterator it;
	list<enemy>::iterator enemyIt=enemies.begin();
	//printf("printing list of enemies\n");
	//printf("the size of enemies = %d\n", enemies.size() );
	for(enemyIt=enemies.begin(); enemyIt!=enemies.end();){
		if(sprites->GetSpriteByID( enemyIt->id)==NULL){
			enemyIt=enemies.erase(enemyIt);
		}
		else {
			enemyIt++;
		}
	}
	
	//printf("printing list of nearby it->GetTarget()\n");
	//int nearbySpritesSize=(*nearbySprites).size();
	//printf("the size of nearbySprites = %d\n",nearbySpritesSize);
	/*for(it=nearbySprites->begin(); it!=nearbySprites->end(); it++){
		if( (*it)->GetDrawOrder() ==DRAW_ORDER_SHIP )
			printf("it->GetTarget() = %d\n",((AI*)(*it))->GetTarget() );
		printf("it->GetID() = %d\n",(*it)->GetID() );

	}*/
	it=nearbySprites->begin();
	enemyIt=enemies.begin();
	int max=0,currTarget=-1;
	int threat=0;
	//printf("starting sprite iteration\n");
		
	for(it= nearbySprites->begin(); it!=nearbySprites->end() && enemyIt!=enemies.end() ; it++){
		if( (*it)->GetID()== this->GetID() )
			continue;


		if( (*it)->GetDrawOrder() ==DRAW_ORDER_SHIP){

			if( enemyIt->id < ((AI*) (*it))->GetTarget() ){
				//printf("starting enemyIt iteration\n");
				while ( enemyIt!=enemies.end() && enemyIt->id < ( (AI*) (*it) )->GetTarget() ) {
				//	printf("enemyIt = %d\n",enemyIt->id);
				//	printf("it->GetTarget() = %d\n", ((AI*) (*it))->GetTarget() );
					if ( !InRange( sprites->GetSpriteByID(enemyIt->id)->GetWorldPosition() , this->GetWorldPosition() ) ) {
						enemyIt=enemies.erase(enemyIt);
						threat=0;
						continue;
					}
					int cost= CalcCost( threat + ( (Ship*)sprites->GetSpriteByID(enemyIt->id))->GetTotalCost() , enemyIt->damage); //damage might need to be scaled so that the damage can be adquately compared to the treat level
					if(currTarget==-1 || max<cost){
						currTarget=enemyIt->id;
						max=cost;
					}
					threat=0;
					enemyIt++;
				}
				//printf("successfully completed enemyIt iteration\n");
				it--;
				continue;
			}
			if( enemyIt->id == ((AI*) (*it))->GetTarget() )
				threat-= ( (Ship*)(*it) )->GetTotalCost();
		}
		else{
			LogMsg( ERR, "Error Sprite %d is not an AI\n", (*it)->GetID() );
		}
	
	}
	// printf("finished sprite iteration\n");

	// cout<<"enemies.size()="<<enemies.size()<<'\n';
	while (enemyIt!=enemies.end()) {
		//printf("starting enemyIt iteration mark2\n");
		if ( !InRange( sprites->GetSpriteByID(enemyIt->id)->GetWorldPosition() , this->GetWorldPosition() ) ) {
			enemyIt=enemies.erase(enemyIt);
			threat=0;
			continue;
		}
		//printf("finished In range check\n");
		//printf("calculate cost\n");
		int cost= CalcCost( threat + ( (Ship*)sprites->GetSpriteByID(enemyIt->id))->GetTotalCost() , enemyIt->damage); //damage might need to be scaled so that the damage can be adquately compared to the treat level
		threat=0;
		//printf("finished calculating cost\n");
		if( currTarget==-1 || max < cost){
			max=cost;
			currTarget=enemyIt->id;
		}
		//printf("successfully completed enemyIt iteration mark 2\n");

		enemyIt++;
	}
	//printf("finished choosing target.  %d is the target\n",currTarget);
	return currTarget;
	
}