Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Written by kurozael (kurozael@gmail.com), do with it
- as you please :)
- */
- #include <Engine/States/PlayState.h>
- #include <Engine/Entities/Spaceship.h>
- #include <Engine/System/Timer.h>
- #include <Engine/System/Entities.h>
- #include <Engine/System/Events.h>
- #include <Engine/System/Asset.h>
- #include <Engine/System/Utility.h>
- #include <Engine/Graphics/Render.h>
- #include <Engine/Game.h>
- namespace en
- {
- float Spaceship::EnterAtmosphere(Planet* planet)
- {
- Vector3f& planetPos = planet->GetPos();
- float distance = planetPos.Distance(m_position);
- float pullSize = planet->GetSize() + (1.0f + planet->GetGravPull());
- if (distance <= pullSize * 2.0f)
- {
- if (m_atmosphere == NULL || (distance < planetPos.Distance(m_atmosphere->GetPos())))
- m_atmosphere = planet;
- }
- return distance;
- }
- void Spaceship::SetDashTime(float dashTime)
- {
- m_dashTime = Timer::CurTime() + dashTime;
- }
- void Spaceship::SetMessage(const std::string& message)
- {
- m_fadeMessageTime = Timer::CurTime() + 3.0f;
- m_message = message;
- }
- void Spaceship::OnCollide(Planet* planet)
- {
- if (m_fuel < 20.0f)
- g_Awards->Earn("Close One");
- SetPlanet(planet);
- SetVelocity(Vector3f(0, 0, 0));
- g_PlayState->AddScore(
- std::ceil((4.0f - planet->GetSize()) * 100.0f));
- m_landCount++;
- if (m_landCount == 1)
- {
- g_PlayState->SetNewPlanet();
- m_landCount = 0;
- }
- }
- void Spaceship::CheckSkip(Planet* planet)
- {
- Entity* nextPlanet = (Planet*)g_Entities->GetNext(m_planet, "Planet");
- float skipBonus = g_Config->GetFloat("SkipPlanetBonus", 300.0f);
- if (nextPlanet != NULL && planet != nextPlanet)
- {
- g_PlayState->AddScore(skipBonus, true);
- g_Awards->Earn("Skip Planet");
- SetMessage("Skip! +" + Math::ToString(skipBonus));
- }
- }
- void Spaceship::SetPlanet(Planet* planet)
- {
- if (m_fuel < 1.0f)
- return;
- Vector3f& position = planet->GetPos();
- Vector3f direction = position - m_position;
- float angle = std::atan2(direction.z, -direction.x);
- // Only play the impact sound if we hopped onto it! Durr.
- if (m_planet != NULL && m_planet != planet)
- {
- g_Audio->PlaySound("impact.wav");
- CheckSkip(planet);
- }
- m_gravity.Reset();
- m_gasSound->Stop();
- m_orbit = angle;
- m_planet = planet;
- m_fuel = 100.0f;
- }
- Planet* Spaceship::GetPlanet()
- {
- return m_planet;
- }
- void Spaceship::OnEvent(sf::Event& event)
- {
- if (event.Type == sf::Event::KeyReleased && event.Key.Code == sf::Keyboard::Space
- && !IsMoving() && !m_exploded)
- Jump();
- }
- void Spaceship::OnUpdate()
- {
- if (m_planet != NULL && !IsMoving() && !m_exploded)
- {
- Vector3f& position = m_planet->GetPos();
- Vector3f direction = position - m_position;
- float orbitSpeed = m_planet->GetSpinSpeed() * 0.04;
- float angle = std::atan2(direction.z, -direction.x);
- float size = m_planet->GetSize() + 1.0f;
- angle = (angle * 180.f) / M_PI;
- m_position.x = position.x + std::cos(m_orbit) * size;
- m_position.z = position.z - std::sin(m_orbit) * size;
- m_position.y = 0.2f;
- m_angle.y = angle;
- bool bIsClockwise = m_planet->IsClockwise();
- if (sf::Keyboard::IsKeyPressed(sf::Keyboard::LShift)
- || sf::Keyboard::IsKeyPressed(sf::Keyboard::RShift))
- {
- bIsClockwise = !bIsClockwise;
- orbitSpeed *= 0.5f;
- }
- if (bIsClockwise)
- m_orbit -= (Timer::GetDT() * orbitSpeed);
- else
- m_orbit += (Timer::GetDT() * orbitSpeed);
- }
- else if (!m_exploded)
- {
- // Are we currently within a planet's atmosphere?
- if (m_atmosphere != NULL)
- {
- Vector3f planetPos = m_atmosphere->GetPos();
- Vector3f direction = planetPos - m_position;
- float distance = planetPos.Distance(m_position);
- float pullSize = m_atmosphere->GetSize() + (1.0f + m_atmosphere->GetGravPull());
- float angle = std::atan2(direction.z, -direction.x);
- angle = angle * (180.f / M_PI);
- if (distance <= pullSize)
- m_gravity = direction * 0.6f;
- else
- m_gravity = direction * 0.2f;
- m_angle.y = Math::DegApproach(
- m_angle.y, angle, Timer::GetDT() * 360.0f
- );
- m_atmosphere = NULL;
- };
- /*
- Here we give the ability for the player to do a short 'halt'
- in space. This is useful to dodge asteroids, but limits their
- speed and still reduces their fuel!
- */
- if (sf::Keyboard::IsKeyPressed(sf::Keyboard::LShift)
- || sf::Keyboard::IsKeyPressed(sf::Keyboard::RShift))
- {
- SetVelocity(m_velocity.NormalCopy() * 4.0f);
- }
- else
- {
- SetVelocity(m_velocity.NormalCopy() * GetSpeed());
- }
- /*
- Change the volume based on our fuel,
- but not too frequently because SFML doesn't
- like it! Silly SFML!
- */
- if (Timer::CurTime() >= m_nextVolumeTime)
- {
- m_nextVolumeTime = Timer::CurTime() + 0.5f;
- m_gasSound->SetVolume(
- Math::Clamp(m_fuel, 0.0f, 100.0f)
- );
- }
- m_position = m_position + (m_gravity * Timer::GetDT());
- m_gravity *= 0.6f;
- float fuelLossAmount = g_Config->GetFloat("FuelLossAmount") * Timer::GetDT();
- PropPhysics::OnUpdate();
- if (m_position.z > 30.0f || m_position.z < -30.0f)
- Kill();
- if (m_fuel > 0.0f)
- m_fuel = std::max<float>(m_fuel - fuelLossAmount, 0);
- else
- Kill();
- FireTrail();
- }
- if (m_nextRespawn > 0.0f && Timer::CurTime() >= m_nextRespawn)
- Respawn();
- m_emitter->Update();
- }
- float Spaceship::GetSpeed()
- {
- if (m_dashTime > 0.0f && Timer::CurTime() < m_dashTime)
- return 12.0f;
- else
- return 9.0f;
- }
- void Spaceship::Kill()
- {
- if (!m_exploded)
- Explode();
- }
- void Spaceship::Respawn()
- {
- g_PlayState->GetCamera()->SetTarget(
- m_planet->GetPos(), true
- );
- Vector3f& sunPos = g_PlayState->GetTheSun()->GetPos();
- sunPos.x = m_planet->GetPos().x - 28.0f;
- g_Audio->PlaySound("impact.wav");
- m_nextRespawn = 0.0f;
- m_gasSound->Stop();
- m_velocity.Reset();
- m_exploded = false;
- m_fuel = 100.0f;
- m_lives--;
- if (m_lives == 0)
- g_PlayState->Lose();
- g_Game->DoFlash(0.2f, "hazard.wav");
- }
- void Spaceship::Explode()
- {
- m_emitter->ExplodeFX(m_position, 18, 60);
- m_emitter->ShockwaveFX(m_position, 10, 60);
- /*
- Ground control to major Tom, your circuits dead, there's something wrong
- Can you hear me, major Tom?
- Can you hear me, major Tom?
- Can you hear me, major Tom?
- Can you...
- Uh... Houston, we have a problem...
- */
- m_nextRespawn = Timer::CurTime() + 1.0f;
- m_gasSound->Stop();
- m_exploded = true;
- // Lose points for the failure!
- float loseLifePenalty = g_Config->GetInt("LoseLifePenalty", 100);
- SetMessage("Boom! -" + Math::ToString(loseLifePenalty));
- g_PlayState->TakeScore(loseLifePenalty);
- // BOOOOOOOOOOOOOOOOOOOOOOOOOOOM!
- m_explosion->Play();
- }
- void Spaceship::FireTrail()
- {
- Vector3f shipDir = m_angle.Direction();
- float velLength = m_velocity.Length();
- int particles = velLength * 0.3f;
- // Don't bother if we aren't moving much!
- if (velLength <= 1.5f) return;
- for (int i = 0; i < particles; i++)
- {
- std::string texture = "textures/particles/dust1.png";
- Vector3f velocity = shipDir * -velLength;
- float startSize = Math::Random(0.4f, 1.2f);
- float endSize = Math::Random(0.0f, 0.4f);
- float randAlpha = Math::Random(0.4f, 1.0f);
- float randGrey = Math::Random(0.2f, 0.8f);
- float dieTime = Math::Random(0.8, 1.6f);
- Color color = Color(randGrey, randGrey, randGrey, randAlpha);
- if (i >= particles * 0.5f)
- {
- texture = "textures/particles/dust2.png";
- startSize = Math::Random(0.8f, 1.8f);
- endSize = Math::Random(0.3f, 0.6f);
- dieTime = Math::Random(0.4f, 1.2f);
- color = Color(Math::Random(0.2f, 1.0f), Math::Random(0.0f, 0.2f), 0.0f, randAlpha);
- }
- pParticle particle = m_emitter->New();
- particle->SetPos(m_position - (shipDir * 0.9f));
- particle->SetColor(color);
- particle->SetDieTime(dieTime);
- particle->SetStartSize(startSize);
- particle->SetTexture(texture);
- particle->SetEndSize(endSize);
- particle->SetVelocity(velocity);
- particle->SetAirResistance(0.1f);
- m_emitter->Add(particle);
- }
- }
- bool Spaceship::IsMoving()
- {
- return m_velocity.SquaredLength() > 0.0f;
- }
- int Spaceship::GetLives()
- {
- return m_lives;
- }
- void Spaceship::OnDraw()
- {
- // See if we're not respawning!
- if (m_nextRespawn == 0.0f)
- {
- Color& color = m_planet->GetColor();
- m_color.r = Math::Approach(m_color.r, color.r + 0.25f, Timer::GetDT() * 0.1f);
- m_color.g = Math::Approach(m_color.g, color.g + 0.25f, Timer::GetDT() * 0.1f);
- m_color.b = Math::Approach(m_color.b, color.b + 0.25f, Timer::GetDT() * 0.1f);
- glPushMatrix();
- glTranslatef(m_position.x, m_position.y, m_position.z);
- glColor4f(m_color.r, m_color.g, m_color.b, 0.4f);
- m_billboard.Draw(Vector3f(0.0f, 0.0f, 0.0f), 10.0f);
- m_angle.Set();
- glColor4f(1, 1, 1, 1);
- glRotatef(180, 0, 1, 0);
- glScalef(0.07, 0.07, 0.07);
- m_model->Draw();
- glPopMatrix();
- }
- Pointf screenPos = Render::ToScreen(m_position);
- if (m_fadeMessageTime != 0.0f)
- {
- float timeLeft = Math::Clamp(m_fadeMessageTime - Timer::CurTime(), 0.0f, 3.0f);
- Color color = Color(1.0f, 1.0f, 1.0f, (1.0f / 3.0f) * timeLeft);
- Render::Start2D();
- Render::Text::SetFont(g_Config->GetString("GameFont"));
- Render::Text::SetHeight(20.0f);
- Render::Text::Draw2D(
- screenPos.x, screenPos.y + 32.0f + (48.0f - ((48.0f / 3.0f) * timeLeft)), m_message, color, true
- );
- Render::End2D();
- if (timeLeft == 0.0f)
- {
- m_fadeMessageTime = 0.0f;
- m_message.clear();
- }
- }
- if (m_nextRespawn == 0.0f)
- {
- // Don't display the fuel bar if we're orbiting!
- if (!IsMoving())
- return;
- // Position the fuel bar above the spaceship.
- screenPos.y -= 64.0f;
- Render::Start2D();
- Render::Screen::Quad(screenPos.x, screenPos.y, 64, 6, Color(1, 0.2, 0.2, 1));
- Render::Screen::Quad(screenPos.x, screenPos.y, (64.0f / 100.0f) * m_fuel, 6, Color(0, 1, 0, 1));
- Render::Text::SetFont(g_Config->GetString("GameFont"));
- Render::Text::SetHeight(20.0f);
- Render::Text::Draw2D(screenPos.x, screenPos.y + 8, "FUEL: " + Math::ToString(std::ceil(m_fuel)));
- Render::End2D();
- }
- m_emitter->Draw();
- }
- float Spaceship::GetFuel()
- {
- return m_fuel;
- }
- void Spaceship::Remove()
- {
- g_Entities->Remove(this);
- }
- void Spaceship::Jump()
- {
- if (m_angle.y <= 90 && m_angle.y >= -90)
- {
- if (Math::Random(0.0f, 1.0f) < 0.1f)
- g_PlayState->MakeAsteroid();
- SetVelocity(m_angle.Direction() * GetSpeed());
- m_gasSound->Play();
- m_planet->Impact();
- }
- }
- Spaceship::Spaceship()
- {
- m_billboard.SetTexture("textures/particle.png");
- m_billboard.DisableLighting();
- m_emitter.reset(new Emitter);
- m_emitter->Clear();
- g_Entities->Add(this);
- g_Events->Add(this);
- m_explosion = g_Audio->GetSound("explosion.ogg");
- m_gasSound = g_Audio->GetSound("cannister_loop.wav");
- m_gasSound->SetLoop(true);
- g_Audio->LoadSound("impact.wav");
- m_nextVolumeTime = 0.0f;
- m_nextRespawn = 0.0f;
- m_exploded = false;
- m_atmosphere = NULL;
- m_landCount = 0;
- m_dashTime = 0.0f;
- m_planet = NULL;
- m_lives = g_Config->GetInt("StartLives", 2);
- m_model = new StaticModel;
- m_model->Load("meshes/SpaceFrigate/SpaceFrigate.3ds");
- m_fuel = 100.0f;
- }
- Spaceship::~Spaceship()
- {
- g_Events->Remove(this);
- delete m_model;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement