From e4b437cb5f0bab31984d267e642c44ea6cf32006 Mon Sep 17 00:00:00 2001 From: regneq Date: Sun, 31 Jan 2021 15:11:45 -0800 Subject: [PATCH] RandomPath grid type improvement RandomPath has been changed to the following behavior: * When stopped at a waypoint, it will now use the waypoint's pause timer if it is non-zero. If it is zero, it will use the first waypoint's pause timer if that is non-zero. If both are zero it will use 38 seconds. Previously it would always use the first waypoint's pause timer if it was non-zero. This new way is what it should have been from the start, really. * If any waypoint is flagged as a centerpoint, then the NPCs will always return to that first randomly selected centerpoint waypoint after moving. I.e. every other move will be to the first waypoint if the bool is set. If any waypoint has a negative number (-1, -10, etc) in the pause timer. It will not be included in the waypoints to be random. Instead the npc will just path through it everytime. This is useful for a path to only select a small area to pause at before returning to it's centerpoints or another random waypoints in between it. --- zone/mob_ai.cpp | 4 +++- zone/waypoints.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 9d0ea02be..517c8eeb2 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1723,7 +1723,9 @@ void NPC::AI_DoMovement() { // reached our randomly selected destination; force a pause if (cur_wp_pause == 0) { - if (Waypoints.size() > 0 && Waypoints[0].pause) + if (Waypoints.size() >= cur_wp && Waypoints[cur_wp].pause) + cur_wp_pause = Waypoints[cur_wp].pause; + else if (Waypoints.size() > 0 && Waypoints[0].pause) cur_wp_pause = Waypoints[0].pause; else cur_wp_pause = 38; diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 1beca2c01..f88c4df39 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -385,8 +385,49 @@ void NPC::CalculateNewWaypoint() { if (cur_wp == patrol) // reutilizing patrol member instead of making new member for this wander type; here we use it to save a random waypoint { + if (!Waypoints[cur_wp].centerpoint) + { + // if we have arrived at a waypoint that is NOT a centerpoint, then check for the existence of any centerpoint waypoint + // if any exists then randomly go to it otherwise go to one that exist. + std::vector random_centerpoints; + for (auto& w : Waypoints) + { + wplist wpl = w; + if (wpl.index != cur_wp && wpl.centerpoint) + { + random_centerpoints.push_back(w); + } + } + + if (random_centerpoints.size() == 1) + { + patrol = random_centerpoints[0].index; + break; + } + else if (random_centerpoints.size() > 1) + { + int windex = zone->random.Roll0(random_centerpoints.size()); + patrol = random_centerpoints[windex].index; + break; + } + } + while (patrol == cur_wp) - patrol = zone->random.Int(0, Waypoints.size() - 1); + { + // Setting a negative number in pause of the select waypoints will NOT be included in the group of waypoints to be random. + // This will cause the NPC to not stop and pause in any of the waypoints that is not part of random waypoints. + std::vector random_waypoints; + for (auto& w : Waypoints) + { + wplist wpl = w; + if (wpl.index != cur_wp && wpl.pause >= 0 && !wpl.centerpoint) + { + random_waypoints.push_back(w); + } + } + int windex = zone->random.Roll0(random_waypoints.size()); + patrol = random_waypoints[windex].index; + } } if (patrol > cur_wp) cur_wp = cur_wp + 1;