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/npc.cc')
-rw-r--r--src/game/base/npc.cc106
1 files changed, 87 insertions, 19 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();
}