Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/base/npc.cc106
-rw-r--r--src/game/base/npc.h2
-rw-r--r--src/game/base/ship.cc29
-rw-r--r--src/game/base/ship.h5
4 files changed, 104 insertions, 38 deletions
diff --git a/src/game/base/npc.cc b/src/game/base/npc.cc
index 0dd33c8..ec43ea0 100644
--- a/src/game/base/npc.cc
+++ b/src/game/base/npc.cc
@@ -14,6 +14,9 @@
namespace game {
+const float NPC_WIMPY = 20.0f; // indicates the health percentage at which the NPC willtry to repair itself
+const float NPC_REPAIR_ARMOR_PER_SECOND = 25.0f; // repair rate in units of armor per second
+
// NPC Wingman factory function
NPC *NPC::add_wingman(Ship *leader)
{
@@ -77,6 +80,7 @@ NPC::NPC(const ShipModel *shipmodel) : Ship(0, shipmodel)
{
npc_mood = MoodWander;
npc_destroyed_timestamp = 0;
+ npc_repair_timestamp = 0;
npc_patrol = 0;
npc_leader = 0;
@@ -250,10 +254,11 @@ void NPC::frame(const unsigned long elapsed)
explode();
npc_destroyed_timestamp = core::game()->time();
- } else if (leader()->zone() == zone()) {
+ } else if (leader()->zone() == zone()) {
// leader is in this zone
- if (leader()->state() == Docked) {
+ if (leader()->state() == Docked)
+ {
if (state() != core::Entity::Docked) {
@@ -279,27 +284,89 @@ void NPC::frame(const unsigned long elapsed)
} else {
- if (state() == core::Entity::Docked) {
- // FIXME check launch conditions when docked at another player's ship
- launch();
-
- } else {
- Ship *enemy = target_closest_enemy();
-
- if (enemy && leader()->has_autopilot_flag(Ship::AutoPilotCombat)) {
- set_autopilot_target(enemy);
+ if (state() == core::Entity::Docked)
+ {
+ if (!core::Entity::find(dock()))
+ {
+ // dock doesn't exist any more
+ set_dock(0);
+ npc_repair_timestamp = 0;
+ nudge(true);
+ set_state(Entity::Normal);
+ set_dirty();
- set_autopilot_flag(Ship::AutoPilotEnabled);
- set_autopilot_flag(Ship::AutoPilotCombat);
- unset_autopilot_flag(Ship::AutoPilotDock);
- unset_autopilot_flag(Ship::AutoPilotFormation);
} else {
+ // check if our dock might be noving
+ if (dock()->moduletype() == ship_enttype)
+ {
+ Ship *carrier = static_cast<Ship *>(dock());
+ if (zone() != carrier->zone())
+ {
+ set_zone(carrier->zone());
+ }
+ set_location(carrier->location());
+ set_axis(carrier->axis());
+
+ if (carrier->state() == core::Entity::Destroyed)
+ {
+ explode();
+
+ } else if ((carrier == leader()) && (armor() < maxarmor()))
+ {
+ // repair
+ const unsigned long now = core::game()->timestamp();
+
+ if (npc_repair_timestamp == 0)
+ {
+ npc_repair_timestamp = now;
+ } else {
+ while (npc_repair_timestamp + 1000 < now)
+ {
+ set_armor(armor() + NPC_REPAIR_ARMOR_PER_SECOND);
+ npc_repair_timestamp += 1000;
+ }
+ }
+ } else
+ {
+ npc_repair_timestamp = 0;
+ if (carrier->state() == core::Entity::Normal)
+ {
+ launch();
+ }
+ }
+ } else {
+ launch();
+ }
+ }
+ } else {
+ if (leader()->has_flag(core::Entity::Dockable) && (health() < NPC_WIMPY))
+ {
set_autopilot_target(leader());
-
+
set_autopilot_flag(Ship::AutoPilotEnabled);
unset_autopilot_flag(Ship::AutoPilotCombat);
- unset_autopilot_flag(Ship::AutoPilotDock);
- set_autopilot_flag(Ship::AutoPilotFormation);
+ set_autopilot_flag(Ship::AutoPilotDock);
+ unset_autopilot_flag(Ship::AutoPilotFormation);
+ } else
+ {
+ Ship *enemy = target_closest_enemy();
+
+ if (enemy && leader()->has_autopilot_flag(Ship::AutoPilotCombat)) {
+ set_autopilot_target(enemy);
+
+ set_autopilot_flag(Ship::AutoPilotEnabled);
+ set_autopilot_flag(Ship::AutoPilotCombat);
+ unset_autopilot_flag(Ship::AutoPilotDock);
+ unset_autopilot_flag(Ship::AutoPilotFormation);
+ } else
+ {
+ set_autopilot_target(leader());
+
+ set_autopilot_flag(Ship::AutoPilotEnabled);
+ unset_autopilot_flag(Ship::AutoPilotCombat);
+ unset_autopilot_flag(Ship::AutoPilotDock);
+ set_autopilot_flag(Ship::AutoPilotFormation);
+ }
}
}
}
@@ -318,7 +385,8 @@ void NPC::frame(const unsigned long elapsed)
target_afterburner = 0.0f;
target_thrust = 0;
- if (state() == core::Entity::Impulse) {
+ if (state() == core::Entity::Impulse)
+ {
func_impulse();
}
diff --git a/src/game/base/npc.h b/src/game/base/npc.h
index 411f807..4469517 100644
--- a/src/game/base/npc.h
+++ b/src/game/base/npc.h
@@ -114,6 +114,8 @@ private:
unsigned long npc_destroyed_timestamp;
+ unsigned long npc_repair_timestamp;
+
float npc_weapon_range;
core::Player *npc_commander;
diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc
index 0dd5415..dbf8b19 100644
--- a/src/game/base/ship.cc
+++ b/src/game/base/ship.cc
@@ -121,12 +121,7 @@ Ship::Ship(core::Player *owner, const ShipModel *shipmodel) : core::EntityContro
set_flag(core::Entity::Dockable);
}
- ship_armor = maxarmor();
-
- // initialize physics
- // FIXME probably should not be called here
- //reset();
- //body()->setDamping(ship_shipmodel->linear_damping(), ship_shipmodel->angular_damping());
+ set_armor(maxarmor());
}
Ship::~Ship()
@@ -423,7 +418,7 @@ void Ship::explode()
entity_thrust = 0;
- ship_armor = 0;
+ set_armor(0);
set_state(core::Entity::Destroyed);
@@ -589,7 +584,14 @@ void Ship::set_spawn(core::Entity *spawn)
{
ship_spawn = spawn;
}
-
+
+void Ship::set_armor(const float armor)
+{
+ ship_armor = armor;
+ math::clamp(ship_armor, 0.0f, maxarmor());
+ entity_health = ship_armor * 100.0f / maxarmor();
+}
+
void Ship::action (btScalar seconds)
{
float engine_force = 0;
@@ -678,11 +680,11 @@ void Ship::hit(core::Entity *other)
// hit by a mine
SpaceMine * spacemine = static_cast<SpaceMine *>(other);
if (spacemine->state() != core::Entity::Destroyed) {
- ship_armor -= spacemine->damage();
+ set_armor(armor() - spacemine->damage());
}
// destroyed
- if (ship_armor <= 0) {
+ if (armor() <= 0) {
explode();
core::Player *assassin = 0;
@@ -735,7 +737,7 @@ void Ship::hit(core::Entity *other)
// don't hit self
if ((projectile->state() != core::Entity::Destroyed) && (projectile->spawn_id() != id())) {
- ship_armor -= projectile->damage();
+ set_armor(armor() - projectile->damage());
core::Player *assassin = 0;
@@ -744,7 +746,7 @@ void Ship::hit(core::Entity *other)
}
// destroyed
- if (ship_armor <= 0) {
+ if (armor() <= 0) {
explode();
if (owner()) {
@@ -1070,9 +1072,6 @@ void Ship::frame(const unsigned long elapsed)
}
}
- // current health
- entity_health = armor() * 100.0f / maxarmor();
-
/* -- SNAPPY ------------------------------------------ */
current_target_afterburner = target_afterburner;
diff --git a/src/game/base/ship.h b/src/game/base/ship.h
index 4b4ae61..db41ba0 100644
--- a/src/game/base/ship.h
+++ b/src/game/base/ship.h
@@ -179,10 +179,7 @@ public:
}
/// set current armor strength (current health)
- inline void set_armor(const float armor)
- {
- ship_armor = armor;
- }
+ void set_armor(const float armor);
/// set maximal shield strength
inline void set_maxshield(const float maxshield)