Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/base/ship.cc')
-rw-r--r--src/game/base/ship.cc142
1 files changed, 142 insertions, 0 deletions
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<const core::EntityControlable *>(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<const core::EntityControlable *>(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