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
function s.matfilter(c,tp)
return c:IsLocation(LOCATION_GRAVE) and c:IsControler(tp) and not c:IsHasEffect(6205579)
end end
function s.migfilter(c,fc) function s.Alba_System_Drugmata_Fusion_Gcheck(g,fc,tp,ec,chkf,gc)
return c:IsLocation(LOCATION_GRAVE) and c:IsControler(fc:GetControler()) local sg=g:Clone()
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()
if not s.abs_list then return function(e,g,gc,chkf)
s.abs_list={} if g==nil then return aux.MustMaterialCheck(nil,e:GetHandlerPlayer(),EFFECT_MUST_BE_FMATERIAL) end
local fc=e:GetHandler()
local tp=e:GetHandlerPlayer()
if gc then
if not g:IsContains(gc) then return false end
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 end
function s.Alba_System_Drugmata_Fusion_Operation()
function s.mfilter(c,fc,sub,mg,sg) return function(e,tp,eg,ep,ev,re,r,rp,gc,chkf)
if not s.migfilter(c,fc) then return false end local fc=e:GetHandler()
if sg then local tp=e:GetHandlerPlayer()
if #sg==0 then return false end -- must select at 2nd place, to determine which one is abs local fg=eg:Clone()
if #sg==1 then local g=nil
s.abs_list[fc]=sg:GetFirst() local sg=nil
return true 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 end
return s.samecheck(c,sg-s.abs_list[fc]) g:Merge(sg)
Duel.SetFusionMaterial(g)
end end
return true
end end
function s.costfilter(c) function s.costfilter(c)
return c:IsAbleToGraveAsCost() return c:IsAbleToGraveAsCost()
......
...@@ -874,38 +874,22 @@ end ...@@ -874,38 +874,22 @@ 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 val[i].multiple then
local multiple_list=val[i].multiple
val[i].multiple=nil
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 type(fcode)=='function' then
if fcode(c,fc,subm,mg,sg) and not c:IsHasEffect(6205579) then return true end if fcode(c,fc,subm,mg,sg) and not c:IsHasEffect(6205579) then return true end
elseif type(fcode)=='number' then elseif type(fcode)=='number' then
...@@ -914,15 +898,12 @@ function Auxiliary.AddFusionProcUltimate(fcard,sub,insf,...) ...@@ -914,15 +898,12 @@ function Auxiliary.AddFusionProcUltimate(fcard,sub,insf,...)
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)
local check_type=notfusion and SUMMON_TYPE_SPECIAL or SUMMON_TYPE_FUSION --gc:Material already used
if not c:IsCanBeFusionMaterial(fc,check_type) then return false end --chkf: check field, default:PLAYER_NONE
for _,o in ipairs(conds) do --chkf&0x100: Not fusion summon, can use substitute (Hex-Sealed Fusion)
if o.f(c,fc,sub) then return true end --chkf&0x200: Not fusion summon, can't use substitute ("Contact Fusion", Neos Fusion)
end local funs={...}
return false return function(e,g,gc,chkfnf)
end if g==nil then return insf and Auxiliary.MustMaterialCheck(nil,e:GetHandlerPlayer(),EFFECT_MUST_BE_FMATERIAL) end
local c=e:GetHandler()
function Auxiliary.FUltimateGoal(sg,tp,fc,sub,chkfnf,conds) local tp=c:GetControler()
for i,o in ipairs(conds) do local hexsealed=chkfnf&0x100>0
if o.min>0 then local notfusion=chkfnf&0x200>0
return false 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 end
return mg:CheckSubGroup(Auxiliary.FCheckMixGoal,#funs,#funs,tp,c,sub2,chkfnf,table.unpack(funs))
end end
local chkf=chkfnf&0xff
local not_fusion=chkfnf&(0x100|0x200)>0
if not Auxiliary.MustMaterialCheck(sg,tp,EFFECT_MUST_BE_FMATERIAL) then return false end
local g=Group.CreateGroup()
return (chkf==PLAYER_NONE or Duel.GetLocationCountFromEx(tp,tp,sg,fc)>0)
and (not Auxiliary.FGoalCheckAdditional or Auxiliary.FGoalCheckAdditional(tp,sg,fc))
end end
function Auxiliary.FOperationMix(insf,sub,...)
function Auxiliary.FUltimateGetCondsResultCode(c,conds,fc,sub,mg,sg) local funs={...}
-- -1 means crcode is invalid return function(e,tp,eg,ep,ev,re,r,rp,gc,chkfnf)
if c:IsLocation(LOCATION_MZONE) or Auxiliary.FGoalCheckAdditional then return -1 end local c=e:GetHandler()
local hexsealed=chkfnf&0x100>0
local code=0 local notfusion=chkfnf&0x200>0
if sub and c:CheckFusionSubstitute(fc) then local sub2=(sub or hexsealed) and not notfusion
code=code|0x1 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
for i,o in ipairs(conds) do
if o.max>0 and o.f(c,fc,sub,mg,sg) then
code=code|(1<<i)
end end
end
function Auxiliary.FConditionFilterMix(c,fc,sub,notfusion,...)
local check_type=notfusion and SUMMON_TYPE_SPECIAL or SUMMON_TYPE_FUSION
if not c:IsCanBeFusionMaterial(fc,check_type) then return false end
for i,f in ipairs({...}) do
if f(c,fc,sub) then return true end
end end
return code return false
end end
function Auxiliary.FCheckMix(c,mg,sg,fc,sub,fun1,fun2,...)
function Auxiliary.FUltimateNext(c,i,mg,sg,tp,fc,sub,chkfnf,conds) if fun2 then
local not_fusion=chkfnf&(0x100|0x200)>0
if not not_fusion and Auxiliary.TuneMagicianCheckX(c,sg,EFFECT_TUNE_MAGICIAN_F) then return false end
sg:AddCard(c) sg:AddCard(c)
local res=false
if Auxiliary.FCheckAdditional and not Auxiliary.FCheckAdditional(tp,sg,fc) if fun1(c,fc,false,mg,sg) then
or chkf~=PLAYER_NONE and Duel.GetLocationCountFromEx(tp,tp,sg,fc)<=0 and not c:IsLocation(LOCATION_MZONE) then res=mg:IsExists(Auxiliary.FCheckMix,1,sg,mg,sg,fc,sub,fun2,...)
sg:RemoveCard(c) elseif sub and fun1(c,fc,true,mg,sg) then
return false res=mg:IsExists(Auxiliary.FCheckMix,1,sg,mg,sg,fc,false,fun2,...)
end 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) sg:RemoveCard(c)
return res 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 else
table.insert(fulfilled_conds, {cond=o, i=i}) return fun1(c,fc,sub,mg,sg)
end
end
local sorted_conds={}
for _,o in ipairs(unfulfilled_conds) do
table.insert(sorted_conds, o)
end 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 end
--if sg1 is subset of sg2 then not Auxiliary.FCheckAdditional(tp,sg1,fc) -> not Auxiliary.FCheckAdditional(tp,sg2,fc)
function Auxiliary.CreateFUltimateCheck(mg,sg,tp,fc,sub,chkfnf,conds) function Auxiliary.FCheckMixGoal(sg,tp,fc,sub,chkfnf,...)
local crcode_cache={} local chkf=chkfnf&0xff
return function(c) local not_fusion=chkfnf&(0x100|0x200)>0
local crcode=Auxiliary.FUltimateGetCondsResultCode(c,conds,fc,sub,mg,sg) if not not_fusion and sg:IsExists(Auxiliary.TuneMagicianCheckX,1,nil,sg,EFFECT_TUNE_MAGICIAN_F) then return false end
local cached=crcode_cache[crcode] if not Auxiliary.MustMaterialCheck(sg,tp,EFFECT_MUST_BE_FMATERIAL) then return false end
if cached then return cached==1 end local g=Group.CreateGroup()
local res=Auxiliary.FUltimateCheck(c,mg,sg,tp,fc,sub,chkfnf,conds) return sg:IsExists(Auxiliary.FCheckMix,1,nil,sg,g,fc,sub,...) and (chkf==PLAYER_NONE or Duel.GetLocationCountFromEx(tp,tp,sg,fc)>0)
if crcode~=-1 then and (not Auxiliary.FCheckAdditional or Auxiliary.FCheckAdditional(tp,sg,fc))
crcode_cache[crcode]=res and 1 or 0 and (not Auxiliary.FGoalCheckAdditional or Auxiliary.FGoalCheckAdditional(tp,sg,fc))
end
return res
end
end end
function Auxiliary.FUltimateGetNextRoutes(c,mg,sg,tp,fc,chkfnf,routes) ---Fusion monster, mixed material * minc to maxc + material + ...
local next_routes={} ---@param fcard Card
---@param sub boolean Can be fusion summoned with substitute material
for _,route in ipairs(routes) do ---@param insf boolean Can be fusion summoned with no material (Instant Fusion)
local conds=route.conds ---@param fun1 number|function|table
local sub=route.sub ---@param minc integer
for i,o in ipairs(conds) do ---@param maxc integer
if o.max>0 then ---@param ... number|function|table
local new_route={ sub=sub, conds={} } function Auxiliary.AddFusionProcMixRep(fcard,sub,insf,fun1,minc,maxc,...)
if fcard:IsStatus(STATUS_COPYING_EFFECT) then return end
for j,oo in ipairs(conds) do local val={fun1,...}
if j==i then local fun={}
table.insert(new_route.conds, { min=oo.min-1, max=oo.max-1, f=oo.f, code=oo.code }) local mat={}
else for i=1,#val do
table.insert(new_route.conds, oo) if type(val[i])=='function' then
end fun[i]=function(c,fc,subm) return val[i](c,fc,subm) and not c:IsHasEffect(6205579) end
end elseif type(val[i])=='table' then
fun[i]=function(c,fc,subm)
local function check_duplicate(sub) for _,fcode in ipairs(val[i]) do
for _,r in ipairs(next_routes) do if type(fcode)=='function' then
if r.sub==sub then if fcode(c,fc,subm) and not c:IsHasEffect(6205579) then return true end
local same=true elseif type(fcode)=='number' then
for j,oo in ipairs(r.conds) do if c:IsFusionCode(fcode) or (subm and c:CheckFusionSubstitute(fc)) then return true end
local cond=new_route.conds[j]
if oo.min~=cond.min or oo.max~=cond.max then
same=false
break
end end
end end
if same then return true end return false
end end
for _,fcode in ipairs(val[i]) do
if type(fcode)=='number' then mat[fcode]=true end
end end
return false 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
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
local mt=getmetatable(fcard)
if mt.material==nil then
mt.material=mat
end end
if mt.material_count==nil then
mt.material_count={#fun+minc-1,#fun+maxc-1}
end end
for index,_ in pairs(mat) do
Auxiliary.AddCodeList(fcard,index)
end end
local e1=Effect.CreateEffect(fcard)
return next_routes 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 else
if select_history_cards[i]==tc then sg:AddCard(tc)
remove_index=i
break
end end
end end
Duel.SetFusionMaterial(sg)
-- 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 end
end
function Auxiliary.FCheckMixRep(sg,g,fc,sub,chkf,fun1,minc,maxc,fun2,...)
if fun2 then
return sg:IsExists(Auxiliary.FCheckMixRepFilter,1,g,sg,g,fc,sub,chkf,fun1,minc,maxc,fun2,...)
else else
table.insert(select_history_cards, tc) local ct1=sg:FilterCount(fun1,g,fc,sub)
table.insert(select_history_routes, current_routes) local ct2=sg:FilterCount(fun1,g,fc,false)
local next_routes=Auxiliary.FUltimateGetNextRoutes(tc,mg,sg,tp,c,chkfnf,current_routes) return ct1==sg:GetCount()-g:GetCount() and ct1-ct2<=1
current_routes=next_routes
sg:AddCard(tc)
end end
end
function Auxiliary.FCheckMixRepFilter(c,sg,g,fc,sub,chkf,fun1,minc,maxc,fun2,...)
if fun2(c,fc,sub) then
g:AddCard(c)
sub=sub and fun2(c,fc,false)
local res=Auxiliary.FCheckMixRep(sg,g,fc,sub,chkf,fun1,minc,maxc,...)
g:RemoveCard(c)
return res
end end
Duel.SetFusionMaterial(sg) return false
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
return false
end end
function Auxiliary.FCheckMixRepSelectedCond(tp,mg,sg,g,...)
---Fusion monster, mixed materials (fixed count) if g:GetCount()<sg:GetCount() then
---@param fcard Card return sg:IsExists(Auxiliary.FCheckMixRepSelected,1,g,tp,mg,sg,g,...)
---@param sub boolean Can be fusion summoned with substitute material
---@param insf boolean Can be fusion summoned with no material (Instant Fusion)
---@param ... number|function|table
function Auxiliary.AddFusionProcMix(fcard,sub,insf,...)
if fcard:IsStatus(STATUS_COPYING_EFFECT) then return end
local val={...}
local conds={}
for i=1,#val do
if type(val[i])=='table' then
conds[i]={
min=1,
max=1,
miltiple=val[i]
}
else else
conds[i]=val[i] return Auxiliary.FCheckSelectMixRep(tp,mg,sg,g,...)
end end
end
function Auxiliary.FCheckMixRepSelected(c,...)
return Auxiliary.FCheckMixRepTemplate(c,Auxiliary.FCheckMixRepSelectedCond,...)
end
function Auxiliary.FCheckSelectMixRep(tp,mg,sg,g,fc,sub,chkfnf,fun1,minc,maxc,...)
local chkf=chkfnf&0xff
if Auxiliary.FCheckAdditional and not Auxiliary.FCheckAdditional(tp,g,fc) then return false end
if chkf==PLAYER_NONE or Duel.GetLocationCountFromEx(tp,tp,g,fc)>0 then
if minc<=0 and #{...}==0 and Auxiliary.FCheckMixRepGoalCheck(tp,g,fc,chkfnf) then return true end
return mg:IsExists(Auxiliary.FCheckSelectMixRepAll,1,g,tp,mg,sg,g,fc,sub,chkfnf,fun1,minc,maxc,...)
else
return mg:IsExists(Auxiliary.FCheckSelectMixRepM,1,g,tp,mg,sg,g,fc,sub,chkfnf,fun1,minc,maxc,...)
end end
Auxiliary.AddFusionProcUltimate(fcard,sub,insf,table.unpack(conds))
end end
function Auxiliary.FCheckSelectMixRepAll(c,tp,mg,sg,g,fc,sub,chkf,fun1,minc,maxc,fun2,...)
if fun2 then
---Fusion monster, mixed material * minc to maxc + material + ... if fun2(c,fc,sub) then
---@param fcard Card g:AddCard(c)
---@param sub boolean Can be fusion summoned with substitute material local subf2=sub and fun2(c,fc,false)
---@param insf boolean Can be fusion summoned with no material (Instant Fusion) local res=Auxiliary.FCheckSelectMixRep(tp,mg,sg,g,fc,subf2,chkf,fun1,minc,maxc,...)
---@param fun1 number|function|table g:RemoveCard(c)
---@param minc integer return res
---@param maxc integer
---@param ... number|function|table
function Auxiliary.AddFusionProcMixRep(fcard,sub,insf,fun1,minc,maxc,...)
if fcard:IsStatus(STATUS_COPYING_EFFECT) then return end
local val={fun1,...}
local conds={}
for i=1,#val do
if type(val[i])=='table' then
conds[i]={
min=1,
max=1,
miltiple=val[i]
}
elseif type(val[i])=='function' then
conds[i]={
min=1,
max=1,
f=val[i]
}
elseif type(val[i])=='number' then
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