From 0d6ad95226f7d17cd4bed567ec622046feb4aab3 Mon Sep 17 00:00:00 2001 From: NiteKat Date: Wed, 1 Jan 2025 05:10:02 -0500 Subject: [PATCH 1/2] Fix Larva Build Queue Fixes issue where a Larva's build queue can have hanging items causing problems with morph commands on the larva or Hydralisks and Mutalisks by having a morph command and stop command issued on the same frame. This ensures the build_queue is clear before attempting to add the desired unit type to the build_queue. Directly erasing maintains the 1.16.1 behavior of the resources still being consumed by this situation, while keeping the larva and it's future unit type functioning properly as in 1.16.1. --- actions.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/actions.h b/actions.h index 5a0ad23..da9e3a9 100644 --- a/actions.h +++ b/actions.h @@ -878,6 +878,9 @@ struct action_functions: state_functions { if (!unit_can_build(u, unit_type)) continue; } else continue; if (u->order_type->id == Orders::ZergUnitMorph) continue; + while (!u->build_queue.emtpy()) { + u->build_queue.erase(u->build_queue.begin()); + } if (!build_queue_push(u, unit_type)) continue; set_unit_order(u, get_order_type(Orders::ZergUnitMorph)); retval = true; From 609a00e289603522a94b5db11218b160f03e1836 Mon Sep 17 00:00:00 2001 From: NiteKat Date: Wed, 1 Jan 2025 18:45:33 -0500 Subject: [PATCH 2/2] Special Case Lurker Devourer And Guardian This removes the loop I made to clear build queues for larva - this deviates from BW behavior in edge cases since in 1.16 and Remaster you can brick a larva with morph/stop on same frame 5 times, and previous fix prevented that. I observed that 1.16 puts the Lurker/Guardian/Devourer types at the front of the build queue on the unit instead of the back. In OpenBW there is no function to do this with a static_vector, so if it pushes to the end successfully I check if it is a Lurker/Guardian/Devourer morph, then push indexes 0 through 3 down 1, then puts the correct unit type (what was pushed to the end) at the front of the build_queue. Behaviorally this is what BW does, but I'm not sure it does it exactly this way. I feel this would be cleaner if there was a way to push to the front of the build queue, but that doesn't exist for a static_vector from what I can see. --- actions.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/actions.h b/actions.h index da9e3a9..4751681 100644 --- a/actions.h +++ b/actions.h @@ -878,10 +878,12 @@ struct action_functions: state_functions { if (!unit_can_build(u, unit_type)) continue; } else continue; if (u->order_type->id == Orders::ZergUnitMorph) continue; - while (!u->build_queue.emtpy()) { - u->build_queue.erase(u->build_queue.begin()); - } if (!build_queue_push(u, unit_type)) continue; + if ((unit_is(u, UnitTypes::Zerg_Hydralisk) && unit_is(unit_type, UnitTypes::Zerg_Lurker)) || (unit_is(u, UnitTypes::Zerg_Mutalisk) && (unit_is(unit_type, UnitTypes::Zerg_Guardian) || unit_is(unit_type, UnitTypes::Zerg_Devourer)))) { + for (int i = 3; i >= 0; i--) + u->build_queue[i + 1] = u->build_queue[i]; + u->build_queue[0] = unit_type; + } set_unit_order(u, get_order_type(Orders::ZergUnitMorph)); retval = true; }