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.cc115
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());