/**\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() ); } }
/**\brief Constructor */ Projectile::Projectile(float damageBooster, float angleToFire, Coordinate worldPosition, Coordinate firedMomentum, Weapon* _weapon) { damageBoost=damageBooster; // All Projectiles get these ownerID = 0; targetID = 0; start = Timer::GetTicks(); SetRadarColor (Color(0x55,0x55,0x55)); // These are based off of the Ship firing this projectile SetWorldPosition( worldPosition ); SetAngle(angleToFire); // These are based off of the Weapon weapon = _weapon; secondsOfLife = weapon->GetLifetime(); SetImage(weapon->GetImage()); Trig *trig = Trig::Instance(); Coordinate momentum = GetMomentum(); float angle = static_cast<float>(trig->DegToRad( angleToFire )); momentum = firedMomentum + Coordinate( trig->GetCos( angle ) * weapon->GetVelocity(), -trig->GetSin( angle ) * weapon->GetVelocity() ); SetMomentum( momentum ); }
/**\brief Update function on every frame. */ void Ship::Update( lua_State *L ) { Sprite::Update( L ); // update momentum and other generic sprite attributes if( status.isAccelerating == false && status.isRotatingLeft == false && status.isRotatingRight == false) { flareAnimation->Reset(); } flareAnimation->Update(); Coordinate momentum = GetMomentum(); momentum.EnforceMagnitude( shipStats.GetMaxSpeed()*engineBooster ); // Show the hits taken as part of the radar color if(IsDisabled()) SetRadarColor( GREY ); else SetRadarColor( RED * GetHullIntegrityPct() ); // Ship has taken as much damage as possible... // It Explodes! if( status.hullDamage >= (float)shipStats.GetHullStrength() ) { SpriteManager *sprites = Simulation_Lua::GetSimulation(L)->GetSpriteManager(); Camera* camera = Simulation_Lua::GetSimulation(L)->GetCamera(); // Play explode sound if(OPTION(int, "options/sound/explosions")) { Sound *explodesnd = Sound::Get("Resources/Audio/Effects/18384__inferno__largex.wav.ogg"); explodesnd->Play( GetWorldPosition() - camera->GetFocusCoordinate()); } // Create Explosion sprites->Add( new Effect( GetWorldPosition(), "Resources/Animations/explosion1.ani", 0) ); // Remove this Sprite from the SpriteManager sprites->Delete( (Sprite*)this ); }
/**\brief Adds damage to hull. */ void Ship::Damage(short int damage) { if(status.shieldDamage >= ((float)shipStats.GetShieldStrength()) * shieldBooster) status.hullDamage += damage; else status.shieldDamage += damage; if( GetHullIntegrityPct() < .15 ) { status.isDisabled = true; SetMomentum( GetMomentum() * .75 ); } }
/**\brief Accelerates the ship. * \sa Model::GetAcceleration */ void Ship::Accelerate( void ) { Trig *trig = Trig::Instance(); Coordinate momentum = GetMomentum(); float angle = static_cast<float>(trig->DegToRad( GetAngle() )); float speed = shipStats.GetMaxSpeed()*engineBooster; float acceleration = (shipStats.GetForceOutput() *engineBooster ) / shipStats.GetMass(); momentum += Coordinate( trig->GetCos( angle ) * acceleration * Timer::GetDelta(), -1 * trig->GetSin( angle ) * acceleration * Timer::GetDelta() ); momentum.EnforceMagnitude(speed); SetMomentum( momentum ); status.isAccelerating = true; // Play engine sound float engvol = OPTION(float,"options/sound/engines"); Coordinate offset = GetWorldPosition() - Camera::Instance()->GetFocusCoordinate(); if ( this->GetDrawOrder() == DRAW_ORDER_SHIP ) engvol = engvol * NON_PLAYER_SOUND_RATIO ; this->engine->GetSound()->SetVolume( engvol ); this->engine->GetSound()->PlayNoRestart( offset ); }