diff options
Diffstat (limited to 'src/game/base/ship.cc')
-rw-r--r-- | src/game/base/ship.cc | 115 |
1 files changed, 99 insertions, 16 deletions
diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index d816943..c93002c 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -18,6 +18,8 @@ #include "base/game.h" #include "base/ship.h" #include "base/spacemine.h" +#include "base/jumppoint.h" +#include "base/racetrack.h" using math::degrees360f; using math::degrees180f; @@ -359,6 +361,9 @@ void Ship::set_dock(core::Entity *dock) return; } + ship_autopilot_flags = AutoPilotDisabled; + ship_autopilot_target = 0; + get_location().assign(dock->location()); get_axis().assign(dock->axis()); ship_dock = dock; @@ -385,13 +390,17 @@ void Ship::launch() get_axis().assign(ship_dock->axis()); if (ship_dock->type() == core::Entity::Globe) - get_location().assign(ship_dock->location() + (ship_dock->axis().forward() * (planet_safe_distance + this->radius() + ship_dock->radius()))); + get_location().assign(ship_dock->location() + (ship_dock->axis().forward() * (PLANET_SAFE_DISTANCE + this->radius() + ship_dock->radius()))); else get_location().assign(ship_dock->location() + (ship_dock->axis().forward() * (this->radius() + ship_dock->radius()))); ship_dock = 0; set_state(core::Entity::Normal); + + ship_autopilot_flags = AutoPilotDisabled; + ship_autopilot_target = 0; + reset(); } @@ -641,15 +650,8 @@ void Ship::frame(const unsigned long elapsed) if (has_autopilot_flag(Ship::AutoPilotEnabled) && !has_target_controlflag(core::EntityControlable::ControlFlagOverride)) { - if (!ship_autopilot_target) { - unset_autopilot_flag(Ship::AutoPilotEnabled); - - } else if (!zone()->find_entity(ship_autopilot_target)) { - ship_autopilot_target = 0; - - } else { - frame_autopilot_goto(elapsed, ship_autopilot_target); - + if ((state() == core::Entity::Normal) || (state() == core::Entity::Impulse) || (state() == core::Entity::ImpulseInitiate)) { + frame_autopilot(elapsed); } } @@ -1013,7 +1015,35 @@ void Ship::frame(const unsigned long elapsed) } -void Ship::frame_autopilot_goto(const unsigned long elapsed, const core::Entity *target) +void Ship::frame_autopilot(const unsigned long elapsed) +{ + if (!autopilot_target()) { + return; + } + + if (!zone()->find_entity(ship_autopilot_target)) { + set_autopilot_target(0); + return; + } + + // reference radius used in calculations + const float r = radius() + autopilot_target()->radius(); + const float distance = math::distance(location(), autopilot_target()->location()); + const float dock_distance = (autopilot_target()->moduletype() == planet_enttype ? r + PLANET_SAFE_DISTANCE : r); + + // thruster and speed control + if (has_autopilot_flag(AutoPilotFormation) && (distance < 4.0f * r)) { + frame_autopilot_formation(elapsed, autopilot_target()); + + } else if (has_autopilot_flag(AutoPilotDock) && (distance < dock_distance)) { + frame_autopilot_dock(elapsed, autopilot_target()); + + } else { + frame_autopilot_goto(elapsed, autopilot_target()); + } +} + +void Ship::frame_autopilot_goto(const unsigned long elapsed, core::Entity *target) { // reference radius used in calculations const float r = radius() + target->radius(); @@ -1043,7 +1073,7 @@ void Ship::frame_autopilot_goto(const unsigned long elapsed, const core::Entity target_roll = 0.0f; // impulse or thruster - if (distance > r + 50.0f) { + if (distance > r + PLANET_SAFE_DISTANCE) { if (state() == core::Entity::Normal) { // enable impulse drive @@ -1083,17 +1113,70 @@ void Ship::frame_autopilot_goto(const unsigned long elapsed, const core::Entity if (distance > 4.0f * r) { target_thrust = 1.0f; - } else if (distance > 2.0f * r ) { - target_thrust = (distance - 2.0f * r ) / 2.0f * r; + } else if (distance > r ) { + target_thrust = math::max(0.1f, (distance - r ) / (3.0f * r)); } else { target_thrust = 0.0f; - // TODO autolevel } } -void Ship::frame_autopilot_formation(const unsigned long elapsed, const core::Entity *target) +void Ship::frame_autopilot_dock(const unsigned long elapsed, core::Entity *target) +{ + // reference radius used in calculations + //const float r = radius() + target->radius(); + //const float dock_distance = (target->moduletype() == planet_enttype ? r + PLANET_SAFE_DISTANCE : r); + + if ((state() == core::Entity::Impulse) || (state() == core::Entity::ImpulseInitiate)) { + func_impulse(); + return; + } + + if (state() != core::Entity::Normal) { + return; + } + + if (target->moduletype() == jumpgate_enttype) { + // jumpgates have their own docking function + JumpGate *jumpgate = static_cast<JumpGate *>(target); + jumpgate->func_dock(this); + unset_autopilot_flag(AutoPilotDock); + return; + + } else if (target->moduletype() == race_enttype) { + if (owner()) { + RaceTrack *race = static_cast<RaceTrack *>(target); + race->func_dock(this); + + } + + unset_autopilot_flag(AutoPilotDock); + return; + } else { + set_dock(target); + + if (owner()) { + + if (owner()->control() == this) { + owner()->set_view(target); + } + + core::Player *dock_owner = (target->type() == core::Entity::Controlable ? static_cast<core::EntityControlable *>(target)->owner() : 0 ); + + if (dock_owner) { + owner()->send("^BDocking at " + dock_owner->name() + "^B's " + target->name()); + } else { + owner()->send("^BDocking at " + target->name()); + } + + // force save + core::server()->module()->player_save(owner()); + } + } +} + +void Ship::frame_autopilot_formation(const unsigned long elapsed, core::Entity *target) { // transform the target's axis into local coordinates const math::Axis reference(axis().transpose() * target->axis()); |