diff --git a/Conditionals.lua b/Conditionals.lua index 27873d6..e2e1d81 100644 --- a/Conditionals.lua +++ b/Conditionals.lua @@ -1481,7 +1481,7 @@ CleveRoids.Keywords = { stat = function(conditionals) return And(conditionals.stat, function(args) - if type(args) ~= "table" or not args.name or not args.operator or not args.amount then + if type(args) ~= "table" or not args.name then return false -- Malformed arguments from the parser. end @@ -1495,8 +1495,26 @@ CleveRoids.Keywords = { local current_value = get_stat_func() if not current_value then return false end - -- Use the addon's existing logic to compare the numbers. - return CleveRoids.comparators[args.operator](current_value, args.amount) + -- Check if this is a multi-comparison stat conditional + -- args.comparisons will be a table of {operator=, amount=} if multiple + if args.comparisons and type(args.comparisons) == "table" then + -- ALL comparisons must pass (AND logic) + for _, comp in ipairs(args.comparisons) do + if not CleveRoids.comparators[comp.operator] then + return false -- Invalid operator + end + if not CleveRoids.comparators[comp.operator](current_value, comp.amount) then + return false -- One comparison failed, so the whole conditional fails + end + end + return true -- All comparisons passed + else + -- Single comparison (backward compatibility) + if not args.operator or not args.amount then + return false + end + return CleveRoids.comparators[args.operator](current_value, args.amount) + end end) end, diff --git a/Core.lua b/Core.lua index aa5faf5..8adfade 100644 --- a/Core.lua +++ b/Core.lua @@ -945,19 +945,59 @@ function CleveRoids.ParseMsg(msg) -- accept decimals too; capture name/op/amount local _, _, name, operator, amount = string.find(arg_for_find, "([^>~=<]*)([>~=<]+)(#?%d*%.?%d+)") + if not operator or not amount then + -- No operator found, treat as simple string argument table.insert(conditionals[condition], processed_arg) else local name_to_use = (name and name ~= "") and name or conditionals.action local final_amount_str, num_replacements = string.gsub(amount, "#", "") local should_check_stacks = (num_replacements == 1) - table.insert(conditionals[condition], { - name = CleveRoids.Trim(name_to_use), - operator = operator, - amount = tonumber(final_amount_str), - checkStacks = should_check_stacks - }) + -- SPECIAL HANDLING FOR STAT CONDITIONALS WITH MULTIPLE COMPARISONS + -- Detect if this is a stat conditional with multiple operators + -- Example: "ap>1800/<2200" should create comparisons for both >1800 and <2200 + if (condition == "stat" or condition == "nostat") and string.find(processed_arg, "[>~=<]+%d+[^%d]+[>~=<]") then + -- This arg has multiple comparisons, parse them all + local stat_name = name_to_use + local comparisons = {} + + -- Extract all operator+number pairs + -- Pattern matches operator followed by optional decimal number + local gfind_func = string.gfind or string.gmatch + for op, num in gfind_func(processed_arg, "([>~=<]+)(#?%d*%.?%d+)") do + local clean_num = string.gsub(num, "#", "") + local check_stacks = (string.find(num, "#") ~= nil) + table.insert(comparisons, { + operator = op, + amount = tonumber(clean_num), + checkStacks = check_stacks + }) + end + + if table.getn(comparisons) > 0 then + table.insert(conditionals[condition], { + name = CleveRoids.Trim(stat_name), + comparisons = comparisons -- Store all comparisons + }) + else + -- Fallback to single comparison if parsing failed + table.insert(conditionals[condition], { + name = CleveRoids.Trim(name_to_use), + operator = operator, + amount = tonumber(final_amount_str), + checkStacks = should_check_stacks + }) + end + else + -- Normal single-comparison conditional (existing behavior) + table.insert(conditionals[condition], { + name = CleveRoids.Trim(name_to_use), + operator = operator, + amount = tonumber(final_amount_str), + checkStacks = should_check_stacks + }) + end end end end diff --git a/README.md b/README.md index 014487b..8f8c9cf 100644 --- a/README.md +++ b/README.md @@ -300,7 +300,7 @@ Check slash command and all conditional lists for new usages! | stealth | [stealth] | | * | If the player is in Stealth or Prowl. | | zone | [zone:"Zone"]
[zone:"Zone"/"Another Zone"] | * | * | If the player is in one or more zones of the given name. | | checkchanneled | [checkchanneled] | * | | Prevents a spell from being cast if you are already channeling it. | -| stat | [stat:stat>=x] | | | Check if one of the players statistics is greater or less than a specific number. Available Stats: str/strength, agi/agility, stam/stamina, int/intellect, spi/spirit, ap/attackpower, rap/rangedattackpower, healing/healingpower, arcane_power, fire_power, frost_power, nature_power, shadow_power, armor, defense, arcane_res, fire_res, frost_res, nature_res, shadow_res. | +| stat | [stat:stat>=x] | * | | Check if one of the players statistics is greater or less than a specific number. Available Stats: str/strength, agi/agility, stam/stamina, int/intellect, spi/spirit, ap/attackpower, rap/rangedattackpower, healing/healingpower, arcane_power, fire_power, frost_power, nature_power, shadow_power, armor, defense, arcane_res, fire_res, frost_res, nature_res, shadow_res. | | pet | [pet]
[pet:Voidwalker]
[pet:Imp/Felhunter] | * | * | If the player has a pet summoned and optionally if it matches the specified pet type(s). Works for Warlock demons and Hunter pets. | ### Unit Based