void PlayerShipController::StaticUpdate(const float timeStep) { vector3d v; matrix4x4d m; if (m_ship->GetFlightState() == Ship::FLYING) { switch (m_flightControlState) { case CONTROL_FIXSPEED: PollControls(timeStep, true); if (IsAnyLinearThrusterKeyDown()) break; v = -m_ship->GetOrient().VectorZ() * m_setSpeed; if (m_setSpeedTarget) { v += m_setSpeedTarget->GetVelocityRelTo(m_ship->GetFrame()); } m_ship->AIMatchVel(v); break; case CONTROL_FIXHEADING_FORWARD: case CONTROL_FIXHEADING_BACKWARD: PollControls(timeStep, true); if (IsAnyAngularThrusterKeyDown()) break; v = m_ship->GetVelocity().NormalizedSafe(); if (m_flightControlState == CONTROL_FIXHEADING_BACKWARD) v = -v; m_ship->AIFaceDirection(v); break; case CONTROL_MANUAL: PollControls(timeStep, false); break; case CONTROL_AUTOPILOT: if (m_ship->AIIsActive()) break; Pi::game->RequestTimeAccel(Game::TIMEACCEL_1X); // AIMatchVel(vector3d(0.0)); // just in case autopilot doesn't... // actually this breaks last timestep slightly in non-relative target cases m_ship->AIMatchAngVelObjSpace(vector3d(0.0)); if (m_ship->GetFrame()->IsRotFrame()) SetFlightControlState(CONTROL_FIXSPEED); else SetFlightControlState(CONTROL_MANUAL); m_setSpeed = 0.0; break; default: assert(0); break; } } else SetFlightControlState(CONTROL_MANUAL); //call autopilot AI, if active (also applies to set speed and heading lock modes) OS::EnableFPE(); m_ship->AITimeStep(timeStep); OS::DisableFPE(); }
void Player::StaticUpdate(const float timeStep) { Body *b; vector3d v; matrix4x4d m; if (GetFlightState() == Ship::FLYING) { switch (m_flightControlState) { case CONTROL_FIXSPEED: if (Pi::GetView() == Pi::worldView) PollControls(timeStep); b = (GetCombatTarget() ? GetCombatTarget() : GetNavTarget()); GetRotMatrix(m); v = m * vector3d(0, 0, -m_setSpeed); if (b) v += b->GetVelocityRelativeTo(this->GetFrame()); AIMatchVel(v); break; case CONTROL_MANUAL: if (Pi::GetView() == Pi::worldView) PollControls(timeStep); break; case CONTROL_AUTOPILOT: break; } } Ship::StaticUpdate(timeStep); // also calls autopilot AI if (m_flightControlState == CONTROL_AUTOPILOT && !AIIsActive()) { Pi::RequestTimeAccel(1); SetFlightControlState(CONTROL_MANUAL); //FIXSPEED); // m_setSpeed = 0; } /* This wank probably shouldn't be in Player... */ /* Ship engine noise. less loud inside */ float v_env = (Pi::worldView->GetCamType() == WorldView::CAM_EXTERNAL ? 1.0f : 0.5f); static Sound::Event sndev; float volBoth = 0.0f; volBoth += 0.5f*fabs(GetThrusterState().y); volBoth += 0.5f*fabs(GetThrusterState().z); float targetVol[2] = { volBoth, volBoth }; if (GetThrusterState().x > 0.0) targetVol[0] += 0.5f*(float)GetThrusterState().x; else targetVol[1] += -0.5f*(float)GetThrusterState().x; targetVol[0] = v_env * Clamp(targetVol[0], 0.0f, 1.0f); targetVol[1] = v_env * Clamp(targetVol[1], 0.0f, 1.0f); float dv_dt[2] = { 4.0f, 4.0f }; if (!sndev.VolumeAnimate(targetVol, dv_dt)) { sndev.Play("Thruster_large", 0.0f, 0.0f, Sound::OP_REPEAT); sndev.VolumeAnimate(targetVol, dv_dt); } float angthrust = 0.1f * v_env * (float)Pi::player->GetAngThrusterState().Length(); static Sound::Event angThrustSnd; if (!angThrustSnd.VolumeAnimate(angthrust, angthrust, 5.0f, 5.0f)) { angThrustSnd.Play("Thruster_Small", 0.0f, 0.0f, Sound::OP_REPEAT); angThrustSnd.VolumeAnimate(angthrust, angthrust, 5.0f, 5.0f); } }
void PlayerShipController::StaticUpdate(const float timeStep) { vector3d v; matrix4x4d m; int mouseMotion[2]; SDL_GetRelativeMouseState (mouseMotion+0, mouseMotion+1); // call to flush // external camera mouselook if (Pi::MouseButtonState(SDL_BUTTON_MIDDLE)) { // not internal camera if (Pi::worldView->GetCamType() != Pi::worldView->CAM_INTERNAL) { MoveableCameraController *mcc = static_cast<MoveableCameraController*>(Pi::worldView->GetCameraController()); const double accel = 0.01; // XXX configurable? mcc->RotateLeft(mouseMotion[0] * accel); mcc->RotateUp( mouseMotion[1] * accel); // only mouselook if the player presses both mmb and rmb mouseMotion[0] = 0; mouseMotion[1] = 0; } } if (m_ship->GetFlightState() == Ship::FLYING) { switch (m_flightControlState) { case CONTROL_FIXSPEED: PollControls(timeStep, true, mouseMotion); if (IsAnyLinearThrusterKeyDown()) break; v = -m_ship->GetOrient().VectorZ() * m_setSpeed; if (m_setSpeedTarget) { v += m_setSpeedTarget->GetVelocityRelTo(m_ship->GetFrame()); } m_ship->AIMatchVel(v); break; case CONTROL_FIXHEADING_FORWARD: case CONTROL_FIXHEADING_BACKWARD: case CONTROL_FIXHEADING_NORMAL: case CONTROL_FIXHEADING_ANTINORMAL: case CONTROL_FIXHEADING_RADIALLY_INWARD: case CONTROL_FIXHEADING_RADIALLY_OUTWARD: case CONTROL_FIXHEADING_KILLROT: PollControls(timeStep, true, mouseMotion); if (IsAnyAngularThrusterKeyDown()) break; v = m_ship->GetVelocity().NormalizedSafe(); if (m_flightControlState == CONTROL_FIXHEADING_BACKWARD || m_flightControlState == CONTROL_FIXHEADING_ANTINORMAL) v = -v; if (m_flightControlState == CONTROL_FIXHEADING_NORMAL || m_flightControlState == CONTROL_FIXHEADING_ANTINORMAL) v = v.Cross(m_ship->GetPosition().NormalizedSafe()); if (m_flightControlState == CONTROL_FIXHEADING_RADIALLY_INWARD) v = -m_ship->GetPosition().NormalizedSafe(); if (m_flightControlState == CONTROL_FIXHEADING_RADIALLY_OUTWARD) v = m_ship->GetPosition().NormalizedSafe(); if (m_flightControlState == CONTROL_FIXHEADING_KILLROT) { v = -m_ship->GetOrient().VectorZ(); if (m_ship->GetAngVelocity().Length() < 0.0001) // fixme magic number SetFlightControlState(CONTROL_MANUAL); } m_ship->AIFaceDirection(v); break; case CONTROL_MANUAL: PollControls(timeStep, false, mouseMotion); break; case CONTROL_AUTOPILOT: if (m_ship->AIIsActive()) break; Pi::game->RequestTimeAccel(Game::TIMEACCEL_1X); // AIMatchVel(vector3d(0.0)); // just in case autopilot doesn't... // actually this breaks last timestep slightly in non-relative target cases m_ship->AIMatchAngVelObjSpace(vector3d(0.0)); if (m_ship->GetFrame()->IsRotFrame()) SetFlightControlState(CONTROL_FIXSPEED); else SetFlightControlState(CONTROL_MANUAL); m_setSpeed = 0.0; break; default: assert(0); break; } } else SetFlightControlState(CONTROL_MANUAL); //call autopilot AI, if active (also applies to set speed and heading lock modes) OS::EnableFPE(); m_ship->AITimeStep(timeStep); OS::DisableFPE(); }
void PlayerShipController::PollControls(const float timeStep, const bool force_rotation_damping, int *mouseMotion) { static bool stickySpeedKey = false; CheckControlsLock(); if (m_controlsLocked) return; // if flying { m_ship->ClearThrusterState(); m_ship->SetGunState(0,0); m_ship->SetGunState(1,0); vector3d wantAngVel(0.0); double angThrustSoftness = 10.0; const float linearThrustPower = (KeyBindings::thrustLowPower.IsActive() ? m_lowThrustPower : 1.0f); // have to use this function. SDL mouse position event is bugged in windows if (Pi::MouseButtonState(SDL_BUTTON_RIGHT)) { const matrix3x3d &rot = m_ship->GetOrient(); if (!m_mouseActive) { m_mouseDir = -rot.VectorZ(); // in world space m_mouseX = m_mouseY = 0; m_mouseActive = true; } vector3d objDir = m_mouseDir * rot; const double radiansPerPixel = 0.00002 * m_fovY; const int maxMotion = std::max(abs(mouseMotion[0]), abs(mouseMotion[1])); const double accel = Clamp(maxMotion / 4.0, 0.0, 90.0 / m_fovY); m_mouseX += mouseMotion[0] * accel * radiansPerPixel; double modx = clipmouse(objDir.x, m_mouseX); m_mouseX -= modx; const bool invertY = (Pi::IsMouseYInvert() ? !m_invertMouse : m_invertMouse); m_mouseY += mouseMotion[1] * accel * radiansPerPixel * (invertY ? -1 : 1); double mody = clipmouse(objDir.y, m_mouseY); m_mouseY -= mody; if(!is_zero_general(modx) || !is_zero_general(mody)) { matrix3x3d mrot = matrix3x3d::RotateY(modx) * matrix3x3d::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(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()) m_ship->SetThrusterState(2, -linearThrustPower); if (KeyBindings::thrustBackwards.IsActive()) m_ship->SetThrusterState(2, linearThrustPower); if (KeyBindings::thrustUp.IsActive()) m_ship->SetThrusterState(1, linearThrustPower); if (KeyBindings::thrustDown.IsActive()) m_ship->SetThrusterState(1, -linearThrustPower); if (KeyBindings::thrustLeft.IsActive()) m_ship->SetThrusterState(0, -linearThrustPower); if (KeyBindings::thrustRight.IsActive()) m_ship->SetThrusterState(0, linearThrustPower); if (KeyBindings::fireLaser.IsActive() || (Pi::MouseButtonState(SDL_BUTTON_LEFT) && Pi::MouseButtonState(SDL_BUTTON_RIGHT))) { //XXX worldview? madness, ask from ship instead m_ship->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::killRot.IsActive()) SetFlightControlState(CONTROL_FIXHEADING_KILLROT); if (KeyBindings::thrustLowPower.IsActive()) angThrustSoftness = 50.0; vector3d changeVec; changeVec.x = KeyBindings::pitchAxis.GetValue(); changeVec.y = KeyBindings::yawAxis.GetValue(); changeVec.z = KeyBindings::rollAxis.GetValue(); // Deadzone more accurate for (int axis=0; axis<3; axis++) { if (fabs(changeVec[axis]) < m_joystickDeadzone) changeVec[axis]=0.0; else changeVec[axis] = changeVec[axis] * 2.0; } wantAngVel += changeVec; if (wantAngVel.Length() >= 0.001 || force_rotation_damping || m_rotationDamping) { if (Pi::game->GetTimeAccel()!=Game::TIMEACCEL_1X) { for (int axis=0; axis<3; axis++) wantAngVel[axis] = wantAngVel[axis] * Pi::game->GetInvTimeAccelRate(); } m_ship->AIModelCoordsMatchAngVel(wantAngVel, angThrustSoftness); } if (m_mouseActive) m_ship->AIFaceDirection(m_mouseDir); } }
void Player::OnEnterSystem() { SetFlightControlState(Player::CONTROL_MANUAL); Pi::sectorView->ResetHyperspaceTarget(); }
void Player::StaticUpdate(const float timeStep) { vector3d v; matrix4x4d m; Ship::StaticUpdate(timeStep); // also calls autopilot AI if (GetFlightState() == Ship::FLYING) { switch (m_flightControlState) { case CONTROL_FIXSPEED: if (Pi::GetView() == Pi::worldView) PollControls(timeStep); if (IsAnyThrusterKeyDown()) break; GetRotMatrix(m); v = m * vector3d(0, 0, -m_setSpeed); if (m_setSpeedTarget) { v += m_setSpeedTarget->GetVelocityRelTo(GetFrame()); } AIMatchVel(v); break; case CONTROL_MANUAL: if (Pi::GetView() == Pi::worldView) PollControls(timeStep); break; case CONTROL_AUTOPILOT: if (AIIsActive()) break; Pi::game->RequestTimeAccel(Game::TIMEACCEL_1X); // AIMatchVel(vector3d(0.0)); // just in case autopilot doesn't... // actually this breaks last timestep slightly in non-relative target cases AIMatchAngVelObjSpace(vector3d(0.0)); if (GetFrame()->IsRotatingFrame()) SetFlightControlState(CONTROL_FIXSPEED); else SetFlightControlState(CONTROL_MANUAL); m_setSpeed = 0.0; break; } } else SetFlightControlState(CONTROL_MANUAL); /* This wank probably shouldn't be in Player... */ /* Ship engine noise. less loud inside */ float v_env = (Pi::worldView->GetCamType() == WorldView::CAM_EXTERNAL ? 1.0f : 0.5f) * Sound::GetSfxVolume(); static Sound::Event sndev; float volBoth = 0.0f; volBoth += 0.5f*fabs(GetThrusterState().y); volBoth += 0.5f*fabs(GetThrusterState().z); float targetVol[2] = { volBoth, volBoth }; if (GetThrusterState().x > 0.0) targetVol[0] += 0.5f*float(GetThrusterState().x); else targetVol[1] += -0.5f*float(GetThrusterState().x); targetVol[0] = v_env * Clamp(targetVol[0], 0.0f, 1.0f); targetVol[1] = v_env * Clamp(targetVol[1], 0.0f, 1.0f); float dv_dt[2] = { 4.0f, 4.0f }; if (!sndev.VolumeAnimate(targetVol, dv_dt)) { sndev.Play("Thruster_large", 0.0f, 0.0f, Sound::OP_REPEAT); sndev.VolumeAnimate(targetVol, dv_dt); } float angthrust = 0.1f * v_env * float(Pi::player->GetAngThrusterState().Length()); static Sound::Event angThrustSnd; if (!angThrustSnd.VolumeAnimate(angthrust, angthrust, 5.0f, 5.0f)) { angThrustSnd.Play("Thruster_Small", 0.0f, 0.0f, Sound::OP_REPEAT); angThrustSnd.VolumeAnimate(angthrust, angthrust, 5.0f, 5.0f); } }