//destroy ship in an explosion void Ship::Explode() { Pi::game->GetSpace()->KillBody(this); Sfx::Add(this, Sfx::TYPE_EXPLOSION); Sound::BodyMakeNoise(this, "Explosion_1", 1.0f); ClearThrusterState(); }
void Ship::TestLanded() { m_testLanded = false; if (m_launchLockTimeout > 0.0f) return; if (m_wheelState < 1.0f) return; if (GetFrame()->GetBody()->IsType(Object::PLANET)) { double speed = GetVelocity().Length(); vector3d up = GetPosition().Normalized(); const double planetRadius = static_cast<Planet*>(GetFrame()->GetBody())->GetTerrainHeight(up); if (speed < MAX_LANDING_SPEED) { // check player is sortof sensibly oriented for landing if (GetOrient().VectorY().Dot(up) > 0.99) { // position at zero altitude SetPosition(up * (planetRadius - GetAabb().min.y)); // position facing in roughly the same direction vector3d right = up.Cross(GetOrient().VectorZ()).Normalized(); SetOrient(matrix3x3d::FromVectors(right, up)); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); ClearThrusterState(); SetFlightState(LANDED); Sound::BodyMakeNoise(this, "Rough_Landing", 1.0f); LuaEvent::Queue("onShipLanded", this, GetFrame()->GetBody()); onLanded.emit(); } } } }
void Ship::Blastoff() { if (m_flightState != LANDED) return; ClearThrusterState(); m_flightState = FLYING; m_testLanded = false; m_dockedWith = 0; m_launchLockTimeout = 2.0; // two second of applying thrusters vector3d up = GetPosition().Normalized(); Enable(); assert(GetFrame()->m_astroBody->IsType(Object::PLANET)); const double planetRadius = 2.0 + static_cast<Planet*>(GetFrame()->m_astroBody)->GetTerrainHeight(up); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); SetForce(vector3d(0, 0, 0)); SetTorque(vector3d(0, 0, 0)); Aabb aabb; GetAabb(aabb); // XXX hm. we need to be able to get sbre aabb SetPosition(up*planetRadius - aabb.min.y*up); SetThrusterState(1, 1.0); // thrust upwards Pi::luaOnShipTakeOff->Queue(this, GetFrame()->m_astroBody); }
//destroy ship in an explosion void Ship::Explode() { if (m_invulnerable) return; Pi::game->GetSpace()->KillBody(this); if (this->GetFrame() == Pi::player->GetFrame()) { SfxManager::AddExplosion(this); Sound::BodyMakeNoise(this, "Explosion_1", 1.0f); } ClearThrusterState(); }
//XXX ui stuff void Player::OnEnterHyperspace() { s_soundHyperdrive.Play("Hyperdrive_Jump"); SetNavTarget(0); SetCombatTarget(0); Pi::game->GetWorldView()->HideTargetActions(); // hide the comms menu m_controller->SetFlightControlState(CONTROL_MANUAL); //could set CONTROL_HYPERDRIVE ClearThrusterState(); Pi::game->WantHyperspace(); }
void Player::OnEnterHyperspace() { SetNavTarget(0); SetCombatTarget(0); if (Pi::player->GetFlightControlState() == Player::CONTROL_AUTOPILOT) Pi::player->SetFlightControlState(Player::CONTROL_MANUAL); ClearThrusterState(); Pi::game->WantHyperspace(); }
void Ship::TestLanded() { m_testLanded = false; if (m_launchLockTimeout > 0.0f) return; if (m_wheelState < 1.0f) return; if (GetFrame()->GetBodyFor()->IsType(Object::PLANET)) { double speed = GetVelocity().Length(); vector3d up = GetPosition().Normalized(); const double planetRadius = static_cast<Planet*>(GetFrame()->GetBodyFor())->GetTerrainHeight(up); if (speed < MAX_LANDING_SPEED) { // orient the damn thing right // Q: i'm totally lost. why is the inverse of the body rot matrix being used? // A: NFI. it just works this way matrix4x4d rot; GetRotMatrix(rot); matrix4x4d invRot = rot.InverseOf(); // check player is sortof sensibly oriented for landing const double dot = vector3d(invRot[1], invRot[5], invRot[9]).Normalized().Dot(up); if (dot > 0.99) { Aabb aabb; GetAabb(aabb); // position at zero altitude SetPosition(up * (planetRadius - aabb.min.y)); vector3d forward = rot * vector3d(0,0,1); vector3d other = up.Cross(forward).Normalized(); forward = other.Cross(up); rot = matrix4x4d::MakeRotMatrix(other, up, forward); rot = rot.InverseOf(); SetRotMatrix(rot); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); SetForce(vector3d(0, 0, 0)); SetTorque(vector3d(0, 0, 0)); // we don't use DynamicBody::Disable because that also disables the geom, and that must still get collisions DisableBodyOnly(); ClearThrusterState(); m_flightState = LANDED; Sound::PlaySfx("Rough_Landing", 1.0f, 1.0f, 0); Pi::luaOnShipLanded->Queue(this, GetFrame()->GetBodyFor()); } } } }
void Ship::SetDockedWith(SpaceStation *s, int port) { if (s) { m_dockedWith = s; m_dockedWithPort = port; m_wheelState = 1.0f; m_flightState = DOCKED; SetVelocity(vector3d(0,0,0)); SetAngVelocity(vector3d(0,0,0)); Disable(); ClearThrusterState(); m_dockedWith->SetDocked(this, port); onDock.emit(); } else { Undock(); } }
void Ship::SetLandedOn(Planet *p, float latitude, float longitude) { m_wheelTransition = 0; m_wheelState = 1.0f; Frame* f = p->GetFrame()->GetRotFrame(); SetFrame(f); vector3d up = vector3d(cos(latitude)*sin(longitude), sin(latitude), cos(latitude)*cos(longitude)); const double planetRadius = p->GetTerrainHeight(up); SetPosition(up * (planetRadius - GetAabb().min.y)); vector3d right = up.Cross(vector3d(0,0,1)).Normalized(); SetOrient(matrix3x3d::FromVectors(right, up)); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); ClearThrusterState(); SetFlightState(LANDED); LuaEvent::Queue("onShipLanded", this, p); onLanded.emit(); }
// returns true if command is complete bool Ship::AITimeStep(float timeStep) { // allow the launch thruster thing to happen if (m_launchLockTimeout > 0.0) return false; if (!m_curAICmd) { if (this == Pi::player) return true; // just in case the AI left it on ClearThrusterState(); for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) SetGunState(i,0); return true; } if (m_curAICmd->TimeStepUpdate()) { AIClearInstructions(); // ClearThrusterState(); // otherwise it does one timestep at 10k and gravity is fatal Pi::luaOnAICompleted->Queue(this); return true; } else return false; }
// returns true if command is complete bool Ship::AITimeStep(float timeStep) { // allow the launch thruster thing to happen if (m_launchLockTimeout > 0.0) return false; m_decelerating = false; if (!m_curAICmd) { if (this == Pi::player) return true; // just in case the AI left it on ClearThrusterState(); for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) SetGunState(i,0); return true; } if (m_curAICmd->TimeStepUpdate()) { AIClearInstructions(); // ClearThrusterState(); // otherwise it does one timestep at 10k and gravity is fatal LuaEvent::Queue("onAICompleted", this, EnumStrings::GetString("ShipAIError", AIMessage())); return true; } else return false; }
void Player::PollControls(const float timeStep) { static bool stickySpeedKey = false; if (Pi::game->GetTimeAccel() == Game::TIMEACCEL_PAUSED || Pi::player->IsDead() || GetFlightState() != FLYING) return; // if flying { ClearThrusterState(); SetGunState(0,0); SetGunState(1,0); vector3d wantAngVel(0.0); double angThrustSoftness = 50.0; // have to use this function. SDL mouse position event is bugged in windows int mouseMotion[2]; SDL_GetRelativeMouseState (mouseMotion+0, mouseMotion+1); // call to flush if (Pi::MouseButtonState(SDL_BUTTON_RIGHT)) { matrix4x4d rot; GetRotMatrix(rot); if (!m_mouseActive) { m_mouseDir = vector3d(-rot[8],-rot[9],-rot[10]); // in world space m_mouseX = m_mouseY = 0; m_mouseActive = true; } vector3d objDir = m_mouseDir * rot; const double radiansPerPixel = 0.002; m_mouseX += mouseMotion[0] * radiansPerPixel; double modx = clipmouse(objDir.x, m_mouseX); m_mouseX -= modx; const bool invertY = (Pi::IsMouseYInvert() ? !m_invertMouse : m_invertMouse); m_mouseY += mouseMotion[1] * radiansPerPixel * (invertY ? -1 : 1); double mody = clipmouse(objDir.y, m_mouseY); m_mouseY -= mody; if(!float_is_zero_general(modx) || !float_is_zero_general(mody)) { matrix4x4d mrot = matrix4x4d::RotateYMatrix(modx); mrot.RotateX(mody); m_mouseDir = (rot * (mrot * objDir)).Normalized(); } } else m_mouseActive = false; // disable all keyboard controls while the console is active if (!Pi::IsConsoleActive()) { if (m_flightControlState == CONTROL_FIXSPEED) { double oldSpeed = m_setSpeed; if (stickySpeedKey) { if (!(KeyBindings::increaseSpeed.IsActive() || KeyBindings::decreaseSpeed.IsActive())) { stickySpeedKey = false; } } if (!stickySpeedKey) { if (KeyBindings::increaseSpeed.IsActive()) m_setSpeed += std::max(fabs(m_setSpeed)*0.05, 1.0); if (KeyBindings::decreaseSpeed.IsActive()) m_setSpeed -= std::max(fabs(m_setSpeed)*0.05, 1.0); if ( ((oldSpeed < 0.0) && (m_setSpeed >= 0.0)) || ((oldSpeed > 0.0) && (m_setSpeed <= 0.0)) ) { // flipped from going forward to backwards. make the speed 'stick' at zero // until the player lets go of the key and presses it again stickySpeedKey = true; m_setSpeed = 0; } } } if (KeyBindings::thrustForward.IsActive()) SetThrusterState(2, -1.0); if (KeyBindings::thrustBackwards.IsActive()) SetThrusterState(2, 1.0); if (KeyBindings::thrustUp.IsActive()) SetThrusterState(1, 1.0); if (KeyBindings::thrustDown.IsActive()) SetThrusterState(1, -1.0); if (KeyBindings::thrustLeft.IsActive()) SetThrusterState(0, -1.0); if (KeyBindings::thrustRight.IsActive()) SetThrusterState(0, 1.0); if (KeyBindings::fireLaser.IsActive() || (Pi::MouseButtonState(SDL_BUTTON_LEFT) && Pi::MouseButtonState(SDL_BUTTON_RIGHT))) { SetGunState(Pi::worldView->GetActiveWeapon(), 1); } if (KeyBindings::yawLeft.IsActive()) wantAngVel.y += 1.0; if (KeyBindings::yawRight.IsActive()) wantAngVel.y += -1.0; if (KeyBindings::pitchDown.IsActive()) wantAngVel.x += -1.0; if (KeyBindings::pitchUp.IsActive()) wantAngVel.x += 1.0; if (KeyBindings::rollLeft.IsActive()) wantAngVel.z += 1.0; if (KeyBindings::rollRight.IsActive()) wantAngVel.z -= 1.0; if (KeyBindings::fastRotate.IsActive()) angThrustSoftness = 10.0; } vector3d changeVec; changeVec.x = KeyBindings::pitchAxis.GetValue(); changeVec.y = KeyBindings::yawAxis.GetValue(); changeVec.z = KeyBindings::rollAxis.GetValue(); // Deadzone if(changeVec.LengthSqr() < m_joystickDeadzone) changeVec = vector3d(0.0); changeVec *= 2.0; wantAngVel += changeVec; double invTimeAccelRate = 1.0 / Pi::game->GetTimeAccelRate(); for (int axis=0; axis<3; axis++) wantAngVel[axis] = Clamp(wantAngVel[axis], -invTimeAccelRate, invTimeAccelRate); if (m_mouseActive) AIFaceDirection(m_mouseDir); else AIModelCoordsMatchAngVel(wantAngVel, angThrustSoftness); } }
void Player::PollControls(const float timeStep) { double time_accel = Pi::GetTimeAccel(); double invTimeAccel = 1.0 / time_accel; static bool stickySpeedKey = false; if ((time_accel == 0) || GetDockedWith() || Pi::player->IsDead() || (GetFlightState() != FLYING)) { return; } // if flying { ClearThrusterState(); vector3d wantAngVel(0.0); // have to use this function. SDL mouse position event is bugged in windows int mouseMotion[2]; SDL_GetRelativeMouseState (mouseMotion+0, mouseMotion+1); // call to flush if (Pi::MouseButtonState(3)) { matrix4x4d rot; GetRotMatrix(rot); if (!m_mouseActive) { m_mouseDir = vector3d(-rot[8],-rot[9],-rot[10]); // in world space m_mouseX = m_mouseY = 0; m_mouseActive = true; } vector3d objDir = m_mouseDir * rot; m_mouseX += mouseMotion[0] * 0.002; double modx = clipmouse(objDir.x, m_mouseX); m_mouseX -= modx; m_mouseY += mouseMotion[1] * 0.002; // factor pixels => radians double mody = clipmouse(objDir.y, m_mouseY); m_mouseY -= mody; if(modx != 0.0 || mody != 0.0) { matrix4x4d mrot = matrix4x4d::RotateYMatrix(modx); mrot.RotateX(mody); m_mouseDir = (rot * (mrot * objDir)).Normalized(); } } else m_mouseActive = false; if (m_flightControlState == CONTROL_FIXSPEED) { double oldSpeed = m_setSpeed; if (stickySpeedKey) { if (!(KeyBindings::increaseSpeed.IsActive() || KeyBindings::decreaseSpeed.IsActive())) { stickySpeedKey = false; } } if (!stickySpeedKey) { if (KeyBindings::increaseSpeed.IsActive()) m_setSpeed += std::max(m_setSpeed*0.05, 1.0); if (KeyBindings::decreaseSpeed.IsActive()) m_setSpeed -= std::max(m_setSpeed*0.05, 1.0); if ( ((oldSpeed < 0.0) && (m_setSpeed >= 0.0)) || ((oldSpeed > 0.0) && (m_setSpeed <= 0.0)) ) { // flipped from going forward to backwards. make the speed 'stick' at zero // until the player lets go of the key and presses it again stickySpeedKey = true; m_setSpeed = 0; } } } if (KeyBindings::thrustForward.IsActive()) SetThrusterState(2, -1.0); if (KeyBindings::thrustBackwards.IsActive()) SetThrusterState(2, 1.0); if (KeyBindings::thrustUp.IsActive()) SetThrusterState(1, 1.0); if (KeyBindings::thrustDown.IsActive()) SetThrusterState(1, -1.0); if (KeyBindings::thrustLeft.IsActive()) SetThrusterState(0, -1.0); if (KeyBindings::thrustRight.IsActive()) SetThrusterState(0, 1.0); SetGunState(0,0); SetGunState(1,0); if (KeyBindings::fireLaser.IsActive() || (Pi::MouseButtonState(1) && Pi::MouseButtonState(3))) { SetGunState(Pi::worldView->GetActiveWeapon(), 1); } if (KeyBindings::yawLeft.IsActive()) wantAngVel.y += 1.0; if (KeyBindings::yawRight.IsActive()) wantAngVel.y += -1.0; if (KeyBindings::pitchDown.IsActive()) wantAngVel.x += -1.0; if (KeyBindings::pitchUp.IsActive()) wantAngVel.x += 1.0; if (KeyBindings::rollLeft.IsActive()) wantAngVel.z += 1.0; if (KeyBindings::rollRight.IsActive()) wantAngVel.z -= 1.0; wantAngVel.x += 2 * KeyBindings::pitchAxis.GetValue(); wantAngVel.y += 2 * KeyBindings::yawAxis.GetValue(); wantAngVel.z += 2 * KeyBindings::rollAxis.GetValue(); for (int axis=0; axis<3; axis++) wantAngVel[axis] = Clamp(wantAngVel[axis], -invTimeAccel, invTimeAccel); // matrix4x4d rot; GetRotMatrix(rot); const double angThrustSoftness = KeyBindings::fastRotate.IsActive() ? 10.0 : 50.0; if (m_mouseActive) AIFaceDirection(m_mouseDir); else AIModelCoordsMatchAngVel(wantAngVel, angThrustSoftness); } }