From 9dc3cc532820349a0f0e087afb60132927fd3411 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 10 Nov 2013 01:48:41 +0000 Subject: Corrected a bug which prevented the patrol profile from being set correctly, corrected a bug where 'give ship' would forget the last spawn, have NPC ships fire on nearby enemies, made patrol leaders hunt nearby enemies. --- src/game/base/npc.cc | 90 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 13 deletions(-) (limited to 'src/game/base/npc.cc') diff --git a/src/game/base/npc.cc b/src/game/base/npc.cc index fa0ef44..992ba6c 100644 --- a/src/game/base/npc.cc +++ b/src/game/base/npc.cc @@ -4,6 +4,8 @@ the terms of the GNU General Public License version 2 */ +#include "core/range.h" + #include "base/npc.h" #include "base/game.h" #include "base/patrol.h" @@ -99,6 +101,79 @@ void NPC::set_patrol(Patrol *patrol) npc_patrol = patrol; } +Ship *NPC::target_closest_enemy() +{ + // scan for enemies + Ship *current_enemy = 0; + float current_distance = 0.0f; + + + for (core::Zone::Content::iterator zit = zone()->content().begin(); zit != zone()->content().end(); ++zit) { + if (((*zit)->moduletype() == ship_enttype) && ((*zit) != this)) { + Ship *ship = static_cast((*zit)); + + if ((ship->state() != Normal) && (ship->state() != ImpulseInitiate) && (ship->state() != Impulse)) { + continue; + } + + const float d = math::distance(location(), ship->location()); + const float r = radius() + ship->radius(); + + // too far + if (d > r + core::range::fxdistance * 2.0f) { + continue; + } + + // further than current target + if ((current_distance > 0.0f) && (d > current_distance)) { + continue; + } + + float reputation = 0.0f; + if (ship->owner()) { + // check owner reputation for the faction the NPC belongs to + reputation = ship->owner()->reputation(faction()); + + } else if (faction() && (faction()->type() == Faction::infotype())) { + //check NPC faction reputation for the other ships's faction + reputation = static_cast(faction())->reputation(ship->faction()); + } + + // reputation threshold to get attacked + if (reputation >= -50.0f) { + continue; + } + + // reputation threshold to get hunted + if (d > core::range::fxdistance + r) { + + if ((!ship->owner()) || (reputation > -100.0f)) { + continue;; + } + } + + current_enemy = ship; + current_distance = d; + } + } + + // 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)) { + // activate weapons + set_target_controlflag(core::EntityControlable::ControlFlagFire); + // rudimentary aim currention + target_aim.assign(current_enemy->location() + current_enemy->axis().forward() * (current_enemy->radius() * 0.25f) ); + } else { + // deactivate weapons + unset_target_controlflag(core::EntityControlable::ControlFlagFire); + } + + return current_enemy; +} + void NPC::frame(const unsigned long elapsed) { if (state() == core::Entity::Destroyed) { @@ -107,13 +182,11 @@ void NPC::frame(const unsigned long elapsed) npc_destroyed_timestamp = core::game()->time(); } else if (npc_destroyed_timestamp + 10.0f < core::game()->time()) { - // stay alive for 10 more seconds while explosion particles are drawn - + // stay alive for 10 more seconds while explosion particles are drawn die(); } } else { - // TODO pilot magic and mood witchcraft if (leader()) { @@ -154,7 +227,6 @@ 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(); @@ -166,14 +238,7 @@ void NPC::frame(const unsigned long elapsed) unset_autopilot_flag(Ship::AutoPilotDock); set_autopilot_flag(Ship::AutoPilotFormation); - /* - if (leader()->has_target_controlflag(core::EntityControlable::ControlFlagFire)) { - set_target_controlflag(core::EntityControlable::ControlFlagFire); - target_aim.assign(leader()->aim()); - } else { - unset_target_controlflag(core::EntityControlable::ControlFlagFire); - } - */ + target_closest_enemy(); } } @@ -218,7 +283,6 @@ void NPC::frame(const unsigned long elapsed) target_thrust = 0; if (state() == core::Entity::Impulse) { - func_impulse(); } -- cgit v1.2.3