diff options
Diffstat (limited to 'src/game/base/ship.cc')
-rw-r--r-- | src/game/base/ship.cc | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index 5be9a00..2a5d68f 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -1194,14 +1194,16 @@ void Ship::frame_autopilot(const unsigned long elapsed) const float dock_distance = (autopilot_target()->moduletype() == planet_enttype ? r + PLANET_SAFE_DISTANCE : r); if (!has_target_controlflag(core::EntityControlable::ControlFlagOverride)) { - // thruster and speed control - if (has_autopilot_flag(AutoPilotFormation) && (distance < 4.0f * r)) { + if (has_autopilot_flag(AutoPilotCombat) && (distance < r + COMBAT_DISTANCE)) { + frame_autopilot_combat(elapsed, autopilot_target()); + + } else 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()); } @@ -1292,6 +1294,63 @@ void Ship::frame_autopilot_goto(const unsigned long elapsed, core::Entity *targe } } +void Ship::frame_autopilot_combat(const unsigned long elapsed, core::Entity *target) +{ + if ((state() == core::Entity::Impulse) || (state() == core::Entity::ImpulseInitiate)) { + func_impulse(); + } + + // desired direction + math::Vector3f direction(target->location() - location()); + const float distance = direction.length(); + // normalize + direction /= distance; + + // transform direction from world coordinates to local entity coordinates + direction = axis().transpose() * direction; + + if (direction.x() < 0) { + // target is behind the ship + target_direction = (direction.y() > 0 ? 1.0f : -1.0f); + target_pitch = 0.0f; + + } else if (direction.x() + MIN_DELTA < 1.0f) { + // target is in front of the ship + target_direction = direction.y(); + target_pitch = direction.z(); + } else { + target_direction = 0.0f; + target_pitch = 0.0f; + } + + // transform the target's axis into local coordinates + const math::Axis reference(axis().transpose() * target->axis()); + if (reference.up().z() < 0.0f) { + // upward-down + target_roll = (reference.up().y() > 0 ? 1.0f : 0.0f); + + } else if (reference.up().z() + MIN_DELTA < 1.0f) { + target_roll = reference.up().y(); + + } else { + target_roll = 0.0f; + } + + // reference radius used in calculations + const float r = radius() + target->radius(); + + // thruster + if (distance > 2.0f * r) { + target_thrust = 1.0f; + + } else if (distance > r ) { + target_thrust = math::max(0.1f, (distance - r ) / r); + + } else { + target_thrust = 0.0f; + } +} + void Ship::frame_autopilot_dock(const unsigned long elapsed, core::Entity *target) { // reference radius used in calculations @@ -1300,10 +1359,7 @@ void Ship::frame_autopilot_dock(const unsigned long elapsed, core::Entity *targe if ((state() == core::Entity::Impulse) || (state() == core::Entity::ImpulseInitiate)) { func_impulse(); - return; - } - - if (state() != core::Entity::Normal) { + } else if (state() != core::Entity::Normal) { return; } |