From c7455f12589b97612ebe928ed11881edf4c4aacc Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 6 Nov 2013 00:35:37 +0000 Subject: Added support for patrol routes with jumpgates. --- src/game/base/patrol.cc | 88 +++++++++++++++++++++++++++++++++++++++---------- src/game/base/patrol.h | 2 ++ 2 files changed, 72 insertions(+), 18 deletions(-) (limited to 'src/game') diff --git a/src/game/base/patrol.cc b/src/game/base/patrol.cc index c612d49..850efb9 100644 --- a/src/game/base/patrol.cc +++ b/src/game/base/patrol.cc @@ -122,7 +122,7 @@ void Patrol::validate() core::Zone *targetzone = 0; - size_t pos = waypoint->target_label().find(':'); + size_t pos = waypoint->target_label().find(':'); if ((pos == std::string::npos) || (pos < 1) || (pos >= (waypoint->target_label().size() - 1))) { targetzone = zone(); @@ -132,7 +132,8 @@ void Patrol::validate() zonelabel.assign(waypoint->target_label().substr(0, pos)); entitylabel.assign(waypoint->target_label().substr(pos + 1, waypoint->target_label().size() - pos)); - core::Zone::find(zonelabel); + targetzone = core::Zone::find(zonelabel); + if (!targetzone) { con_warn << " Patrol '" << label() << "' waypoint " << waypoint_counter << " has invalid target zone '" << zonelabel << "'\n"; break; @@ -246,6 +247,22 @@ void Patrol::set_leader() } } +// return true is any of the zones of any waypoint in this patrol has players in it +bool Patrol::route_alive() const +{ + if (zone()->keepalive_run()) { + return true; + } + + for (WayPoints::const_iterator it = patrol_waypoints.begin(); it != patrol_waypoints.end(); ++it) { + if ((*it)->target()->zone()->keepalive_run()) { + return true; + } + } + + return false; +} + void Patrol::frame(const unsigned long elapsed) { if (patrol_waypoints.size() < 2) { @@ -253,13 +270,11 @@ void Patrol::frame(const unsigned long elapsed) } if (patrol_members.size() == 0) { - if (zone()->keepalive_run()) { - // 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 = patrol_waypoints.begin(); - } - + // 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)) { @@ -325,8 +340,7 @@ void Patrol::frame(const unsigned long elapsed) if (patrol_leader->dock() == waypoint()->target()) { - if (zone()->keepalive_run()) { - + if (route_alive()) { // verify everyone in the patrol is docked bool group_docked = true; for (Members::iterator it = patrol_members.begin(); it != patrol_members.end(); ++it) { @@ -401,8 +415,6 @@ 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)) { -// patrol_launch_timeout = 0; - if (waypoint()->target()->zone() == patrol_leader->zone()) { patrol_leader->set_autopilot_target(waypoint()->target()); @@ -418,11 +430,13 @@ void Patrol::frame(const unsigned long elapsed) if ( math::distance(patrol_leader->location(), waypoint()->target()->location()) < PLANET_SAFE_DISTANCE + patrol_leader->radius() + waypoint()->target()->radius() ) { - // check if other group memebers are near + // check if other patrol memebers are near bool group_present = true; for (Members::iterator it = patrol_members.begin(); it != patrol_members.end(); ++it) { - if ( math::distance(patrol_leader->location(), (*it)->location()) > 4.0f * (patrol_leader->radius() + (*it)->radius()) ) { + if ((*it)->zone() != patrol_leader->zone()) { group_present = false; + } else if ( math::distance(patrol_leader->location(), (*it)->location()) > 4.0f * (patrol_leader->radius() + (*it)->radius()) ) { + group_present = false; } } @@ -438,11 +452,49 @@ void Patrol::frame(const unsigned long elapsed) } } } - } else { - patrol_leader->set_autopilot_target(0); - } + // current waypoint is in different zone + + // check if a jumpgate got use here + JumpGate *jumpgate = (waypoint()->target()->moduletype() == jumpgate_enttype ? static_cast(waypoint()->target()) : 0 ); + if (jumpgate && jumpgate->target()->zone() == patrol_leader->zone()) { + + // check if other patrol memebers are near + bool group_present = true; + for (Members::iterator it = patrol_members.begin(); it != patrol_members.end(); ++it) { + if ((*it)->zone() != patrol_leader->zone()) { + group_present = false; + } else if ( math::distance(patrol_leader->location(), (*it)->location()) > 4.0f * (patrol_leader->radius() + (*it)->radius()) ) { + group_present = false; + } + } + + // next waypoint + if (group_present) { + patrol_waypoint_current++; + if (patrol_waypoint_current == patrol_waypoints.end()) { + patrol_waypoint_current = patrol_waypoints.begin(); + } + patrol_leader->set_autopilot_target(waypoint()->target()); + } else { + // cruise away from the jumpgate until patrol memebers arrive + patrol_leader->set_autopilot_target(jumpgate->target()); + patrol_leader->unset_autopilot_flag(Ship::AutoPilotEnabled); + patrol_leader->set_target_thrust(0.25f); + } + + } else { + // we're lost: delete patrol + for (Members::iterator it = patrol_members.begin(); it != patrol_members.end(); ++it) { + (*it)->die(); + + } + } + + } + } else { + patrol_leader->set_autopilot_target(0); } } diff --git a/src/game/base/patrol.h b/src/game/base/patrol.h index 4c612fe..0e03234 100644 --- a/src/game/base/patrol.h +++ b/src/game/base/patrol.h @@ -118,6 +118,8 @@ public: private: void set_leader(); + bool route_alive() const; + WayPoints patrol_waypoints; WayPoints::iterator patrol_waypoint_current; -- cgit v1.2.3