diff --git a/Conditionals.lua b/Conditionals.lua index 0a2344e..52fcff3 100644 --- a/Conditionals.lua +++ b/Conditionals.lua @@ -101,10 +101,10 @@ local function Multi(t, func, conditionals, condition) end -- Helper to choose And() or Or() based on operator metadata --- For negated conditionals (nomybuff, nozone, etc.): --- - AND separator (&) or comma-separated: ALL must pass (e.g., nomybuff:X&Y = missing X AND missing Y) --- - OR separator (/): ANY can pass (e.g., nomybuff:X/Y = missing X OR missing Y) --- The func already returns the negated check (e.g., "not has buff"), so we apply operators directly. +-- For negated conditionals (nomybuff, nozone, etc.), operators are FLIPPED (De Morgan's law): +-- - OR separator (/) [default]: ALL must be missing (e.g., nobuff:X/Y = no X AND no Y) +-- - AND separator (&): ANY can be missing (e.g., nobuff:X&Y = no X OR no Y) +-- This matches natural language: "no X or Y" intuitively means "neither X nor Y" local function NegatedMulti(t, func, conditionals, condition) if type(func) ~= "function" then return false end if type(t) ~= "table" then @@ -117,12 +117,13 @@ local function NegatedMulti(t, func, conditionals, condition) operatorType = conditionals._operators[condition] end + -- FLIPPED from positive conditionals (De Morgan's law for intuitive behavior) if operatorType == "AND" then - -- AND separator (&) or comma-separated: ALL negations must pass - return And(t, func) - else - -- OR separator (/) [default]: ANY negation can pass + -- AND separator (&): ANY negation can pass (missing at least one) return Or(t, func) + else + -- OR separator (/) [default]: ALL negations must pass (missing all) + return And(t, func) end end diff --git a/README.md b/README.md index 5a396e2..f8e9972 100644 --- a/README.md +++ b/README.md @@ -136,22 +136,25 @@ Both formats work identically: [zone:Stormwind_City&Ironforge] -- In Stormwind AND Ironforge (both - impossible, but illustrative) ``` -#### Negated conditionals work the same way +#### Negated conditionals: Operators are FLIPPED for intuitive behavior +For `no*` conditionals, `/` and `&` work opposite to positive conditionals (De Morgan's law): ```lua -[nozone:Stormwind_City/Ironforge] -- NOT in Stormwind OR NOT in Ironforge (not in at least one) -[nozone:Stormwind_City&Ironforge] -- NOT in Stormwind AND NOT in Ironforge (not in either) +[nozone:Stormwind_City/Ironforge] -- NOT in Stormwind AND NOT in Ironforge (not in either) +[nozone:Stormwind_City&Ironforge] -- NOT in Stormwind OR NOT in Ironforge (not in at least one) ``` -#### Comma-separated same conditionals = AND +This matches natural language: `[nobuff:X/Y]` reads as "no X or Y" meaning "neither X nor Y". + +#### Comma-separated same conditionals = AND (missing all) ```lua -[nomybuff:X, nomybuff:Y] -- Same as [nomybuff:X&Y] - missing both X AND Y +[nomybuff:X, nomybuff:Y] -- Same as [nomybuff:X/Y] - missing both X AND Y [mybuff:X, mybuff:Y] -- Same as [mybuff:X&Y] - has both X AND Y ``` #### More Examples ```lua -[nomybuff:Mark_of_the_Wild/Thorns] -- Missing at least one buff (OR) -[nomybuff:"Seal of Wisdom"&"Seal of Light"] -- Missing both buffs (AND) +[nomybuff:Mark_of_the_Wild/Thorns] -- Missing BOTH buffs (neither present) +[nomybuff:"Seal of Wisdom"&"Seal of Light"] -- Missing at least one buff (not both present) [nomybuff:"Mind Quickening", nomybuff:"Arcane Power"] -- Missing both (comma = AND) ```