From a0d4241b10e1e2f9c250033d404ec6545fd05923 Mon Sep 17 00:00:00 2001 From: TarnishedKnight Date: Thu, 10 Sep 2026 15:28:41 +0100 Subject: [PATCH 1/3] fix issue where ships could get incorrect pathmap blocking zones (#3132) * fix issue where ships could get incorrect pathmap blocking zones with underwater structures near coast lines. * rename isSubmersible to hasUnderwaterCollision --- rts/Sim/MoveTypes/MoveDefHandler.cpp | 4 ++-- rts/Sim/MoveTypes/MoveDefHandler.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rts/Sim/MoveTypes/MoveDefHandler.cpp b/rts/Sim/MoveTypes/MoveDefHandler.cpp index eb59743c08e..0b350377af5 100644 --- a/rts/Sim/MoveTypes/MoveDefHandler.cpp +++ b/rts/Sim/MoveTypes/MoveDefHandler.cpp @@ -51,7 +51,7 @@ CR_REG_METADATA(MoveDef, ( CR_MEMBER(followGround), CR_MEMBER(isSubmarine), - CR_MEMBER(isSubmersible), + CR_MEMBER(hasUnderwaterCollision), CR_MEMBER(overrideUnitWaterline), @@ -343,7 +343,7 @@ MoveDef::MoveDef(const LuaTable& moveDefTable): MoveDef() { } height = std::max(1, moveDefTable.GetInt("height", defaultHeight)); - isSubmersible = (isSubmarine || (followGround && depth > height)); + hasUnderwaterCollision = (isSubmarine || (followGround && depth > height) || (waterline > 0 && maxWaterDepth > waterline)); allowDirectionalPathing = moveDefTable.GetBool("allowDirectionalPathing", allowDirectionalPathing); preferShortestPath = moveDefTable.GetBool("preferShortestPath", preferShortestPath); } diff --git a/rts/Sim/MoveTypes/MoveDefHandler.h b/rts/Sim/MoveTypes/MoveDefHandler.h index 9c8d1db5601..13bacb00a82 100644 --- a/rts/Sim/MoveTypes/MoveDefHandler.h +++ b/rts/Sim/MoveTypes/MoveDefHandler.h @@ -106,7 +106,7 @@ struct MoveDef { unsigned int CalcCheckSum() const; bool IsComplexSubmersible() const { - return isSubmersible && overrideUnitWaterline; + return hasUnderwaterCollision && overrideUnitWaterline; }; static float GetDefaultMinWaterDepth() { return -1e6f; } @@ -183,8 +183,8 @@ struct MoveDef { /// are we supposed to be a purely sub-surface ship? bool isSubmarine = false; - // can this unit completely submerge in water? - bool isSubmersible = false; + // can this unit at least partially submerge in water? + bool hasUnderwaterCollision = false; /// If false, this forces the use of simple underwater collisions, which can cause some pathing issues for /// amphibious units. i.e. they are blocked by obstacles above and below the water regardless of height. From 641f53bddf75278106f8ff8cc45c1ddee967cc53 Mon Sep 17 00:00:00 2001 From: rlcevg <514675+rlcevg@users.noreply.github.com> Date: Thu, 10 Sep 2026 17:47:42 +0300 Subject: [PATCH 2/3] Update BARb 1.6.29 (#3265) --- AI/Skirmish/BARb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AI/Skirmish/BARb b/AI/Skirmish/BARb index e6b33037dfb..f4a6ca3ae09 160000 --- a/AI/Skirmish/BARb +++ b/AI/Skirmish/BARb @@ -1 +1 @@ -Subproject commit e6b33037dfbe81f2b0eb289f884ed90a1718eec0 +Subproject commit f4a6ca3ae096631894e194cfa9b4e8e53f4fb78c From 1c9b9ae4ff67cde086699f94022c3c829f6ff997 Mon Sep 17 00:00:00 2001 From: Robert Burnham Date: Thu, 10 Sep 2026 10:31:44 -0500 Subject: [PATCH 3/3] Stop unbind from clobbering longer key chains (#3136) * Stop unbind from removing longer chains that share the last key * Match unbind keychains exactly instead of by fit() --------- Co-authored-by: TarnishedKnight --- rts/Game/UI/KeyBindings.cpp | 24 +++++++++++++++++++++++- rts/Game/UI/KeyBindings.h | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/rts/Game/UI/KeyBindings.cpp b/rts/Game/UI/KeyBindings.cpp index 32c55dcfb6a..b566ebb4259 100644 --- a/rts/Game/UI/KeyBindings.cpp +++ b/rts/Game/UI/KeyBindings.cpp @@ -674,6 +674,11 @@ bool CKeyBindings::UnBind(const std::string& keystr, const std::string& command) if (debugEnabled) LOG("[CKeyBindings::%s] keystr=%s command=%s", __func__, keystr.c_str(), command.c_str()); + /* Bind does the same to the stored chain, so mirror it + * here or a stateful bind can never be named exactly. */ + if (statefulCommands.find(command) != statefulCommands.end()) + kc.back().SetAnyBit(); + const CKeySet& ks = kc.back(); KeyMap& bindings = ks.IsKeyCode() ? codeBindings : scanBindings; const auto it = bindings.find(ks); @@ -681,7 +686,7 @@ bool CKeyBindings::UnBind(const std::string& keystr, const std::string& command) if (it != bindings.end()) { ActionList& al = it->second; - if (RemoveCommandFromList(al, command)) + if (RemoveCommandFromList(al, kc, command)) buildHotkeyMap = true; if (al.empty()) @@ -816,6 +821,23 @@ bool CKeyBindings::RemoveCommandFromList(ActionList& al, const std::string& comm } +/* Chains are stored under their last keyset, so + * a bucket holds every chain ending in that key. */ +bool CKeyBindings::RemoveCommandFromList(ActionList& al, const CKeyChain& kc, const std::string& command) +{ + RECOIL_DETAILED_TRACY_ZONE; + + const auto removedCount = std::erase_if(al, [&kc, &command] (const auto& x) { + /* exact compare, not .fit(): naming one modifier + * combination must not remove a different one. + * operator== also rejects differing chain lengths. */ + return x.command == command && x.keyChain == kc; + }); + + return removedCount > 0; +} + + void CKeyBindings::ConfigNotify(const std::string& key, const std::string& value) { RECOIL_DETAILED_TRACY_ZONE; diff --git a/rts/Game/UI/KeyBindings.h b/rts/Game/UI/KeyBindings.h index 9caf37e6102..94f163af6e0 100644 --- a/rts/Game/UI/KeyBindings.h +++ b/rts/Game/UI/KeyBindings.h @@ -79,6 +79,7 @@ class CKeyBindings : public CommandReceiver bool AddKeySymbol(const std::string& keysym, const std::string& code); static bool RemoveCommandFromList(ActionList& al, const std::string& command); + static bool RemoveCommandFromList(ActionList& al, const CKeyChain& kc, const std::string& command); bool FileSave(FILE* file) const;