From 243ef412d9abb609ec1ad6ed296056c6c7c3a063 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Mon, 22 Dec 2014 21:03:32 +0000 Subject: Wingmen will try to repair their ship if the leader has a carrier and health drops below 25%. --- src/game/base/npc.cc | 106 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 19 deletions(-) (limited to 'src/game/base/npc.cc') 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(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(); } -- cgit v1.2.3