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/patrol.cc | 268 +++++++++++++++++++++++++++++------------------- 1 file changed, 163 insertions(+), 105 deletions(-) (limited to 'src/game/base/patrol.cc') diff --git a/src/game/base/patrol.cc b/src/game/base/patrol.cc index fbe02df..d1bbe15 100644 --- a/src/game/base/patrol.cc +++ b/src/game/base/patrol.cc @@ -197,6 +197,33 @@ void Patrol::validate() } } +void Patrol::print() const +{ + core::Entity::print(); + con_print << " ^Nprofile ^B"; + switch (profile()) { + case(ProfileFreelancer): + con_print << "freelancer"; + break; + case(ProfileConvoy): + con_print << "convoy"; + break; + case(ProfilePatrol): + con_print << "patrol"; + break; + case(ProfileGuard): + con_print << "guard"; + break; + case(ProfileWingman): + con_print << "wingman"; + break; + } + con_print << std::endl; + con_print << " ^Nwaypoints ^B" << patrol_waypoints.size() << std::endl; + con_print << " ^Nnpc types ^B" << patrol_npctypes.size() << std::endl; + con_print << " ^Nmembers ^B" << patrol_members.size() << std::endl; +} + Patrol::WayPoint *Patrol::add_waypoint() { WayPoint *waypoint = new WayPoint(); @@ -269,123 +296,133 @@ bool Patrol::route_alive() const return false; } -void Patrol::frame(const unsigned long elapsed) -{ - if (patrol_waypoints.size() < 2) { - return; +void Patrol::create_patrol() +{ + if (patrol_waypoint_current == patrol_waypoints.end() || !(*patrol_waypoint_current)->dock()) { + patrol_waypoint_current = patrol_waypoints.begin(); } - - if (patrol_members.size() == 0) { - // there are no members, verify if the spawn zone has players in it and create a new patrol - if (patrol_waypoint_current == patrol_waypoints.end() || !(*patrol_waypoint_current)->dock()) { - patrol_waypoint_current = patrol_waypoints.begin(); - } - if (route_alive()) { - core::Entity *spawn = waypoint()->target(); - - if (spawn->has_flag(core::Entity::Dockable)) { - // create NPC members for every NPC type - for (NPCTypes::const_iterator it = patrol_npctypes.begin(); it != patrol_npctypes.end(); ++it) { - - NPCType *npctype = (*it); - - if (!npctype->shipmodel()) { - continue; - } + core::Entity *spawn = waypoint()->target(); + + if (spawn->has_flag(core::Entity::Dockable)) { + + // create NPC members for every NPC type + for (NPCTypes::const_iterator it = patrol_npctypes.begin(); it != patrol_npctypes.end(); ++it) { + + NPCType *npctype = (*it); + + if (!npctype->shipmodel()) { + continue; + } + + if (npctype->amount() <= 0) { + continue; + } + + const size_t nbships = 1 + math::randomi((unsigned int) npctype->amount()); + for (size_t i = 0; i < nbships; i++) { + + // add NPC + NPC *npc = new NPC(npctype->shipmodel()); + npc->set_mood(NPC::MoodFormation); + + // set NPC name + if (npctype->name().size()) { + std::string str(npctype->name()); + npc->set_name(str); - if (npctype->amount() <= 0) { - continue; + aux::to_label(str); + npc->set_label(str); + } + + // set NPC color + if (npctype->faction()) { + npctype->faction()->apply(npc); + } else if (faction()) { + faction()->apply(npc); + } + + // patrol ships are not dockable + if (npc->has_flag(core::Entity::Dockable)) { + unset_flag(core::Entity::Dockable); + // delete menus + for (Menus::iterator mit = npc->menus().begin(); mit != npc->menus().end(); ++mit) { + delete (*mit); + (*mit) = 0; } + npc->menus().clear(); + } + + // install inventory + if (!npc->inventory()) { + npc->add_inventory(); + } + + // install slots + if (!npc->slots()) { + npc->add_slots(); + slots()->load(model()); + } + + // install weapons + for (core::Slots::iterator slit = npc->slots()->begin(); slit != npc->slots()->end(); ++slit) { + core::Slot *slot = (*slit); - const size_t nbships = 1 + math::randomi((unsigned int) npctype->amount()); - for (size_t i = 0; i < nbships; i++) { + core::Item *item = 0; - // add NPC - NPC *npc = new NPC(npctype->shipmodel()); - npc->set_mood(NPC::MoodFormation); - - // set NPC name - if (npctype->name().size()) { - npc->set_name(npctype->name()); - } - - // set NPC color - if (npctype->faction()) { - npctype->faction()->apply(npc); - } else if (faction()) { - faction()->apply(npc); - } - - // patrol ships are not dockable - if (npc->has_flag(core::Entity::Dockable)) { - unset_flag(core::Entity::Dockable); - // delete menus - for (Menus::iterator mit = npc->menus().begin(); mit != npc->menus().end(); ++mit) { - delete (*mit); - (*mit) = 0; - } - npc->menus().clear(); + if (slot->type() == model::Weapon::Cannon) { + if (npctype->cannon()) { + item = new core::Item(npctype->cannon()); } - - // install inventory - if (!npc->inventory()) { - npc->add_inventory(); + } else if (slot->type() == model::Weapon::Turret) { + if (npctype->turret()) { + item = new core::Item(npctype->turret()); } + } + + if (item) { + // add item + item->set_flag(core::Item::Unique); + item->set_flag(core::Item::Mountable); + item->set_flag(core::Item::Unrestricted); + item->set_amount(1); + npc->inventory()->add(item); - // install slots - if (!npc->slots()) { - npc->add_slots(); - slots()->load(model()); - } - - // install weapons - for (core::Slots::iterator slit = npc->slots()->begin(); slit != npc->slots()->end(); ++slit) { - core::Slot *slot = (*slit); - - core::Item *item = 0; - - if (slot->type() == model::Weapon::Cannon) { - if (npctype->cannon()) { - item = new core::Item(npctype->cannon()); - } - } else if (slot->type() == model::Weapon::Turret) { - if (npctype->turret()) { - item = new core::Item(npctype->turret()); - } - } - - if (item) { - // add item - item->set_flag(core::Item::Unique); - item->set_flag(core::Item::Mountable); - item->set_flag(core::Item::Unrestricted); - item->set_amount(1); - npc->inventory()->add(item); - - // mount weapon - slot->set_item(item); - slot->set_flag(core::Slot::Active); - slot->set_flag(core::Slot::Mounted); - } - } - - npc->inventory()->recalculate(); - - // dock npc at spawn - npc->set_zone(spawn->zone()); - npc->set_dock(spawn); - - // add NPC to patrol - add_member(npc); + // mount weapon + slot->set_item(item); + slot->set_flag(core::Slot::Active); + slot->set_flag(core::Slot::Mounted); } } - set_leader(); + npc->inventory()->recalculate(); + + // dock npc at spawn + npc->set_zone(spawn->zone()); + npc->set_dock(spawn); - patrol_launch_timeout = core::server()->timestamp() + 15000 + (unsigned long) math::randomi(30000); + // add NPC to patrol + add_member(npc); } } + + set_leader(); + + patrol_launch_timeout = core::server()->timestamp() + 15000 + (unsigned long) math::randomi(30000); + } +} +void Patrol::frame(const unsigned long elapsed) +{ + if (patrol_waypoints.size() < 2) { + return; + } + + if (patrol_members.size() == 0) { + if (route_alive()) { + create_patrol(); + } + return; + } else if (patrol_leader) { if (patrol_leader->state() == core::Entity::Docked) { @@ -468,12 +505,31 @@ void Patrol::frame(const unsigned long elapsed) } else if ((patrol_leader->state() == core::Entity::Normal) || (patrol_leader->state() == core::Entity::ImpulseInitiate) || (patrol_leader->state() == core::Entity::Impulse)) { - if (waypoint()->target()->zone() == patrol_leader->zone()) { + Ship *enemy = 0; + + if (profile() == ProfilePatrol) { + enemy = patrol_leader->target_closest_enemy(); + } + + if (enemy) { + // combat conditions + if (patrol_leader->autopilot_target() != enemy) { + patrol_leader->set_autopilot_target(enemy); + } + patrol_leader->set_autopilot_flag(Ship::AutoPilotEnabled); + patrol_leader->set_autopilot_flag(Ship::AutoPilotCombat); + patrol_leader->unset_autopilot_flag(Ship::AutoPilotFormation); + patrol_leader->unset_autopilot_flag(Ship::AutoPilotDock); + + } else if (waypoint()->target()->zone() == patrol_leader->zone()) { + + // current waypoint is in this zone patrol_leader->set_autopilot_target(waypoint()->target()); patrol_leader->set_autopilot_flag(Ship::AutoPilotEnabled); patrol_leader->unset_autopilot_flag(Ship::AutoPilotFormation); + patrol_leader->unset_autopilot_flag(Ship::AutoPilotCombat); if ( (waypoint()->dock()) && (waypoint()->target()->has_flag(core::Entity::Dockable)) ) { patrol_leader->set_autopilot_flag(Ship::AutoPilotDock); @@ -505,10 +561,12 @@ void Patrol::frame(const unsigned long elapsed) } } } + } else { // current waypoint is in different zone + patrol_leader->unset_autopilot_flag(Ship::AutoPilotCombat); - // check if a jumpgate got use here + // check if the leader got here through a jumpgate JumpGate *jumpgate = (waypoint()->target()->moduletype() == jumpgate_enttype ? static_cast(waypoint()->target()) : 0 ); if (jumpgate && jumpgate->target()->zone() == patrol_leader->zone()) { @@ -537,7 +595,7 @@ void Patrol::frame(const unsigned long elapsed) } } else { - // we're lost: delete patrol + // we're lost: delete patrol members for (Members::iterator it = patrol_members.begin(); it != patrol_members.end(); ++it) { (*it)->die(); -- cgit v1.2.3