Commit 79c7b5cd authored by nanahira's avatar nanahira

Revert "add AddFusionProcUltimate (#2852)"

screw it

This reverts commit 84b54d39.
parent e34e16d2
--白の枢機竜 --白の枢機竜
local s,id,o=GetID() local s,id,o=GetID()
function s.initial_effect(c) function s.initial_effect(c)
aux.AddFusionProcCodeFun(c,68468459,s.mfilter,6,true,true) aux.AddCodeList(c,68468459)
aux.AddMaterialCodeList(c,68468459)
--aux.AddFusionProcCodeFun(c,68468459,s.mfilter,6,true,true)
c:EnableReviveLimit() c:EnableReviveLimit()
local e0=Effect.CreateEffect(c)
e0:SetType(EFFECT_TYPE_SINGLE)
e0:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e0:SetCode(EFFECT_FUSION_MATERIAL)
e0:SetCondition(s.Alba_System_Drugmata_Fusion_Condition())
e0:SetOperation(s.Alba_System_Drugmata_Fusion_Operation())
c:RegisterEffect(e0)
local e1=Effect.CreateEffect(c) local e1=Effect.CreateEffect(c)
e1:SetType(EFFECT_TYPE_SINGLE) e1:SetType(EFFECT_TYPE_SINGLE)
e1:SetProperty(EFFECT_FLAG_SINGLE_RANGE+EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE) e1:SetProperty(EFFECT_FLAG_SINGLE_RANGE+EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
...@@ -36,32 +45,79 @@ end ...@@ -36,32 +45,79 @@ end
function s.splimit(e,se,sp,st) function s.splimit(e,se,sp,st)
return bit.band(st,SUMMON_TYPE_FUSION)==SUMMON_TYPE_FUSION return bit.band(st,SUMMON_TYPE_FUSION)==SUMMON_TYPE_FUSION
end end
function s.samecheck(c,sg) function s.Alba_System_Drugmata_Fusion_Filter(c,mg,fc,tp,chkf,gc)
local fuscodes={c:GetFusionCode()} if not c:IsFusionCode(68468459) and not c:IsHasEffect(EFFECT_FUSION_SUBSTITUTE) then return false end
for _,code in ipairs(fuscodes) do local g=mg:Filter(s.matfilter,c,tp)
if not sg:IsExists(Card.IsCode,1,nil,code) then return true end aux.GCheckAdditional=aux.dncheck
end local res=g:CheckSubGroup(s.Alba_System_Drugmata_Fusion_Gcheck,6,6,fc,tp,c,chkf,gc)
return false aux.GCheckAdditional=nil
return res
end end
function s.migfilter(c,fc) function s.matfilter(c,tp)
return c:IsLocation(LOCATION_GRAVE) and c:IsControler(fc:GetControler()) return c:IsLocation(LOCATION_GRAVE) and c:IsControler(tp) and not c:IsHasEffect(6205579)
end end
function s.Alba_System_Drugmata_Fusion_Gcheck(g,fc,tp,ec,chkf,gc)
if not s.abs_list then local sg=g:Clone()
s.abs_list={} sg:AddCard(ec)
if sg:IsExists(aux.TuneMagicianCheckX,1,nil,sg,EFFECT_TUNE_MAGICIAN_F) then return false end
if gc and not sg:IsContains(gc) then return false end
if aux.FCheckAdditional and not aux.FCheckAdditional(tp,sg,fc)
or aux.FGoalCheckAdditional and not aux.FGoalCheckAdditional(tp,sg,fc) then return false end
return g:GetClassCount(Card.GetFusionCode)==g:GetCount()
and (chkf==PLAYER_NONE or Duel.GetLocationCountFromEx(tp,tp,sg,fc)>0)
end end
function s.Alba_System_Drugmata_Fusion_Condition()
function s.mfilter(c,fc,sub,mg,sg) return function(e,g,gc,chkf)
if not s.migfilter(c,fc) then return false end if g==nil then return aux.MustMaterialCheck(nil,e:GetHandlerPlayer(),EFFECT_MUST_BE_FMATERIAL) end
if sg then local fc=e:GetHandler()
if #sg==0 then return false end -- must select at 2nd place, to determine which one is abs local tp=e:GetHandlerPlayer()
if #sg==1 then if gc then
s.abs_list[fc]=sg:GetFirst() if not g:IsContains(gc) then return false end
return true return g:IsExists(s.Alba_System_Drugmata_Fusion_Filter,1,nil,g,fc,tp,chkf,gc)
end
return g:IsExists(s.Alba_System_Drugmata_Fusion_Filter,1,nil,g,fc,tp,chkf,nil)
end
end
function s.Alba_System_Drugmata_Fusion_Operation()
return function(e,tp,eg,ep,ev,re,r,rp,gc,chkf)
local fc=e:GetHandler()
local tp=e:GetHandlerPlayer()
local fg=eg:Clone()
local g=nil
local sg=nil
while not sg do
if g then
fg:AddCard(g:GetFirst())
end
if gc then
if s.Alba_System_Drugmata_Fusion_Filter(gc,fg,fc,tp,chkf) then
g=Group.FromCards(gc)
fg:RemoveCard(gc)
local mg=fg:Filter(s.matfilter,fc,tp)
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_FMATERIAL)
sg=mg:SelectSubGroup(tp,s.Alba_System_Drugmata_Fusion_Gcheck,false,6,6,fc,tp,g:GetFirst(),chkf,gc)
else
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_FMATERIAL)
g=fg:FilterSelect(tp,s.Alba_System_Drugmata_Fusion_Filter,1,1,nil,fg,fc,tp,chkf,gc)
fg:Sub(g)
local mg=fg:Filter(s.matfilter,fc,tp)
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_FMATERIAL)
sg=mg:SelectSubGroup(tp,s.Alba_System_Drugmata_Fusion_Gcheck,true,6,6,fc,tp,g:GetFirst(),chkf,gc)
end
else
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_FMATERIAL)
g=fg:FilterSelect(tp,s.Alba_System_Drugmata_Fusion_Filter,1,1,nil,fg,fc,tp,chkf,nil)
fg:Sub(g)
local mg=fg:Filter(s.matfilter,fc,tp)
aux.GCheckAdditional=aux.dncheck
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_FMATERIAL)
sg=mg:SelectSubGroup(tp,s.Alba_System_Drugmata_Fusion_Gcheck,true,6,6,fc,tp,g:GetFirst(),chkf)
aux.GCheckAdditional=nil
end
end
g:Merge(sg)
Duel.SetFusionMaterial(g)
end end
return s.samecheck(c,sg-s.abs_list[fc])
end
return true
end end
function s.costfilter(c) function s.costfilter(c)
return c:IsAbleToGraveAsCost() return c:IsAbleToGraveAsCost()
......
...@@ -874,55 +874,36 @@ end ...@@ -874,55 +874,36 @@ end
--Fusion Summon --Fusion Summon
---Fusion monster, ultimate ---Fusion monster, mixed materials (fixed count)
---@param fcard Card ---@param fcard Card
---@param sub boolean Can be fusion summoned with substitute material ---@param sub boolean Can be fusion summoned with substitute material
---@param insf boolean Can be fusion summoned with no material (Instant Fusion) ---@param insf boolean Can be fusion summoned with no material (Instant Fusion)
---@param ... table { min: number, max: number, f: function, code: number, multiple: (string|function)[] } ---@param ... number|function|table
function Auxiliary.AddFusionProcUltimate(fcard,sub,insf,...) function Auxiliary.AddFusionProcMix(fcard,sub,insf,...)
if fcard:IsStatus(STATUS_COPYING_EFFECT) then return end if fcard:IsStatus(STATUS_COPYING_EFFECT) then return end
local val={...} local val={...}
local fun={}
local mat={} local mat={}
for i=1,#val do for i=1,#val do
if type(val[i])=='function' then if type(val[i])=='function' then
val[i]={ min=1, max=1, f=val[i] } fun[i]=function(c,fc,subm,mg,sg) return val[i](c,fc,subm,mg,sg) and not c:IsHasEffect(6205579) end
elseif type(val[i])=='number' then elseif type(val[i])=='table' then
local code=val[i] fun[i]=function(c,fc,subm,mg,sg)
val[i]={ min=1, max=1, code=code } for _,fcode in ipairs(val[i]) do
end if type(fcode)=='function' then
if fcode(c,fc,subm,mg,sg) and not c:IsHasEffect(6205579) then return true end
if val[i].multiple then elseif type(fcode)=='number' then
local multiple_list=val[i].multiple if c:IsFusionCode(fcode) or (subm and c:CheckFusionSubstitute(fc)) then return true end
val[i].multiple=nil end
local use_code=nil
for _,item in ipairs(multiple_list) do
if type(item)=="number" then
mat[item]=true
if not use_code then
use_code=item
end
end
end
val[i].code=use_code
val[i].f=function(c,fc,subm,mg,sg)
for _,fcode in ipairs(multiple_list) do
if type(fcode)=='function' then
if fcode(c,fc,subm,mg,sg) and not c:IsHasEffect(6205579) then return true end
elseif type(fcode)=='number' then
if c:IsFusionCode(fcode) or (subm and c:CheckFusionSubstitute(fc)) then return true end
end end
end return false
return false
end end
elseif val[i].code then for _,fcode in ipairs(val[i]) do
local code=val[i].code if type(fcode)=='number' then mat[fcode]=true end
mat[code]=true
val[i].f = function(c,fc,subm) return c:IsFusionCode(code) or (subm and c:CheckFusionSubstitute(fc)) end
else
local f = val[i].f
val[i].f = function(c,fc,subm,mg,sg)
return f(c,fc,subm,mg,sg) and not c:IsHasEffect(6205579)
end end
elseif type(val[i])=='number' then
fun[i]=function(c,fc,subm) return c:IsFusionCode(val[i]) or (subm and c:CheckFusionSubstitute(fc)) end
mat[val[i]]=true
end end
end end
local mt=getmetatable(fcard) local mt=getmetatable(fcard)
...@@ -930,13 +911,7 @@ function Auxiliary.AddFusionProcUltimate(fcard,sub,insf,...) ...@@ -930,13 +911,7 @@ function Auxiliary.AddFusionProcUltimate(fcard,sub,insf,...)
mt.material=mat mt.material=mat
end end
if mt.material_count==nil then if mt.material_count==nil then
local min=0 mt.material_count={#fun,#fun}
local max=0
for i=1,#val do
min=min+val[i].min
max=max+val[i].max
end
mt.material_count={min,max}
end end
for index,_ in pairs(mat) do for index,_ in pairs(mat) do
Auxiliary.AddCodeList(fcard,index) Auxiliary.AddCodeList(fcard,index)
...@@ -945,180 +920,141 @@ function Auxiliary.AddFusionProcUltimate(fcard,sub,insf,...) ...@@ -945,180 +920,141 @@ function Auxiliary.AddFusionProcUltimate(fcard,sub,insf,...)
e1:SetType(EFFECT_TYPE_SINGLE) e1:SetType(EFFECT_TYPE_SINGLE)
e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE) e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e1:SetCode(EFFECT_FUSION_MATERIAL) e1:SetCode(EFFECT_FUSION_MATERIAL)
e1:SetCondition(Auxiliary.FConditionUltimate(insf,sub,table.unpack(val))) e1:SetCondition(Auxiliary.FConditionMix(insf,sub,table.unpack(fun)))
e1:SetOperation(Auxiliary.FOperationUltimate(insf,sub,table.unpack(val))) e1:SetOperation(Auxiliary.FOperationMix(insf,sub,table.unpack(fun)))
fcard:RegisterEffect(e1) fcard:RegisterEffect(e1)
end end
function Auxiliary.FConditionMix(insf,sub,...)
function Auxiliary.FConditionFilterUltimate(c,fc,sub,notfusion,conds) --g:Material group(nil for Instant Fusion)
--gc:Material already used
--chkf: check field, default:PLAYER_NONE
--chkf&0x100: Not fusion summon, can use substitute (Hex-Sealed Fusion)
--chkf&0x200: Not fusion summon, can't use substitute ("Contact Fusion", Neos Fusion)
local funs={...}
return function(e,g,gc,chkfnf)
if g==nil then return insf and Auxiliary.MustMaterialCheck(nil,e:GetHandlerPlayer(),EFFECT_MUST_BE_FMATERIAL) end
local c=e:GetHandler()
local tp=c:GetControler()
local hexsealed=chkfnf&0x100>0
local notfusion=chkfnf&0x200>0
local sub2=(sub or hexsealed) and not notfusion
local mg=g:Filter(Auxiliary.FConditionFilterMix,c,c,sub2,notfusion,table.unpack(funs))
if gc then
if not mg:IsContains(gc) then return false end
Duel.SetSelectedCard(gc)
end
return mg:CheckSubGroup(Auxiliary.FCheckMixGoal,#funs,#funs,tp,c,sub2,chkfnf,table.unpack(funs))
end
end
function Auxiliary.FOperationMix(insf,sub,...)
local funs={...}
return function(e,tp,eg,ep,ev,re,r,rp,gc,chkfnf)
local c=e:GetHandler()
local hexsealed=chkfnf&0x100>0
local notfusion=chkfnf&0x200>0
local sub2=(sub or hexsealed) and not notfusion
local cancel=notfusion and Duel.GetCurrentChain()==0
local mg=eg:Filter(Auxiliary.FConditionFilterMix,c,c,sub2,notfusion,table.unpack(funs))
if gc then Duel.SetSelectedCard(gc) end
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_FMATERIAL)
local sg=mg:SelectSubGroup(tp,Auxiliary.FCheckMixGoal,cancel,#funs,#funs,tp,c,sub2,chkfnf,table.unpack(funs))
if sg then
Duel.SetFusionMaterial(sg)
else
Duel.SetFusionMaterial(Group.CreateGroup())
end
end
end
function Auxiliary.FConditionFilterMix(c,fc,sub,notfusion,...)
local check_type=notfusion and SUMMON_TYPE_SPECIAL or SUMMON_TYPE_FUSION local check_type=notfusion and SUMMON_TYPE_SPECIAL or SUMMON_TYPE_FUSION
if not c:IsCanBeFusionMaterial(fc,check_type) then return false end if not c:IsCanBeFusionMaterial(fc,check_type) then return false end
for _,o in ipairs(conds) do for i,f in ipairs({...}) do
if o.f(c,fc,sub) then return true end if f(c,fc,sub) then return true end
end end
return false return false
end end
function Auxiliary.FCheckMix(c,mg,sg,fc,sub,fun1,fun2,...)
function Auxiliary.FUltimateGoal(sg,tp,fc,sub,chkfnf,conds) if fun2 then
for i,o in ipairs(conds) do sg:AddCard(c)
if o.min>0 then local res=false
return false if fun1(c,fc,false,mg,sg) then
res=mg:IsExists(Auxiliary.FCheckMix,1,sg,mg,sg,fc,sub,fun2,...)
elseif sub and fun1(c,fc,true,mg,sg) then
res=mg:IsExists(Auxiliary.FCheckMix,1,sg,mg,sg,fc,false,fun2,...)
end end
sg:RemoveCard(c)
return res
else
return fun1(c,fc,sub,mg,sg)
end end
end
--if sg1 is subset of sg2 then not Auxiliary.FCheckAdditional(tp,sg1,fc) -> not Auxiliary.FCheckAdditional(tp,sg2,fc)
function Auxiliary.FCheckMixGoal(sg,tp,fc,sub,chkfnf,...)
local chkf=chkfnf&0xff local chkf=chkfnf&0xff
local not_fusion=chkfnf&(0x100|0x200)>0 local not_fusion=chkfnf&(0x100|0x200)>0
if not not_fusion and sg:IsExists(Auxiliary.TuneMagicianCheckX,1,nil,sg,EFFECT_TUNE_MAGICIAN_F) then return false end
if not Auxiliary.MustMaterialCheck(sg,tp,EFFECT_MUST_BE_FMATERIAL) then return false end if not Auxiliary.MustMaterialCheck(sg,tp,EFFECT_MUST_BE_FMATERIAL) then return false end
local g=Group.CreateGroup() local g=Group.CreateGroup()
return (chkf==PLAYER_NONE or Duel.GetLocationCountFromEx(tp,tp,sg,fc)>0) return sg:IsExists(Auxiliary.FCheckMix,1,nil,sg,g,fc,sub,...) and (chkf==PLAYER_NONE or Duel.GetLocationCountFromEx(tp,tp,sg,fc)>0)
and (not Auxiliary.FCheckAdditional or Auxiliary.FCheckAdditional(tp,sg,fc))
and (not Auxiliary.FGoalCheckAdditional or Auxiliary.FGoalCheckAdditional(tp,sg,fc)) and (not Auxiliary.FGoalCheckAdditional or Auxiliary.FGoalCheckAdditional(tp,sg,fc))
end end
function Auxiliary.FUltimateGetCondsResultCode(c,conds,fc,sub,mg,sg) ---Fusion monster, mixed material * minc to maxc + material + ...
-- -1 means crcode is invalid ---@param fcard Card
if c:IsLocation(LOCATION_MZONE) or Auxiliary.FGoalCheckAdditional then return -1 end ---@param sub boolean Can be fusion summoned with substitute material
---@param insf boolean Can be fusion summoned with no material (Instant Fusion)
local code=0 ---@param fun1 number|function|table
if sub and c:CheckFusionSubstitute(fc) then ---@param minc integer
code=code|0x1 ---@param maxc integer
end ---@param ... number|function|table
for i,o in ipairs(conds) do function Auxiliary.AddFusionProcMixRep(fcard,sub,insf,fun1,minc,maxc,...)
if o.max>0 and o.f(c,fc,sub,mg,sg) then if fcard:IsStatus(STATUS_COPYING_EFFECT) then return end
code=code|(1<<i) local val={fun1,...}
end local fun={}
end local mat={}
return code for i=1,#val do
end if type(val[i])=='function' then
fun[i]=function(c,fc,subm) return val[i](c,fc,subm) and not c:IsHasEffect(6205579) end
function Auxiliary.FUltimateNext(c,i,mg,sg,tp,fc,sub,chkfnf,conds) elseif type(val[i])=='table' then
local not_fusion=chkfnf&(0x100|0x200)>0 fun[i]=function(c,fc,subm)
if not not_fusion and Auxiliary.TuneMagicianCheckX(c,sg,EFFECT_TUNE_MAGICIAN_F) then return false end for _,fcode in ipairs(val[i]) do
if type(fcode)=='function' then
sg:AddCard(c) if fcode(c,fc,subm) and not c:IsHasEffect(6205579) then return true end
elseif type(fcode)=='number' then
if Auxiliary.FCheckAdditional and not Auxiliary.FCheckAdditional(tp,sg,fc) if c:IsFusionCode(fcode) or (subm and c:CheckFusionSubstitute(fc)) then return true end
or chkf~=PLAYER_NONE and Duel.GetLocationCountFromEx(tp,tp,sg,fc)<=0 and not c:IsLocation(LOCATION_MZONE) then
sg:RemoveCard(c)
return false
end
conds[i].min=conds[i].min-1
conds[i].max=conds[i].max-1
local res=Auxiliary.FUltimateGoal(sg,tp,fc,sub,chkfnf,conds)
or mg:IsExists(Auxiliary.CreateFUltimateCheck(mg,sg,tp,fc,sub,chkfnf,conds),1,sg)
conds[i].min=conds[i].min+1
conds[i].max=conds[i].max+1
sg:RemoveCard(c)
return res
end
function Auxiliary.FUltimateCheck(c,mg,sg,tp,fc,sub,chkfnf,conds)
-- we consider unfulfilled conditions first
local unfulfilled_conds={}
local fulfilled_conds={}
for i,o in ipairs(conds) do
if o.min>0 then
table.insert(unfulfilled_conds, {cond=o, i=i})
else
table.insert(fulfilled_conds, {cond=o, i=i})
end
end
local sorted_conds={}
for _,o in ipairs(unfulfilled_conds) do
table.insert(sorted_conds, o)
end
for _,o in ipairs(fulfilled_conds) do
table.insert(sorted_conds, o)
end
for _,item in ipairs(sorted_conds) do
local o=item.cond
local i=item.i
if o.max>0 then
if o.f(c,fc,false,mg,sg) and Auxiliary.FUltimateNext(c,i,mg,sg,tp,fc,sub,chkfnf,conds) then
return true
elseif sub and o.code and o.f(c,fc,true,mg,sg) and Auxiliary.FUltimateNext(c,i,mg,sg,tp,fc,false,chkfnf,conds) then
return true
end
end
end
return false
end
function Auxiliary.CreateFUltimateCheck(mg,sg,tp,fc,sub,chkfnf,conds)
local crcode_cache={}
return function(c)
local crcode=Auxiliary.FUltimateGetCondsResultCode(c,conds,fc,sub,mg,sg)
local cached=crcode_cache[crcode]
if cached then return cached==1 end
local res=Auxiliary.FUltimateCheck(c,mg,sg,tp,fc,sub,chkfnf,conds)
if crcode~=-1 then
crcode_cache[crcode]=res and 1 or 0
end
return res
end
end
function Auxiliary.FUltimateGetNextRoutes(c,mg,sg,tp,fc,chkfnf,routes)
local next_routes={}
for _,route in ipairs(routes) do
local conds=route.conds
local sub=route.sub
for i,o in ipairs(conds) do
if o.max>0 then
local new_route={ sub=sub, conds={} }
for j,oo in ipairs(conds) do
if j==i then
table.insert(new_route.conds, { min=oo.min-1, max=oo.max-1, f=oo.f, code=oo.code })
else
table.insert(new_route.conds, oo)
end
end
local function check_duplicate(sub)
for _,r in ipairs(next_routes) do
if r.sub==sub then
local same=true
for j,oo in ipairs(r.conds) do
local cond=new_route.conds[j]
if oo.min~=cond.min or oo.max~=cond.max then
same=false
break
end
end
if same then return true end
end end
end end
return false return false
end
if o.f(c,fc,false,mg,sg) and not check_duplicate(sub) and Auxiliary.FUltimateNext(c,i,mg,sg,tp,fc,sub,chkfnf,conds) then
table.insert(next_routes, new_route)
elseif sub and o.code and o.f(c,fc,true,mg,sg) and not check_duplicate(false) and Auxiliary.FUltimateNext(c,i,mg,sg,tp,fc,false,chkfnf,conds) then
new_route.sub=false
table.insert(next_routes, new_route)
end
end end
for _,fcode in ipairs(val[i]) do
if type(fcode)=='number' then mat[fcode]=true end
end
elseif type(val[i])=='number' then
fun[i]=function(c,fc,subm) return c:IsFusionCode(val[i]) or (subm and c:CheckFusionSubstitute(fc)) end
mat[val[i]]=true
end end
end end
local mt=getmetatable(fcard)
return next_routes if mt.material==nil then
mt.material=mat
end
if mt.material_count==nil then
mt.material_count={#fun+minc-1,#fun+maxc-1}
end
for index,_ in pairs(mat) do
Auxiliary.AddCodeList(fcard,index)
end
local e1=Effect.CreateEffect(fcard)
e1:SetType(EFFECT_TYPE_SINGLE)
e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e1:SetCode(EFFECT_FUSION_MATERIAL)
e1:SetCondition(Auxiliary.FConditionMixRep(insf,sub,fun[1],minc,maxc,table.unpack(fun,2)))
e1:SetOperation(Auxiliary.FOperationMixRep(insf,sub,fun[1],minc,maxc,table.unpack(fun,2)))
fcard:RegisterEffect(e1)
end end
function Auxiliary.FConditionMixRep(insf,sub,fun1,minc,maxc,...)
function Auxiliary.FConditionUltimate(insf,sub,...) local funs={...}
--g:Material group(nil for Instant Fusion)
--gc:Material already used
--chkf: check field, default:PLAYER_NONE
--chkf&0x100: Not fusion summon, can use substitute (Hex-Sealed Fusion)
--chkf&0x200: Not fusion summon, can't use substitute ("Contact Fusion", Neos Fusion)
local conds={...}
return function(e,g,gc,chkfnf) return function(e,g,gc,chkfnf)
if g==nil then return insf and Auxiliary.MustMaterialCheck(nil,e:GetHandlerPlayer(),EFFECT_MUST_BE_FMATERIAL) end if g==nil then return insf and Auxiliary.MustMaterialCheck(nil,e:GetHandlerPlayer(),EFFECT_MUST_BE_FMATERIAL) end
local c=e:GetHandler() local c=e:GetHandler()
...@@ -1126,184 +1062,162 @@ function Auxiliary.FConditionUltimate(insf,sub,...) ...@@ -1126,184 +1062,162 @@ function Auxiliary.FConditionUltimate(insf,sub,...)
local hexsealed=chkfnf&0x100>0 local hexsealed=chkfnf&0x100>0
local notfusion=chkfnf&0x200>0 local notfusion=chkfnf&0x200>0
local sub2=(sub or hexsealed) and not notfusion local sub2=(sub or hexsealed) and not notfusion
local mg=g:Filter(Auxiliary.FConditionFilterUltimate,c,c,sub2,notfusion,conds) local mg=g:Filter(Auxiliary.FConditionFilterMix,c,c,sub2,notfusion,fun1,table.unpack(funs))
for _,cond in ipairs(conds) do
if not mg:IsExists(cond.f,cond.min,nil,c,sub) then return false end
end
local checkf=Auxiliary.CreateFUltimateCheck(mg,Group.CreateGroup(),tp,c,sub2,chkfnf,conds)
if gc then if gc then
if not mg:IsContains(gc) then return false end if not mg:IsContains(gc) then return false end
return checkf(gc) local sg=Group.CreateGroup()
return Auxiliary.FSelectMixRep(gc,tp,mg,sg,c,sub2,chkfnf,fun1,minc,maxc,table.unpack(funs))
end end
return mg:IsExists(checkf,1,nil) local sg=Group.CreateGroup()
return mg:IsExists(Auxiliary.FSelectMixRep,1,nil,tp,mg,sg,c,sub2,chkfnf,fun1,minc,maxc,table.unpack(funs))
end end
end end
function Auxiliary.FOperationMixRep(insf,sub,fun1,minc,maxc,...)
function Auxiliary.FOperationUltimate(insf,sub,...) local funs={...}
local conds={...}
return function(e,tp,eg,ep,ev,re,r,rp,gc,chkfnf) return function(e,tp,eg,ep,ev,re,r,rp,gc,chkfnf)
local c=e:GetHandler() local c=e:GetHandler()
local tp=c:GetControler()
local hexsealed=chkfnf&0x100>0 local hexsealed=chkfnf&0x100>0
local notfusion=chkfnf&0x200>0 local notfusion=chkfnf&0x200>0
local sub2=(sub or hexsealed) and not notfusion local sub2=(sub or hexsealed) and not notfusion
local cancel=notfusion and Duel.GetCurrentChain()==0 local cancel=notfusion and Duel.GetCurrentChain()==0
local mg=eg:Filter(Auxiliary.FConditionFilterUltimate,c,c,sub2,notfusion,conds) local mg=eg:Filter(Auxiliary.FConditionFilterMix,c,c,sub2,notfusion,fun1,table.unpack(funs))
local sg=Group.CreateGroup() local sg=Group.CreateGroup()
if gc then sg:AddCard(gc) end if gc then sg:AddCard(gc) end
local current_conds={} while sg:GetCount()<maxc+#funs do
local total_minc=0 local cg=mg:Filter(Auxiliary.FSelectMixRep,sg,tp,mg,sg,c,sub2,chkfnf,fun1,minc,maxc,table.unpack(funs))
local total_maxc=0 if cg:GetCount()==0 then break end
for _,o in ipairs(conds) do local finish=Auxiliary.FCheckMixRepGoal(tp,sg,c,sub2,chkfnf,fun1,minc,maxc,table.unpack(funs))
table.insert(current_conds, { min=o.min, max=o.max, f=o.f, code=o.code })
total_minc=total_minc+o.min
total_maxc=total_maxc+o.max
end
local current_routes = {
{ sub=sub2, conds=current_conds }
}
if gc then
current_routes = Auxiliary.FUltimateGetNextRoutes(gc,mg,sg,tp,c,chkfnf,current_routes)
end
local select_history_cards={}
local select_history_routes={}
while sg:GetCount()<total_maxc do
local crcode_cache={}
local function select_filter(sc)
for _,route in ipairs(current_routes) do
if not crcode_cache[route] then
crcode_cache[route]={}
end
local crcode=Auxiliary.FUltimateGetCondsResultCode(sc,route.conds,c,route.sub,mg,sg)
local cached=crcode_cache[route][crcode]
if cached then
if cached==1 then return true end
else
local res=Auxiliary.FUltimateCheck(sc,mg,sg,tp,c,route.sub,chkfnf,route.conds)
if res then
if crcode~=-1 then
crcode_cache[route][crcode]=1
end
return true
elseif crcode~=-1 then
crcode_cache[route][crcode]=0
end
end
end
return false
end
local cg=mg:Filter(select_filter,sg)
if cg:GetCount()==0 then
break
end
local finish=false
for _,route in ipairs(current_routes) do
if Auxiliary.FUltimateGoal(sg,tp,c,sub2,chkfnf,route.conds) then
finish=true
break
end
end
local cancel_group=sg:Clone() local cancel_group=sg:Clone()
if gc then cancel_group:RemoveCard(gc) end if gc then cancel_group:RemoveCard(gc) end
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_FMATERIAL) Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_FMATERIAL)
local tc=cg:SelectUnselect(cancel_group,tp,finish,cancel,total_minc,total_maxc) local tc=cg:SelectUnselect(cancel_group,tp,finish,cancel,minc+#funs,maxc+#funs)
if not tc then if not tc then
if not finish then sg:Clear() end if not finish then sg:Clear() end
break break
end end
if sg:IsContains(tc) then if sg:IsContains(tc) then
local remove_index=1 sg:RemoveCard(tc)
for i=1,#select_history_cards do
if select_history_cards[i]==tc then
remove_index=i
break
end
end
-- revert to old routes
current_routes=select_history_routes[remove_index]
while true do
local rc=table.remove(select_history_cards,remove_index)
if not rc then break end
sg:RemoveCard(rc)
table.remove(select_history_routes,remove_index)
end
else else
table.insert(select_history_cards, tc)
table.insert(select_history_routes, current_routes)
local next_routes=Auxiliary.FUltimateGetNextRoutes(tc,mg,sg,tp,c,chkfnf,current_routes)
current_routes=next_routes
sg:AddCard(tc) sg:AddCard(tc)
end end
end end
Duel.SetFusionMaterial(sg) Duel.SetFusionMaterial(sg)
end end
end end
function Auxiliary.FCheckMixRep(sg,g,fc,sub,chkf,fun1,minc,maxc,fun2,...)
---Fusion monster, mixed materials (fixed count) if fun2 then
---@param fcard Card return sg:IsExists(Auxiliary.FCheckMixRepFilter,1,g,sg,g,fc,sub,chkf,fun1,minc,maxc,fun2,...)
---@param sub boolean Can be fusion summoned with substitute material else
---@param insf boolean Can be fusion summoned with no material (Instant Fusion) local ct1=sg:FilterCount(fun1,g,fc,sub)
---@param ... number|function|table local ct2=sg:FilterCount(fun1,g,fc,false)
function Auxiliary.AddFusionProcMix(fcard,sub,insf,...) return ct1==sg:GetCount()-g:GetCount() and ct1-ct2<=1
if fcard:IsStatus(STATUS_COPYING_EFFECT) then return end end
local val={...} end
local conds={} function Auxiliary.FCheckMixRepFilter(c,sg,g,fc,sub,chkf,fun1,minc,maxc,fun2,...)
for i=1,#val do if fun2(c,fc,sub) then
if type(val[i])=='table' then g:AddCard(c)
conds[i]={ sub=sub and fun2(c,fc,false)
min=1, local res=Auxiliary.FCheckMixRep(sg,g,fc,sub,chkf,fun1,minc,maxc,...)
max=1, g:RemoveCard(c)
miltiple=val[i] return res
} end
else return false
conds[i]=val[i] end
function Auxiliary.FCheckMixRepGoalCheck(tp,sg,fc,chkfnf)
local not_fusion=chkfnf&(0x100|0x200)>0
if not not_fusion and sg:IsExists(Auxiliary.TuneMagicianCheckX,1,nil,sg,EFFECT_TUNE_MAGICIAN_F) then return false end
if not Auxiliary.MustMaterialCheck(sg,tp,EFFECT_MUST_BE_FMATERIAL) then return false end
if Auxiliary.FGoalCheckAdditional and not Auxiliary.FGoalCheckAdditional(tp,sg,fc) then return false end
return true
end
function Auxiliary.FCheckMixRepGoal(tp,sg,fc,sub,chkfnf,fun1,minc,maxc,...)
local chkf=chkfnf&0xff
if sg:GetCount()<minc+#{...} or sg:GetCount()>maxc+#{...} then return false end
if not (chkf==PLAYER_NONE or Duel.GetLocationCountFromEx(tp,tp,sg,fc)>0) then return false end
if Auxiliary.FCheckAdditional and not Auxiliary.FCheckAdditional(tp,sg,fc) then return false end
if not Auxiliary.FCheckMixRepGoalCheck(tp,sg,fc,chkfnf) then return false end
local g=Group.CreateGroup()
return Auxiliary.FCheckMixRep(sg,g,fc,sub,chkf,fun1,minc,maxc,...)
end
function Auxiliary.FCheckMixRepTemplate(c,cond,tp,mg,sg,g,fc,sub,chkfnf,fun1,minc,maxc,...)
for i,f in ipairs({...}) do
if f(c,fc,sub) then
g:AddCard(c)
local subf=sub and f(c,fc,false)
local t={...}
table.remove(t,i)
local res=cond(tp,mg,sg,g,fc,subf,chkfnf,fun1,minc,maxc,table.unpack(t))
g:RemoveCard(c)
if res then return true end
end
end
if maxc>0 then
if fun1(c,fc,sub) then
g:AddCard(c)
local subf1=sub and fun1(c,fc,false)
local res=cond(tp,mg,sg,g,fc,subf1,chkfnf,fun1,minc-1,maxc-1,...)
g:RemoveCard(c)
if res then return true end
end end
end end
Auxiliary.AddFusionProcUltimate(fcard,sub,insf,table.unpack(conds)) return false
end end
function Auxiliary.FCheckMixRepSelectedCond(tp,mg,sg,g,...)
if g:GetCount()<sg:GetCount() then
---Fusion monster, mixed material * minc to maxc + material + ... return sg:IsExists(Auxiliary.FCheckMixRepSelected,1,g,tp,mg,sg,g,...)
---@param fcard Card else
---@param sub boolean Can be fusion summoned with substitute material return Auxiliary.FCheckSelectMixRep(tp,mg,sg,g,...)
---@param insf boolean Can be fusion summoned with no material (Instant Fusion) end
---@param fun1 number|function|table end
---@param minc integer function Auxiliary.FCheckMixRepSelected(c,...)
---@param maxc integer return Auxiliary.FCheckMixRepTemplate(c,Auxiliary.FCheckMixRepSelectedCond,...)
---@param ... number|function|table end
function Auxiliary.AddFusionProcMixRep(fcard,sub,insf,fun1,minc,maxc,...) function Auxiliary.FCheckSelectMixRep(tp,mg,sg,g,fc,sub,chkfnf,fun1,minc,maxc,...)
if fcard:IsStatus(STATUS_COPYING_EFFECT) then return end local chkf=chkfnf&0xff
local val={fun1,...} if Auxiliary.FCheckAdditional and not Auxiliary.FCheckAdditional(tp,g,fc) then return false end
local conds={} if chkf==PLAYER_NONE or Duel.GetLocationCountFromEx(tp,tp,g,fc)>0 then
for i=1,#val do if minc<=0 and #{...}==0 and Auxiliary.FCheckMixRepGoalCheck(tp,g,fc,chkfnf) then return true end
if type(val[i])=='table' then return mg:IsExists(Auxiliary.FCheckSelectMixRepAll,1,g,tp,mg,sg,g,fc,sub,chkfnf,fun1,minc,maxc,...)
conds[i]={ else
min=1, return mg:IsExists(Auxiliary.FCheckSelectMixRepM,1,g,tp,mg,sg,g,fc,sub,chkfnf,fun1,minc,maxc,...)
max=1, end
miltiple=val[i] end
} function Auxiliary.FCheckSelectMixRepAll(c,tp,mg,sg,g,fc,sub,chkf,fun1,minc,maxc,fun2,...)
elseif type(val[i])=='function' then if fun2 then
conds[i]={ if fun2(c,fc,sub) then
min=1, g:AddCard(c)
max=1, local subf2=sub and fun2(c,fc,false)
f=val[i] local res=Auxiliary.FCheckSelectMixRep(tp,mg,sg,g,fc,subf2,chkf,fun1,minc,maxc,...)
} g:RemoveCard(c)
elseif type(val[i])=='number' then return res
conds[i]={
min=1,
max=1,
code=val[i]
}
end end
elseif maxc>0 and fun1(c,fc,sub) then
g:AddCard(c)
local subf1=sub and fun1(c,fc,false)
local res=Auxiliary.FCheckSelectMixRep(tp,mg,sg,g,fc,subf1,chkf,fun1,minc-1,maxc-1)
g:RemoveCard(c)
return res
end end
conds[1].min=minc return false
conds[1].max=maxc end
Auxiliary.AddFusionProcUltimate(fcard,sub,insf,table.unpack(conds)) function Auxiliary.FCheckSelectMixRepM(c,tp,...)
return c:IsControler(tp) and c:IsLocation(LOCATION_MZONE)
and Auxiliary.FCheckMixRepTemplate(c,Auxiliary.FCheckSelectMixRep,tp,...)
end
function Auxiliary.FSelectMixRep(c,tp,mg,sg,fc,sub,chkfnf,...)
sg:AddCard(c)
local res=false
if Auxiliary.FCheckAdditional and not Auxiliary.FCheckAdditional(tp,sg,fc) then
res=false
elseif Auxiliary.FCheckMixRepGoal(tp,sg,fc,sub,chkfnf,...) then
res=true
else
local g=Group.CreateGroup()
res=sg:IsExists(Auxiliary.FCheckMixRepSelected,1,nil,tp,mg,sg,g,fc,sub,chkfnf,...)
end
sg:RemoveCard(c)
return res
end end
---Fusion monster, name + name ---Fusion monster, name + name
...@@ -1343,11 +1257,11 @@ end ...@@ -1343,11 +1257,11 @@ end
---@param sub boolean ---@param sub boolean
---@param insf boolean ---@param insf boolean
function Auxiliary.AddFusionProcCodeRep(c,code1,cc,sub,insf) function Auxiliary.AddFusionProcCodeRep(c,code1,cc,sub,insf)
Auxiliary.AddFusionProcUltimate(c,sub,insf,{ local code={}
min=cc, for i=1,cc do
max=cc, code[i]=code1
code=code1 end
}) Auxiliary.AddFusionProcMix(c,sub,insf,table.unpack(code))
end end
---Fusion monster, name * minc to maxc ---Fusion monster, name * minc to maxc
---@param c Card ---@param c Card
...@@ -1367,11 +1281,11 @@ end ...@@ -1367,11 +1281,11 @@ end
---@param sub boolean ---@param sub boolean
---@param insf boolean ---@param insf boolean
function Auxiliary.AddFusionProcCodeFun(c,code1,f,cc,sub,insf) function Auxiliary.AddFusionProcCodeFun(c,code1,f,cc,sub,insf)
Auxiliary.AddFusionProcUltimate(c,sub,insf,code1,{ local fun={}
min=cc, for i=1,cc do
max=cc, fun[i]=f
f=f end
}) Auxiliary.AddFusionProcMix(c,sub,insf,code1,table.unpack(fun))
end end
---Fusion monster, condition + condition ---Fusion monster, condition + condition
---@param c Card ---@param c Card
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment