--AUX.SELECTUNSELECTLOOP PORTED FROM EDOPRO --sg: This group is initially empty and is gradually filled with cards from g. --mg: This is a clone of the sample group (g) but it does not contain the cards that failed the loop check --rescon: The condition that must be satisfied by the cards in the temporary checked group (sg). If the "stop" condition is fulfilled, the card is immediately removed from "sg" and fails the loop check function Auxiliary.SelectUnselectLoop(c,sg,mg,e,tp,minc,maxc,rescon) local res=not rescon if #sg>=maxc then return false end sg:AddCard(c) if rescon then local stop res,stop=rescon(sg,e,tp,mg,c) if stop then sg:RemoveCard(c) return false end end if #sg=minc and (not finishcon or finishcon(sg,e,tp,g)) local mg=g:Filter(Auxiliary.SelectUnselectLoop,sg,sg,g,e,tp,minc,maxc,rescon) if (breakcon and breakcon(sg,e,tp,mg)) or #mg<=0 or #sg>=maxc then break end Duel.Hint(HINT_SELECTMSG,seltp,hintmsg) local tc=mg:SelectUnselect(sg,seltp,finishable,finishable or (cancelable and #sg==0),minc,maxc) if not tc then break end if sg:IsContains(tc) then sg:RemoveCard(tc) else sg:AddCard(tc) end end return sg end --[[Differently from the regular SelectUnselectLoop, now rescon can also be used to define a razor filter that will restrict which members of (mg) can be added to the current subgroup]] function Glitchy.SelectUnselectLoop(c,sg,mg,e,tp,minc,maxc,rescon,firstElementFilter,firstElementIndex) if #sg>=maxc then return false end if firstElementFilter and firstElementIndex<=#firstElementFilter and not firstElementFilter[firstElementIndex](c,e,tp) then return false end local res=not rescon local mg2=mg:Clone() sg:AddCard(c) local razor if rescon then local stop res,stop,razor=rescon(sg,e,tp,mg2,c) if stop then sg:RemoveCard(c) return false end end if razor then if type(razor)=="table" then local razorfunc=razor[1] table.remove(razor,1) mg2=mg2:Filter(razorfunc,nil,table.unpack(razor)) else mg2=mg2:Filter(razor,nil) end end if #sg=minc and (not finishcon or finishcon(sg,e,tp,g2)) local mg=g2:Filter(Glitchy.SelectUnselectLoop,sg,sg,g2,e,tp,minc,maxc,rescon) if (breakcon and breakcon(sg,e,tp,mg)) or #mg<=0 or #sg>=maxc then break end local selg=mg if firstElementFilter then local typ=aux.GetValueType(firstElementFilter) if typ=="function" then if #sg==0 then selg=mg:Filter(firstElementFilter,nil,e,tp) end elseif typ=="table" then if #sg<#firstElementFilter then selg=mg:Filter(firstElementFilter[firstElementIndex],nil,e,tp) end elseif typ=="Card" then if #sg==0 then selg=Group.FromCards(firstElementFilter) end end end Duel.Hint(HINT_SELECTMSG,seltp,hintmsg) local tc=selg:SelectUnselect(sg,seltp,finishable,finishable or (cancelable and #sg==0),minc,maxc) if not tc then break end if sg:IsContains(tc) then while true do firstElementIndex = firstElementIndex - 1 local tc2=table.remove(history) sg:RemoveCard(tc2) local lastDelta = table.remove(deltas) ApplyDelta(g2, { added = lastDelta.removed, removed = lastDelta.added }) if tc2==tc then break end end else sg:AddCard(tc) firstElementIndex = firstElementIndex + 1 if rescon then local delta = { added = Group.CreateGroup(), removed = Group.CreateGroup() } --delta.added just for futureproofing table.insert(deltas, delta) table.insert(history,tc) local _,_,razor=rescon(sg,e,tp,mg,tc) if razor then if type(razor)=="table" then local razorfunc=razor[1] table.remove(razor,1) g2=g2:Filter(razorfunc,nil,table.unpack(razor)) else g2=g2:Filter(razor,nil,sg,e,tp,mg) end delta.removed = g:Filter(function(card) return not g2:IsContains(card) end, nil) end end end end return sg end --SelectUnselectGroup aux functions function Auxiliary.dncheckbrk(g,e,tp,mg,c) local res=g:GetClassCount(Card.GetCode)==#g return res, not res end function Glitchy.dncheck(g,e,tp,mg,c) local valid = g:GetClassCount(Card.GetCode)==#g local razor = {aux.NOT(Card.IsCode),c:GetCode()} return valid,false,razor end function Auxiliary.sncheck(g) return g:GetClassCount(Card.GetCode)==1 end function Auxiliary.ogdncheckbrk(g,e,tp,mg,c) local res=g:GetClassCount(Card.GetOriginalCodeRule)==#g return res, not res end function Glitchy.ogdncheck(g,e,tp,mg,c) local valid = g:GetClassCount(Card.GetOriginalCodeRule)==#g local razor = {aux.NOT(Card.IsOriginalCodeRule),c:GetCode()} return valid,false,razor end function Glitchy.dloccheck(g,e,tp,mg,c) local valid = g:GetClassCount(Card.GetLocation)==#g local razor = {aux.NOT(Card.IsLocation),c:GetLocation()} return valid,false,razor end function Glitchy.dloccheck_field(g,e,tp,mg,c) local valid = g:GetClassCount(Card.GetLocationSimple)==#g local razor = {aux.NOT(Card.IsLocation),c:GetLocationSimple()} return valid,false,razor end --check for Free Monster Zones (from EDOPRO) function Auxiliary.ChkfMMZ(sumcount) return function(sg,e,tp,mg) return Duel.GetMZoneCount(tp,sg)>=sumcount end end function Auxiliary.ChkfMMZRel(sumcount,reason) sumcount=sumcount or 1 reason=reason or REASON_COST return function(g,e,tp,mg) return Duel.GetMZoneCount(tp,g)>=sumcount and Duel.CheckReleaseGroupEx(tp,Auxiliary.IsInGroup,#g,reason,false,nil,g) end end