From aabb379d84afab3679acc6dc4472d886dae88f39 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Mon, 14 Oct 2013 20:33:50 +0000 Subject: Separated autopilot from AI code, added basic formation flying. --- src/game/base/ship.cc | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) (limited to 'src/game/base/ship.cc') diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index 6c5598e..23baa5d 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -990,4 +990,146 @@ void Ship::frame(const unsigned long elapsed) } +void Ship::frame_autopilot_goto(const unsigned long elapsed, const core::Entity *target) +{ + // reference radius used in calculations + const float r = radius() + target->radius(); + + // desired direction + math::Vector3f direction(target->location() - location()); + const float distance = direction.length(); + direction.normalize(); + + // transform direction from world coordinates to local entity coordinates + direction = axis().transpose() * direction; + + if (direction.x() < 0) { + // target is behind the ship + target_direction = math::sgnf(direction.y()); + 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; + } + + target_roll = 0.0f; + + // impulse or thruster + if (distance > r + 50.0f) { + + if (state() == core::Entity::Normal) { + // enable impulse drive + func_impulse(); + } + + } else { + + if (target->type() == core::Entity::Controlable) { + + const core::EntityControlable *controlable = static_cast(target); + + if (state() == core::Entity::Impulse) { + + if (controlable->state() != core::Entity::Impulse) { + // disbable impulse drive + func_impulse(); + } + + } else if (state() == core::Entity::Normal) { + + if ((controlable->state() == core::Entity::Impulse) || (controlable->state() == core::Entity::ImpulseInitiate)) { + // enable impulse drive + func_impulse(); + } + } + + } else { + + if (state() == core::Entity::Impulse) { + func_impulse(); + } + } + } + + // thruster + 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 { + target_thrust = 0.0f; + + // TODO autolevel + } +} + +void Ship::frame_autopilot_formation(const unsigned long elapsed, const core::Entity *target) +{ + // transform the target's axis into local coordinates + const math::Axis reference(axis().transpose() * target->axis()); + + //const float distance = math::distance(location(), target->location()); + //const float r = radius() + target->radius(); + + if (reference.forward().x() < 0) { + // target is behind the ship + target_direction = math::sgnf(reference.forward().y()); + target_pitch = 0.0f; + target_roll = 0.0f; + + } else if (reference.forward().x() + MIN_DELTA < 1.0f) { + // target is in front of the ship + target_direction = reference.forward().y(); + target_pitch = reference.forward().z(); + target_roll = 0.0f; + + } else { + target_direction = 0.0f; + target_pitch = 0.0f; + + if (reference.up().z() < 0) { + // upward-down + target_roll = math::sgnf(reference.up().y()); + } else { + target_roll = reference.up().y(); + } + } + + if (target->type() == core::Entity::Controlable) { + + const core::EntityControlable *controlable = static_cast(target); + + target_thrust = controlable->thrust(); + + if (state() == core::Entity::Impulse) { + + if (controlable->state() != core::Entity::Impulse) { + // disbable impulse drive + func_impulse(); + } + + } else if (state() == core::Entity::Normal) { + + if ((controlable->state() == core::Entity::Impulse) || (controlable->state() == core::Entity::ImpulseInitiate)) { + // enable impulse drive + func_impulse(); + } + } + + } else { + if (state() == core::Entity::Impulse) { + // disable impulse drive + func_impulse(); + } + } + +} + } // namespace game -- cgit v1.2.3