From 72ab7c8aa51fcc10adc602fb7e86c0045d103bd8 Mon Sep 17 00:00:00 2001 From: shaga <14+shaga@noreply.octowow.st> Date: Thu, 15 Oct 2026 07:05:15 +0000 Subject: [PATCH] Throw the whole totem set on one press OctoWoW gives each totem element its own global cooldown category (Fire 105, Earth 106, Water 107, Air 108), so one totem per element can be cast at the same time. ThrowSet still stopped after the first totem it cast, as it had to when all totems shared one global cooldown, so "/coe throwset" dropped one totem per key press. - ThrowSet casts every ready, not yet thrown totem of the active set. - A second press within 1 second skips totems whose cast is not yet confirmed, so a double press does not drop them again. "/coe restartset" clears this. - Each element gets its own pending timeout. They shared one name, so casting several at once replaced the earlier timeouts. --- COE_TotemData.lua | 8 ++++++++ COE_TotemLogic.lua | 27 ++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/COE_TotemData.lua b/COE_TotemData.lua index 0f6e81d..48054b6 100644 --- a/COE_TotemData.lua +++ b/COE_TotemData.lua @@ -113,6 +113,14 @@ COE["TotemSets"] = {} -------------------------------------------------------------------]] COE["SetCycle"] = {Earth = false, Fire = false, Water = false, Air = false}; +--[[ ---------------------------------------------------------------- + COE.SetThrown stores when ThrowSet last cast each element, so a + second press does not recast a totem whose cast is still + unconfirmed. COE.SetThrowGuard is that window in seconds +-------------------------------------------------------------------]] +COE["SetThrown"] = {}; +COE["SetThrowGuard"] = 1; + --[[ ---------------------------------------------------------------- COE.NoTotem is a placeholder for an empty anchor button -------------------------------------------------------------------]] diff --git a/COE_TotemLogic.lua b/COE_TotemLogic.lua index dcf025f..d43515d 100644 --- a/COE_TotemLogic.lua +++ b/COE_TotemLogic.lua @@ -536,8 +536,9 @@ end --[[ ---------------------------------------------------------------- METHOD: COE_Totem:ThrowSet - PURPOSE: Throws the next totem in the active set that is not - yet thrown + PURPOSE: Throws every totem in the active set that is not yet + thrown and is ready. Each element has its own GCD category + on the server, so the whole set goes out on one press -------------------------------------------------------------------]] function COE_Totem:ThrowSet() COE:DebugMessage("Method Executing: ThrowSet"); @@ -545,11 +546,13 @@ function COE_Totem:ThrowSet() if (COE_Config:GetSaved(COEOPT_ENABLESETS) == 1) then -- ======================================================================= - -- check which totem to throw + -- check which totems to throw -- ======================================================================= local activeset = COE_Config:GetSaved(COEOPT_ACTIVESET); COE:DebugMessage("ThrowSet activeset value: " .. activeset); + local now = GetTime(); + for k = 1, 4 do COE:DebugMessage("ThrowSet k value: " .. k); @@ -563,7 +566,15 @@ function COE_Totem:ThrowSet() tostring(COE.SetCycle[element])); if (COE.SetCycle[element] == false and totem) then - if (totem.isTrinket) then + local thrown = COE.SetThrown[element]; + + if (thrown and now - thrown < COE.SetThrowGuard) then + -- cast sent moments ago and not yet confirmed + -- -------------------------------------------- + COE:DebugMessage("ThrowSet skipping unconfirmed: " .. + element); + + elseif (totem.isTrinket) then if (totem.TrinketSlot) then -- first check if the trinket is already usable @@ -573,7 +584,7 @@ function COE_Totem:ThrowSet() if (start == 0 and duration == 0) then UseInventoryItem(totem.TrinketSlot); - return; + COE.SetThrown[element] = now; end end @@ -596,7 +607,7 @@ function COE_Totem:ThrowSet() CastSpellByName(COE.TotemSets[activeset][element] .SpellName); -- COE_Totem:SetPendingTotem(totem, totem.MaxRank); - return; + COE.SetThrown[element] = now; end end end @@ -613,6 +624,7 @@ function COE_Totem:ResetSetCycle() COE:Message(COESTR_RESTARTINGSET); COE.SetCycle = {Earth = false, Fire = false, Water = false, Air = false}; + COE.SetThrown = {}; end @@ -663,7 +675,8 @@ function COE_Totem:SetPendingTotem(totem, rank) COE:DebugMessage("SetPendingTotem Setting pending timeout to: " .. timeoutSec .. " seconds"); - Chronos.scheduleByName("COE_Pending", timeoutSec, + -- one timeout per element: a set throw has several pending at once + Chronos.scheduleByName("COE_Pending" .. totem.Element, timeoutSec, COESched_CheckPendingTotem, totem.Element); end