From f009487bbe6120f8f487302f5e1bb4ae606a51af Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 10 Nov 2013 19:01:43 +0000 Subject: Made NPCs only fire weapons on enemies within weapon range. --- src/game/base/npc.cc | 44 ++++++++++++++++++++++++++++++++++++++++---- src/game/base/npc.h | 9 ++++++++- src/game/base/patrol.cc | 2 ++ src/game/base/ship.cc | 2 +- src/game/base/weapon.h | 8 ++++++++ 5 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/game/base/npc.cc b/src/game/base/npc.cc index ca2a1c2..bb716c9 100644 --- a/src/game/base/npc.cc +++ b/src/game/base/npc.cc @@ -65,6 +65,8 @@ NPC *NPC::add_wingman(Ship *leader) npc_slot->set_flag(core::Slot::Mounted); } + npc->calculate_weapon_range(); + npc->reset(); return npc; @@ -77,6 +79,8 @@ NPC::NPC(const ShipModel *shipmodel) : Ship(0, shipmodel) npc_patrol = 0; npc_leader = 0; + + npc_weapon_range = 0.0f; } NPC::~NPC() @@ -86,6 +90,38 @@ NPC::~NPC() } } +void NPC::calculate_weapon_range() +{ + npc_weapon_range = 0.0f; + + if (!slots()) { + return; + } + + for (core::Slots::const_iterator it = slots()->begin(); it != slots()->end(); it++) { + core::Slot *slot = (*it); + + if (!slot->has_flag(core::Slot::Mounted)) { + continue; + + } else if (!slot->item() || (slot->item()->info()->type() != Weapon::infotype())) { + continue; + + } else { + const Weapon *weapon = static_cast(slot->item()->info()); + + if ((weapon->subtype() != Weapon::Cannon) && (weapon->subtype() != Weapon::Turret) ) { + continue; + } + const float r = weapon->projectile_range(); + + if (r > npc_weapon_range) { + npc_weapon_range = r; + } + } + } +} + void NPC::set_mood(const Mood mood) { npc_mood = mood; @@ -107,6 +143,9 @@ Ship *NPC::target_closest_enemy() Ship *current_enemy = 0; float current_distance = 0.0f; + if (!npc_weapon_range) { + return 0; + } for (core::Zone::Content::iterator zit = zone()->content().begin(); zit != zone()->content().end(); ++zit) { if (((*zit)->moduletype() == ship_enttype) && ((*zit) != this)) { @@ -149,11 +188,8 @@ Ship *NPC::target_closest_enemy() } } - // FIXME calculate weaposn range, arbitrarily set to 10 km - const float weapons_range = COMBAT_DISTANCE; - // set aim - if ((state() == Normal) && current_enemy && (current_distance <= weapons_range)) { + if ((state() == Normal) && current_enemy && (current_distance <= radius() + npc_weapon_range)) { // activate weapons set_target_controlflag(core::EntityControlable::ControlFlagFire); // rudimentary aim currention diff --git a/src/game/base/npc.h b/src/game/base/npc.h index 68620e1..39395c0 100644 --- a/src/game/base/npc.h +++ b/src/game/base/npc.h @@ -76,7 +76,6 @@ public: * */ virtual void frame(const unsigned long elapsed); - /** * @brief factory function for wingman NPCs * */ @@ -86,6 +85,12 @@ public: * @brief aim at closest enemy in range, returns target * */ Ship *target_closest_enemy(); + + /** + * @brief calculate weapon range + * Calling calculate_weapon_range() will set npc_weapon_range. + * */ + void calculate_weapon_range(); private: Mood npc_mood; @@ -96,6 +101,8 @@ private: unsigned long npc_destroyed_timestamp; + float npc_weapon_range; + }; // class NPC } // namespace game diff --git a/src/game/base/patrol.cc b/src/game/base/patrol.cc index 6640cb8..3df277a 100644 --- a/src/game/base/patrol.cc +++ b/src/game/base/patrol.cc @@ -362,6 +362,8 @@ void Patrol::create_patrol() npc->inventory()->recalculate(); + npc->calculate_weapon_range(); + // dock npc at spawn npc->set_zone(spawn->zone()); npc->set_dock(spawn); diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index 9c2605d..368fc11 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -1142,7 +1142,7 @@ void Ship::frame(const unsigned long elapsed) if (!slot->has_flag(core::Slot::Mounted)) { continue; - } else if ( !(slot->item() && (slot->item()->info()->type() == Weapon::infotype()))) { + } else if (!slot->item() || (slot->item()->info()->type() != Weapon::infotype())) { continue; } else { diff --git a/src/game/base/weapon.h b/src/game/base/weapon.h index ee67cfc..a6a5731 100644 --- a/src/game/base/weapon.h +++ b/src/game/base/weapon.h @@ -56,6 +56,14 @@ public: return weapon_projectile_speed; } + /** + * @brief projectile range, in game units + * */ + inline const float projectile_range() const + { + return (weapon_projectile_speed * ((float) weapon_projectile_lifespan) / 1000.0f); + } + /** * @brief interval between consequtive projectils fired by this weapon, in milliseconds * */ -- cgit v1.2.3