diff --git a/proc_xyz.lua b/proc_xyz.lua index d58fe6150e..70de307e8e 100644 --- a/proc_xyz.lua +++ b/proc_xyz.lua @@ -8,6 +8,10 @@ end local infToken={} Xyz.InfiniteMats=infToken Xyz.ProcCancellable=false +Xyz.CheckAdditional=nil +EFFECT_GALAXY_WIZARD = 511600442 +EFFECT_GAGAGA_MIRAGE = 511600443 + function Xyz.EffectXyzMaterialChk(c,xyz,tp) local eff_xyzmat={c:GetCardEffect(EFFECT_XYZ_MATERIAL)} for _,eff in ipairs(eff_xyzmat) do @@ -16,16 +20,6 @@ function Xyz.EffectXyzMaterialChk(c,xyz,tp) end return false end -function Xyz.AlterFilter(c,alterf,xyzc,e,tp,op) - if not alterf(c,tp,xyzc) or not c:IsCanBeXyzMaterial(xyzc,tp) - or (c:IsControler(1-tp) and not Xyz.EffectXyzMaterialChk(c,xyzc,tp)) - or (op and not op(e,tp,0,c)) then return false end - if xyzc:IsLocation(LOCATION_EXTRA) then - return Duel.GetLocationCountFromEx(tp,tp,c,xyzc)>0 - else - return Duel.GetMZoneCount(tp,c,tp)>0 - end -end --Xyz monster, lv k*n function Xyz.AddProcedure(c,f,lv,ct,alterf,desc,maxct,op,mustbemat,exchk) --exchk for special xyz, checking other materials @@ -46,7 +40,7 @@ function Xyz.AddProcedure(c,f,lv,ct,alterf,desc,maxct,op,mustbemat,exchk) local chk1=Effect.CreateEffect(c) chk1:SetType(EFFECT_TYPE_SINGLE) - chk1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_IGNORE_IMMUNE+EFFECT_FLAG_SET_AVAILABLE) + chk1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE|EFFECT_FLAG_SET_AVAILABLE) chk1:SetCode(946) chk1:SetCondition(Xyz.Condition(f,lv,ct,maxct,mustbemat,exchk)) chk1:SetTarget(Xyz.Target(f,lv,ct,maxct,mustbemat,exchk)) @@ -56,7 +50,7 @@ function Xyz.AddProcedure(c,f,lv,ct,alterf,desc,maxct,op,mustbemat,exchk) e1:SetType(EFFECT_TYPE_FIELD) e1:SetDescription(1173) e1:SetCode(EFFECT_SPSUMMON_PROC) - e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE) + e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE|EFFECT_FLAG_UNCOPYABLE) e1:SetRange(LOCATION_EXTRA) e1:SetCondition(Xyz.Condition(f,lv,ct,maxct,mustbemat,exchk)) e1:SetTarget(Xyz.Target(f,lv,ct,maxct,mustbemat,exchk)) @@ -76,6 +70,7 @@ function Xyz.AddProcedure(c,f,lv,ct,alterf,desc,maxct,op,mustbemat,exchk) e2:SetCondition(Xyz.Condition2(alterf,op)) e2:SetTarget(Xyz.Target2(alterf,op)) e2:SetOperation(Xyz.Operation2(alterf,op)) + e2:SetLabelObject(chk2) c:RegisterEffect(e2) end end @@ -95,17 +90,20 @@ end function Xyz.MatFilter(c,f,lv,xyz,tp) return (c:IsControler(tp) or Xyz.EffectXyzMaterialChk(c,xyz,tp)) and Xyz.MatFilter2(c,f,lv,xyz,tp) end +function Xyz.GalaxyWizardChk(c,f,lv,xyz,tp) + if not c:IsHasEffect(EFFECT_GALAXY_WIZARD) then return false end + if not c:IsCanBeXyzMaterial(xyz,tp) or (f and not f(c,xyz,SUMMON_TYPE_XYZ|MATERIAL_XYZ,tp)) then return false end + if c:IsControler(1-tp) and not Xyz.EffectXyzMaterialChk(c,xyz,tp) then return false end + return lv and c:IsLevel(lv-4) and c:IsXyzLevel(xyz,lv-4) +end function Xyz.SubMatFilter(c,lv,xyz,tp) if not lv then return false end - local te=c:GetCardEffect(EFFECT_SPELL_XYZ_MAT) - if not te then return false end - local f=te:GetValue() - if type(f)=='function' then - if f(te)~=lv then return false end - else - if f~=lv then return false end + local effs={c:GetCardEffect(EFFECT_SPELL_XYZ_MAT)} + for _,te in ipairs(effs) do + local val=te:GetValue() + if (type(val)=='function' and val(te,c,lv,xyz,tp)==lv) or val==lv then return true end end - return true + return false end function Xyz.CheckValidMultiXyzMaterial(effs,xyz,matg) for i,te in ipairs(effs) do @@ -157,92 +155,124 @@ function Xyz.MatNumChkF2(tg,lv,xyz) end return true end -function Xyz.CheckMaterialSet(matg,xyz,tp,exchk,mustg,lv) +function Xyz.CheckMaterialSet(matg,xyz,tp,exchk,mustg,lv,min,max,gmg,Double,finale) if not matg:Includes(mustg) then return false end - if not Xyz.MatNumChkF(matg) then - return false - end - if lv and not Xyz.MatNumChkF2(matg,lv,xyz) then - return false - end + if #matgmax) then return false end + if not Xyz.MatNumChkF(matg) or (lv and not Xyz.MatNumChkF2(matg,lv,xyz)) then return false end + local ignored=#(gmg&matg)>0 if exchk and #matg>0 and not exchk(matg,tp,xyz) then - return false + if not matg:IsExists(Card.IsHasEffect,1,nil,EFFECT_GAGAGA_MIRAGE) then return false end + xyz:RegisterFlagEffect(EFFECT_GAGAGA_MIRAGE,0,0,0) --Rilliona & Longlong + for matc in matg:Iter() do + matc:AssumeProperty(ASSUME_RACE,0xfffffff) + matc:AssumeProperty(ASSUME_ATTRIBUTE,0x7f) + end + local exres=exchk(matg,tp,xyz) + xyz:ResetFlagEffect(EFFECT_GAGAGA_MIRAGE) + Duel.AssumeReset() + if not exres then return false end + ignored=true end + if ignored and Double==0 then return false end + if Xyz.CheckAdditional and not Xyz.CheckAdditional(matg,xyz,tp,lv) then return false end if xyz:IsLocation(LOCATION_EXTRA) then - return Duel.GetLocationCountFromEx(tp,tp,matg,xyz)>0 + if Duel.GetLocationCountFromEx(tp,tp,matg,xyz)<1 then return false end + else + if Duel.GetMZoneCount(tp,matg,tp)<1 then return false end end - return Duel.GetMZoneCount(tp,matg,tp)>0 + if finale then return true,ignored end + return true end -function Xyz.RecursionChk(c,mg,xyz,tp,min,max,minc,maxc,sg,matg,ct,matct,mustbemat,exchk,f,mustg,lv,eqmg,equips_inverse) +function Xyz.RecursionChk(c,mg,xyz,tp,min,max,minc,maxc,sg,matg,ct,matct,mustbemat,exchk,f,mustg,lv,eqmg,equips_inverse,gwg,gmg,Double) local addToMatg=true if eqmg and eqmg:IsContains(c) then if not sg:IsContains(c:GetEquipTarget()) then return false end - addToMatg=false end local xct=ct local rg=Group.CreateGroup() if not c:IsHasEffect(EFFECT_ORICHALCUM_CHAIN) then xct=xct+1 else - addToMatg=true + addToMatg=false end local xmatct=matct+1 + local gwp,gwf,gwv=gwg:IsContains(c),false,0 + if gwp then + gwv=c:GetCardEffect(EFFECT_GALAXY_WIZARD):GetValue() + if not c:IsXyzLevel(xyz,lv) then + gwf=true + xmatct=xmatct+gwv + end + end + local gmf,ignored=false,#(gmg&(matg+c))>0 + if Double==0 and ignored then + if maxc~=infToken then + if gwf then + if (max and xct+1>max) or xmatct+2>maxc then mg:Merge(rg) return false end + else + if xmatct+1==maxc then + if not c:IsHasEffect(EFFECT_GAGAGA_MIRAGE) then mg:Merge(rg) return false end + gmf=true + Double=Double+1 + xmatct=xmatct+1 + end + end + else + if not mg:IsExists(Card.IsHasEffect,1,matg+c,EFFECT_GAGAGA_MIRAGE) then + if not c:IsHasEffect(EFFECT_GAGAGA_MIRAGE) or gwf then mg:Merge(rg) return false end + gmf=true + Double=Double+1 + xmatct=xmatct+1 + end + end + end if (max and xct>max) or (maxc~=infToken and xmatct>maxc) then mg:Merge(rg) return false end for i,f in ipairs({c:GetCardEffect(EFFECT_XYZ_MAT_RESTRICTION)}) do - if matg:IsExists(Auxiliary.HarmonizingMagFilter,1,c,f,f:GetValue()) then - mg:Merge(rg) - return false - end + if matg:IsExists(Auxiliary.HarmonizingMagFilter,1,c,f,f:GetValue()) then mg:Merge(rg) return false end local sg2=mg:Filter(Auxiliary.HarmonizingMagFilter,nil,f,f:GetValue()) rg:Merge(sg2) mg:Sub(sg2) end for tc in sg:Iter() do for i,f in ipairs({tc:GetCardEffect(EFFECT_XYZ_MAT_RESTRICTION)}) do - if Auxiliary.HarmonizingMagFilter(c,f,f:GetValue()) then - mg:Merge(rg) - return false - end + if Auxiliary.HarmonizingMagFilter(c,f,f:GetValue()) then mg:Merge(rg) return false end end end - if addToMatg then - matg:AddCard(c) - end + if addToMatg then matg:AddCard(c) end sg:AddCard(c) local eqg=nil local res=(function() - if (xct>=min and xmatct>=minc) and Xyz.CheckMaterialSet(matg,xyz,tp,exchk,mustg,lv) then return true end + local function chkset(db) return Xyz.CheckMaterialSet(matg,xyz,tp,exchk,mustg,lv,min,max,gmg,db) end + local function checkother(n1,n2,db) return mg:IsExists(Xyz.RecursionChk,1,sg,mg,xyz,tp,min,max,minc,maxc,sg,matg,n1,n2,mustbemat,exchk,f,mustg,lv,eqmg,equips_inverse,gwg,gmg,db) end + if xmatct>=minc and chkset(Double) then return true end if equips_inverse then eqg=equips_inverse[c] - if eqg then - mg:Merge(eqg) - end + if eqg then mg:Merge(eqg) end end - if mg:IsExists(Xyz.RecursionChk,1,sg,mg,xyz,tp,min,max,minc,maxc,sg,matg,xct,xmatct,mustbemat,exchk,f,mustg,lv,eqmg,equips_inverse) then return true end - if not mustbemat then - local retchknum={} - for i,te in ipairs({c:IsHasEffect(EFFECT_DOUBLE_XYZ_MATERIAL,tp)}) do - local tgf=te:GetOperation() - local val=te:GetValue() - if val>0 and not retchknum[val] and (not maxc or maxc==infToken or xmatct+val<=maxc) and (not tgf or tgf(te,xyz,matg)) then - retchknum[val]=true - te:UseCountLimit(tp) - local chk=(xct+val>=min and xmatct+val>=minc and Xyz.CheckMaterialSet(matg,xyz,tp,exchk,mustg,lv)) - or mg:IsExists(Xyz.RecursionChk,1,sg,mg,xyz,tp,min,max,minc,maxc,sg,matg,xct,xmatct+val,mustbemat,exchk,f,mustg,lv,eqmg,equips_inverse) - te:RestoreCountLimit(tp) - if chk then return true end - end + if checkother(xct,xmatct,Double) then return true end + if mustbemat then return false end + if gwf or gmf then return (xmatct>=minc and chkset(Double)) or checkother(xct,xmatct,Double) end + if gwp and (not maxc or maxc==infToken or xmatct+gwv<=maxc) then + if (xmatct+gwv>=minc and chkset(Double)) or checkother(xct,xmatct+gwv,Double) then return true end + end + local retchknum={} + for i,te in ipairs({c:IsHasEffect(EFFECT_DOUBLE_XYZ_MATERIAL,tp)}) do + local tgf,val=te:GetOperation(),te:GetValue() + if val>0 and not retchknum[val] and (not maxc or maxc==infToken or xmatct+val<=maxc) and (not tgf or tgf(te,xyz,matg)) then + retchknum[val]=true + te:UseCountLimit(tp) + local double_plus=Double + if c:IsHasEffect(EFFECT_GAGAGA_MIRAGE) and val==1 then double_plus=double_plus+1 end + local chk=(xmatct+val>=minc and chkset(double_plus)) or checkother(xct,xmatct+val,double_plus) + te:RestoreCountLimit(tp) + if chk then return true end end end return false end)() - if addToMatg then - matg:RemoveCard(c) - end + if addToMatg then matg:RemoveCard(c) end sg:RemoveCard(c) - if eqg then - mg:Sub(eqg) - end + if eqg then mg:Sub(eqg) end mg:Merge(rg) return res end @@ -256,17 +286,35 @@ function Xyz.Condition(f,lv,minc,maxc,mustbemat,exchk) if (maxc~=infToken and min and min>maxc) then return false end if c:IsType(TYPE_PENDULUM) and c:IsFaceup() then return false end local tp=c:GetControler() - local mg - local g - local eqmg - local equips_inverse + local g,mg,eqmg,equips_inverse + local gwg,gmg=Group.CreateGroup(),Group.CreateGroup() if og then g=og - mg=og:Filter(Xyz.MatFilter,nil,f,lv,c,tp) + mg=g:Filter(Xyz.MatFilter,nil,f,lv,c,tp) else g=Xyz.GetMaterials(tp,c) mg=g:Filter(Xyz.MatFilter2,nil,f,lv,c,tp) - if not mustbemat then + end + if not mustbemat then + gwg=g:Filter(Xyz.GalaxyWizardChk,nil,f,lv,c,tp) + mg:Merge(gwg) + if g:IsExists(Card.IsHasEffect,1,nil,EFFECT_GAGAGA_MIRAGE) then + local invg=g-mg + for invc in invg:Iter() do + invc:AssumeProperty(ASSUME_RACE,0xfffffff) + invc:AssumeProperty(ASSUME_ATTRIBUTE,0x7f) + end + if og then + gmg=invg:Filter(Xyz.MatFilter,nil,f,lv,c,tp) + else + gmg=invg:Filter(Xyz.MatFilter2,nil,f,lv,c,tp) + end + gwg:Merge(invg:Filter(Xyz.GalaxyWizardChk,nil,f,lv,c,tp)) + gmg:Merge(invg:Filter(Xyz.GalaxyWizardChk,nil,f,lv,c,tp)) + Duel.AssumeReset() + mg:Merge(gwg):Merge(gmg) + end + if not og then for tc in aux.Next(mg) do local eq=tc:GetEquipGroup():Filter(Card.IsHasEffect,nil,EFFECT_EQUIP_SPELL_XYZ_MAT) if #eq~=0 then @@ -278,38 +326,51 @@ function Xyz.Condition(f,lv,minc,maxc,mustbemat,exchk) eqmg:Merge(eq) end end - if eqmg then - mg:Merge(eqmg) - end - if not f then - mg:Merge(Duel.GetMatchingGroup(Xyz.SubMatFilter,tp,LOCATION_ONFIELD+LOCATION_GRAVE,0,nil,lv,c,tp)) - end + if eqmg then mg:Merge(eqmg) end + if not f then mg:Merge(Duel.GetMatchingGroup(Xyz.SubMatFilter,tp,LOCATION_ONFIELD|LOCATION_GRAVE,0,nil,lv,c,tp)) end end end local mustg=Auxiliary.GetMustBeMaterialGroup(tp,g,tp,c,mg,REASON_XYZ) if must then mustg:Merge(must) end if not mg:Includes(mustg) then return false end if not mustbemat then - mg:Merge(Duel.GetMatchingGroup(Card.IsHasEffect,tp,LOCATION_HAND+LOCATION_ONFIELD+LOCATION_GRAVE+LOCATION_REMOVED,0,nil,EFFECT_ORICHALCUM_CHAIN)) + mg:Merge(Duel.GetMatchingGroup(Card.IsHasEffect,tp,LOCATION_HAND|LOCATION_ONFIELD|LOCATION_GRAVE|LOCATION_REMOVED,0,nil,EFFECT_ORICHALCUM_CHAIN)) end min=min or 0 - return mg:IsExists(Xyz.RecursionChk,1,nil,mg,c,tp,min,max,minc,maxc,Group.CreateGroup(),Group.CreateGroup(),0,0,mustbemat,exchk,f,mustg,lv,eqmg,equips_inverse) + return mg:IsExists(Xyz.RecursionChk,1,nil,mg,c,tp,min,max,minc,maxc,Group.CreateGroup(),Group.CreateGroup(),0,0,mustbemat,exchk,f,mustg,lv,eqmg,equips_inverse,gwg,gmg,0) end end function Xyz.Target(f,lv,minc,maxc,mustbemat,exchk) return function(e,tp,eg,ep,ev,re,r,rp,chk,c,must,og,min,max) - local cancel=not og and Duel.IsSummonCancelable() - local g - local mg - local eqmg - local equips_inverse + local g,mg,eqmg,equips_inverse + local gwg,gmg=Group.CreateGroup(),Group.CreateGroup() if og then g=og - mg=og:Filter(Xyz.MatFilter,nil,f,lv,c,tp) + mg=g:Filter(Xyz.MatFilter,nil,f,lv,c,tp) else g=Xyz.GetMaterials(tp,c) mg=g:Filter(Xyz.MatFilter2,nil,f,lv,c,tp) - if not mustbemat then + end + if not mustbemat then + gwg=g:Filter(Xyz.GalaxyWizardChk,nil,f,lv,c,tp) + mg:Merge(gwg) + if g:IsExists(Card.IsHasEffect,1,nil,EFFECT_GAGAGA_MIRAGE) then + local invg=g-mg + for invc in invg:Iter() do + invc:AssumeProperty(ASSUME_RACE,0xfffffff) + invc:AssumeProperty(ASSUME_ATTRIBUTE,0x7f) + end + if og then + gmg=invg:Filter(Xyz.MatFilter,nil,f,lv,c,tp) + else + gmg=invg:Filter(Xyz.MatFilter2,nil,f,lv,c,tp) + end + gwg:Merge(invg:Filter(Xyz.GalaxyWizardChk,nil,f,lv,c,tp)) + gmg:Merge(invg:Filter(Xyz.GalaxyWizardChk,nil,f,lv,c,tp)) + Duel.AssumeReset() + mg:Merge(gwg):Merge(gmg) + end + if not og then for tc in aux.Next(mg) do local eq=tc:GetEquipGroup():Filter(Card.IsHasEffect,nil,EFFECT_EQUIP_SPELL_XYZ_MAT) if #eq~=0 then @@ -321,24 +382,14 @@ function Xyz.Target(f,lv,minc,maxc,mustbemat,exchk) eqmg:Merge(eq) end end - if eqmg then - mg:Merge(eqmg) - end - if not f then - mg:Merge(Duel.GetMatchingGroup(Xyz.SubMatFilter,tp,LOCATION_ONFIELD+LOCATION_GRAVE,0,nil,lv,c,tp)) - end + if eqmg then mg:Merge(eqmg) end + if not f then mg:Merge(Duel.GetMatchingGroup(Xyz.SubMatFilter,tp,LOCATION_ONFIELD|LOCATION_GRAVE,0,nil,lv,c,tp)) end end end local mustg=Auxiliary.GetMustBeMaterialGroup(tp,g,tp,c,mg,REASON_XYZ) if must then mustg:Merge(must) end - local orichalcumGroup if not mustbemat then - orichalcumGroup=Duel.GetMatchingGroup(Card.IsHasEffect,tp,LOCATION_HAND+LOCATION_ONFIELD+LOCATION_GRAVE+LOCATION_REMOVED,0,nil,EFFECT_ORICHALCUM_CHAIN) - mg:Merge(orichalcumGroup) - end - if (not orichalcumGroup or #orichalcumGroup==0) and (must and #must==min and #must==max) then - e:SetLabelObject(mustg:Clone():KeepAlive()) - return true + mg:Merge(Duel.GetMatchingGroup(Card.IsHasEffect,tp,LOCATION_HAND|LOCATION_ONFIELD|LOCATION_GRAVE|LOCATION_REMOVED,0,nil,EFFECT_ORICHALCUM_CHAIN)) end do local extra_mats=0 @@ -346,12 +397,14 @@ function Xyz.Target(f,lv,minc,maxc,mustbemat,exchk) local matg=Group.CreateGroup() local sg=Group.CreateGroup() local multiXyzSelectedCards={} + local gwCards,gmCards={},{} + local Double=0 local finishable=false while true do local ct=#matg local matct=ct+extra_mats - if not ((not max or #matgmax) or (maxc~=infToken and matct>=maxc) then break end + local selg=mg:Filter(Xyz.RecursionChk,sg,mg,c,tp,min,max,minc,maxc,sg,matg,ct,matct,mustbemat,exchk,f,mustg,lv,eqmg,equips_inverse,gwg,gmg,Double) if #selg==0 then break end Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_XMATERIAL) local cancelable=not og and Duel.IsSummonCancelable() and #sg==0 @@ -362,63 +415,101 @@ function Xyz.Target(f,lv,minc,maxc,mustbemat,exchk) end if not sg:IsContains(sc) then sg:AddCard(sc) - if equips_inverse and equips_inverse[sc] then - mg:Merge(equips_inverse[sc]) - end - local multiXyz={sc:IsHasEffect(EFFECT_DOUBLE_XYZ_MATERIAL,tp)} - if #multiXyz>0 and Xyz.CheckValidMultiXyzMaterial(multiXyz,c,matg) and ct0 and (not tgf or tgf(te,c,matg)) then - local newCount=matct+1+val - te:UseCountLimit(tp) - local chk=(minc<=newCount and (maxc==infToken or newCount<=maxc) and sg:Includes(mustg)) - or mg:IsExists(Xyz.RecursionChk,1,sg,mg,c,tp,min,max,minc,maxc,sg,matg,ct+1,newCount,mustbemat,exchk,f,mustg,lv,eqmg,equips_inverse) - if chk then - if not multi[1+val] then - multi[1+val]={} + local gmf,ignored=false,#(gmg&matg)>0 + local gmp=ignored and Double==0 and not (gwf or mustbemat) and (maxc==infToken or matct+2<=maxc) + if gmp then + if maxc~=infToken then + gmf=matct+2==maxc + else + gmf=not mg:IsExists(Card.IsHasEffect,1,matg,EFFECT_GAGAGA_MIRAGE) + end + end + local multiXyz={sc:IsHasEffect(EFFECT_DOUBLE_XYZ_MATERIAL,tp)} + local multi,numTab={},{} + local ctchk=ct0 and Xyz.CheckValidMultiXyzMaterial(multiXyz,c,matg) and ctchk then + if checkother(ct+1,matct+1,Double) then multi[1]={} end + for _,te in ipairs(multiXyz) do + local tgf,val=te:GetOperation(),te:GetValue() + if val>0 and (not tgf or tgf(te,c,matg)) then + local newCount=matct+1+val + te:UseCountLimit(tp) + local double_plus=Double + if sc:IsHasEffect(EFFECT_GAGAGA_MIRAGE) and val==1 then double_plus=double_plus+1 end + local chk=(minc<=newCount and (not maxc or maxc==infToken or newCount<=maxc) and chkset(double_plus)) or checkother(ct+1,newCount,double_plus) + if chk then + if not multi[1+val] then multi[1+val]={} end + table.insert(multi[1+val],te) end - table.insert(multi[1+val],te) + te:RestoreCountLimit(tp) end - te:RestoreCountLimit(tp) end + for k in pairs(multi) do table.insert(numTab,k) end end - local availableNumbers={} - for k in pairs(multi) do - table.insert(availableNumbers,k) - end - if #availableNumbers>0 then - local chosen=availableNumbers[1] - if #availableNumbers~=1 then - table.sort(availableNumbers) - Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_XMATERIAL) - chosen=Duel.AnnounceNumber(tp,availableNumbers) + if gwp and not (gwf or gmf) then + local gwmatct=matct+1+gwv + gwf=#numTab==0 and minc>=gwmatct and not checkother(ct+1,matct+1,Double) and (chkset(Double) or checkother(ct+1,gwmatct,Double)) + if not gwf and (maxc==infToken or gwmatct<=maxc) then + if (minc<=gwmatct and chkset(Double)) or checkother(ct+1,gwmatct,Double) then + gwf=Duel.SelectYesNo(tp,aux.Stringid(511600442,0)) + end end - if chosen>1 then - local eff=multi[chosen][1] - extra_mats=extra_mats+chosen-1 - eff:UseCountLimit(tp) - multiXyzSelectedCards[sc]={eff,chosen} + end + local function GmEffOwners(_c) + local effg=Group.CreateGroup() + for _,ce in ipairs({_c:GetCardEffect(EFFECT_GAGAGA_MIRAGE)}) do effg:AddCard(ce:GetOwner()) end + return effg + end + if gwf then + extra_mats=extra_mats+gwv + local flage=sc:RegisterFlagEffect(5160442,RESET_EVENT|RESETS_CANNOT_ACT,0,0) + gwCards[sc]={gwv,flage} + elseif gmf then + extra_mats=extra_mats+1 + Double=Double+1 + gmCards[sc]=GmEffOwners(sc) + else + if #numTab>0 then + local chosen=numTab[1] + if #numTab~=1 then + table.sort(numTab) + Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_XMATERIAL) + chosen=Duel.AnnounceNumber(tp,numTab) + end + if chosen>1 then + if chosen==2 and sc:IsHasEffect(EFFECT_GAGAGA_MIRAGE) and Double==0 then + extra_mats=extra_mats+1 + Double=Double+1 + gmCards[sc]=GmEffOwners(sc) + else + extra_mats=extra_mats+chosen-1 + local eff=multi[chosen][1] + eff:UseCountLimit(tp) + multiXyzSelectedCards[sc]={eff,chosen} + end + end end end - elseif sc:IsHasEffect(EFFECT_ORICHALCUM_CHAIN) then - extra_mats=extra_mats+1 - else - matg:AddCard(sc) end else if equips_inverse and equips_inverse[sc] then local equips=equips_inverse[sc] - if sg:Includes(equips) then - goto continue - end + if #(sg&equips)>0 then goto continue end mg:Sub(equips) end sg:RemoveCard(sc) @@ -426,19 +517,34 @@ function Xyz.Target(f,lv,minc,maxc,mustbemat,exchk) extra_mats=extra_mats-1 else matg:RemoveCard(sc) - local multiXyzSelection=multiXyzSelectedCards[sc] - if multiXyzSelection then - multiXyzSelectedCards[sc]=nil + local multiXyzSelection,gwcheck,gmcheck=multiXyzSelectedCards[sc],gwCards[sc],gmCards[sc] + if gwcheck then + gwCards[sc]=nil + local gwv,flage=gwcheck[1],gwcheck[2] + extra_mats=extra_mats-gwv + flage:Reset() + elseif gmcheck then + gmCards[sc]=nil + extra_mats=extra_mats-1 + Double=Double-1 + elseif multiXyzSelection then local eff,num=table.unpack(multiXyzSelection) eff:RestoreCountLimit(tp) extra_mats=extra_mats-(num-1) end end end - finishable=#matg+extra_mats>=minc and Xyz.CheckMaterialSet(matg,c,tp,exchk,mustg,lv) + finishable=#matg+extra_mats>=minc and Xyz.CheckMaterialSet(matg,c,tp,exchk,mustg,lv,min,max,gmg,Double) ::continue:: end - sg:KeepAlive() + local _,req_ignored=Xyz.CheckMaterialSet(matg,c,tp,exchk,mustg,lv,min,max,gmg,Double,true) + if #(gmg&matg)>0 or req_ignored then + local _,effg=next(gmCards) + Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_EFFECT) + local effc = #effg==1 and effg:GetFirst() or effg:Select(tp,1,1,nil):GetFirst() + effc:RegisterFlagEffect(5160443,RESETS_STANDARD_PHASE_END,EFFECT_FLAG_CLIENT_HINT,1,0,aux.Stringid(511600443,0)) + Duel.Hint(HINT_CARD,0,511600443) + end e:SetLabelObject(sg) return true end @@ -450,47 +556,62 @@ function Xyz.Operation(f,lv,minc,maxc,mustbemat,exchk) local g=e:GetLabelObject() if not g then return end local remg=g:Filter(Card.IsHasEffect,nil,EFFECT_ORICHALCUM_CHAIN) - remg:ForEach(function(c) c:RegisterFlagEffect(511002115,RESET_EVENT+RESETS_STANDARD,0,0) end) + remg:ForEach(Card.RegisterFlagEffect,511002115,RESET_EVENT|RESETS_STANDARD,0,0) g:Remove(Card.IsHasEffect,nil,EFFECT_ORICHALCUM_CHAIN):Remove(Card.IsHasEffect,nil,511002115) c:SetMaterial(g) Duel.Overlay(c,g,true) + Xyz.CheckAdditional=nil g:DeleteGroup() end end + +function Xyz.GetAlterMaterials(tp,xyz) + return Duel.GetMatchingGroup(function(c) + return c:IsFaceup() and (c:IsControler(tp) or Xyz.EffectXyzMaterialChk(c,xyz,tp)) + end,tp,LOCATION_MZONE,LOCATION_MZONE,nil) +end +function Xyz.AlterFilter(c,alterf,xyz,e,tp,op) + if not alterf(c,tp,xyz) or not c:IsCanBeXyzMaterial(xyz,tp) or (op and not op(e,tp,0,c)) then return false end + if Xyz.CheckAdditional and not Xyz.CheckAdditional(Group.FromCards(c),xyz,tp) then return false end + if xyz:IsLocation(LOCATION_EXTRA) then return Duel.GetLocationCountFromEx(tp,tp,c,xyz)>0 end + return Duel.GetMZoneCount(tp,c,tp)>0 +end +function Xyz.AlterFilter2(c,alterf,xyz,e,tp,op) + return (c:IsControler(tp) or Xyz.EffectXyzMaterialChk(c,xyz,tp)) and Xyz.AlterFilter(c,alterf,xyz,e,tp,op) +end --Xyz summon(alterf) function Xyz.Condition2(alterf,op) return function(e,c,must,og,min,max) if c==nil then return true end if c:IsType(TYPE_PENDULUM) and c:IsFaceup() then return false end local tp=c:GetControler() - local mg=nil + local g,mg if og then - mg=og + g=og + mg=g:Filter(Xyz.AlterFilter2,nil,alterf,c,e,tp,op) else - mg=Duel.GetFieldGroup(tp,LOCATION_MZONE,LOCATION_MZONE) + g=Xyz.GetAlterMaterials(tp,c) + mg=g:Filter(Xyz.AlterFilter,nil,alterf,c,e,tp,op) end - local mustg=Auxiliary.GetMustBeMaterialGroup(tp,og,tp,c,mg,REASON_XYZ) + if #mg==0 then return false end + local mustg=Auxiliary.GetMustBeMaterialGroup(tp,g,tp,c,mg,REASON_XYZ) if must then mustg:Merge(must) end - if #mustg>1 or (min and min>1) or not mg:Includes(mustg) then return false end - local mustc=mustg:GetFirst() - if mustc then - return Xyz.AlterFilter(mustc,alterf,c,e,tp,op) - else - return mg:IsExists(Xyz.AlterFilter,1,nil,alterf,c,e,tp,op) - end + return #mustg<=1 and (not min or min<=1) and mg:Includes(mustg) end end function Xyz.Target2(alterf,op) return function(e,tp,eg,ep,ev,re,r,rp,chk,c,must,og,min,max) local cancelable=not og and Duel.IsSummonCancelable() Xyz.ProcCancellable=cancelable - local mg=nil + local g,mg if og then - mg=og + g=og + mg=g:Filter(Xyz.AlterFilter2,nil,alterf,c,e,tp,op) else - mg=Duel.GetFieldGroup(tp,LOCATION_MZONE,LOCATION_MZONE) + g=Xyz.GetAlterMaterials(tp,c) + mg=g:Filter(Xyz.AlterFilter,nil,alterf,c,e,tp,op) end - local mustg=Auxiliary.GetMustBeMaterialGroup(tp,og,tp,c,mg,REASON_XYZ) + local mustg=Auxiliary.GetMustBeMaterialGroup(tp,g,tp,c,mg,REASON_XYZ) if must then mustg:Merge(must) end local oc if must and #must==min and #must==max then @@ -518,5 +639,6 @@ function Xyz.Operation2(alterf,op) local oc=e:GetLabelObject() c:SetMaterial(oc) Duel.Overlay(c,oc) + Xyz.CheckAdditional=nil end end