/* base/npc.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "base/npc.h" #include "base/game.h" namespace game { // NPC Wingman factory function NPC *NPC::add_wingman(Ship *leader) { if (!leader) { return 0; } if (leader->state() != Entity::Normal) { return 0; } NPC *npc = new NPC(ProfileWingman, leader->shipmodel()); npc->set_leader(leader); npc->set_owner(leader->owner()); npc->set_name("Wingman"); npc->set_mood(MoodFormation); npc->set_color(npc->leader()->color()); npc->set_color_second(npc->leader()->color_second()); npc->set_location(leader->location() - leader->axis().forward() * 2.0f * (leader->radius() + npc->radius())); npc->set_axis(leader->axis()); npc->set_zone(leader->zone()); npc->reset(); return npc; } NPC::NPC(const Profile profile, const ShipModel *shipmodel) : Ship(0, shipmodel) { npc_profile = profile; npc_mood = MoodWander; npc_destroyed_timestamp = 0; } void NPC::set_mood(const Mood mood) { npc_mood = mood; } void NPC::set_leader(Ship *leader) { npc_leader = leader; } void NPC::frame(const unsigned long elapsed) { if (state() == core::Entity::Destroyed) { if (!npc_destroyed_timestamp) { 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 die(); } } else { // TODO pilot magic and mood witchcraft if (leader()) { // verify leader still exists if (!core::Entity::find(leader())) { set_leader(0); explode(); npc_destroyed_timestamp = core::game()->time(); } else if (leader()->zone() == zone()) { if (leader()->state() == Docked) { // TODO dock where the leader is docked if (leader()->dock()) { frame_autopilot_goto(elapsed, leader()->dock()); } } else { if (math::distance(location(), leader()->location()) > 4.0f * ( radius() + leader()->radius())) { // goto the leader frame_autopilot_goto(elapsed, leader()); } else { // formatian flying frame_autopilot_formation(elapsed, leader()); } } } else { target_direction = 0; target_pitch = 0; target_roll = 0; target_strafe = 0.0f; target_vstrafe = 0.0f; target_afterburner = 0.0f; target_thrust = 0; if (state() == core::Entity::Impulse) { func_impulse(); } } } } // run a ship game frame Ship::frame(elapsed); } } // namespace game