/**\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 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() ); } }
RigidBody::RigidBody(Rect rect) { float width = (rect.right - rect.left); float height = (rect.bottom - rect.top); // Create a Rectangle shape - origin middle mShape = new Shape(); mShape->setOrigin(Vector(rect.left + width/2, rect.top + height/2, 0)); mShape->addPoint(Vector(-width/2, -height/2, 0)); // top - left mShape->addPoint(Vector(-width/2, height/2, 0)); // bottom - left mShape->addPoint(Vector(width/2, height/2, 0)); // bottom - right mShape->addPoint(Vector(width/2, -height/2, 0)); // top - right setStatic(false); mAlive = true; mTexture = NULL; SetMass(1); SetVelocity(0, 0); SetAngularVelocity(0.0f); SetForce(Vector(0, 0, 0)); SetTorque(Vector(0, 0, 0)); SetMomentum(Vector(0, 0, 0)); SetFriction(1.0f); SetSleeping(false); }
/**\brief set name of last planet visited */ void Player::Land( lua_State *L, Planet* planet ){ assert( planet ); if( planet->GetLandable() == false || planet->GetForbidden() == true ) { return; } LogMsg(INFO, "Landed on %s", planet->GetName().c_str() ); Lua::Call( "landingDialog", "i", planet->GetID() ); // Stay on the Planet SetMomentum( Coordinate(0,0) ); // Run Land function for each Mission bool missionOver; list<Mission*>::iterator i = missions.begin(); while( i != missions.end() ) { missionOver = (*i)->Land(); if( missionOver ) { LogMsg(INFO, "Completed the Mission '%s'", (*i)->GetName().c_str() ); // Remove this completed mission from the list i = missions.erase( i ); } else { ++i; } } lastPlanet = planet->GetName(); Save( Simulation_Lua::GetSimulation(L)->GetName() ); //AdvanceFromLand }
/**\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 ); } }
RigidBody::RigidBody(float x, float y, int width, int height) { // Create a Rectangle shape - origin middle mShape = new Shape(); mShape->setOrigin(Vector(x, y, 0)); mShape->addPoint(Vector(-width/2, -height/2, 0)); // top - left mShape->addPoint(Vector(-width/2, height/2, 0)); // bottom - left mShape->addPoint(Vector(width/2, height/2, 0)); // bottom - right mShape->addPoint(Vector(width/2, -height/2, 0)); // top - right setStatic(false); mAlive = true; SetMass(1); SetVelocity(0, 0); SetAngularVelocity(0.0f); SetForce(Vector(0, 0, 0)); SetTorque(Vector(0, 0, 0)); SetMomentum(Vector(0, 0, 0)); SetFriction(1.0f); SetSleeping(false); SetRepeatX(false); }
/**\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 ); }