Commit b02703c0 authored by Vury Leo's avatar Vury Leo

Add 多層融合 to new fusion

parent cc23a09b
Pipeline #37080 failed with stages
in 3 minutes and 7 seconds
......@@ -13,7 +13,7 @@ function s.initial_effect(c)
e1:SetValue(s.mtval)
e1:SetOperation(function() return FusionSpell.FUSION_OPERATION_INHERIT end)
-- as of 2025 May, there is no card can add LOCATION_MZONE base on material group. So we can just check pre_select_mat_location.
e1:SetLabel(0xff,LOCATION_MZONE) --- only avaliable when pre_select_mat_location contains LOCATION_MZONE, 1st number is limitaion of count materials, set 0xff as a placeholder
e1:SetLabel(0,LOCATION_MZONE) --- only avaliable when pre_select_mat_location contains LOCATION_MZONE, 1st number is limitaion of count materials, set 0 as infinity
c:RegisterEffect(e1)
--counter
local e2=Effect.CreateEffect(c)
......
......@@ -2,121 +2,50 @@
local s,id,o=GetID()
function s.initial_effect(c)
--Activate
local e1=Effect.CreateEffect(c)
local e1=FusionSpell.CreateSummonEffect(c,{
additional_fcheck=s.additional_fcheck,
additional_fgoalcheck=s.additional_fgoalcheck,
pre_select_mat_location=LOCATION_HAND|LOCATION_MZONE|LOCATION_EXTRA,
mat_operation_code_map={
{ [LOCATION_EXTRA|LOCATION_GRAVE] = FusionSpell.FUSION_OPERATION_BANISH },
{ [0xff] = FusionSpell.FUSION_OPERATION_GRAVE }
},
stage_x_operation=s.stage_x_operation
})
e1:SetDescription(aux.Stringid(id,0))
e1:SetCategory(CATEGORY_SPECIAL_SUMMON+CATEGORY_FUSION_SUMMON)
e1:SetType(EFFECT_TYPE_ACTIVATE)
e1:SetCode(EVENT_FREE_CHAIN)
e1:SetTarget(s.target)
e1:SetOperation(s.activate)
c:RegisterEffect(e1)
end
s.fusion_effect=true
function s.fcheck1(ct)
return function(tp,sg,fc)
if ct>0 and sg:FilterCount(Card.IsLocation,nil,LOCATION_EXTRA)>ct then
return false
end
return true
end
end
function s.fcheck2(tp,sg,fc)
return sg:GetCount()>=3
end
function s.filter0(c)
return c:IsType(TYPE_MONSTER) and c:IsCanBeFusionMaterial() and c:IsAbleToRemove()
end
function s.filter2(c,e,tp,m,f,chkf)
return c:IsType(TYPE_FUSION) and (not f or f(c))
and c:IsCanBeSpecialSummoned(e,SUMMON_TYPE_FUSION,tp,false,false) and c:CheckFusionMaterial(m,nil,chkf)
end
function s.target(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then
local chkf=tp
local mg=Duel.GetFusionMaterial(tp):Filter(aux.NOT(Card.IsImmuneToEffect),nil,e)
local ct=Duel.GetFieldGroupCount(tp,0,LOCATION_MZONE)
if ct>0 then
local mg2=Duel.GetMatchingGroup(s.filter0,tp,LOCATION_EXTRA,0,nil)
if mg2:GetCount()>0 then
mg:Merge(mg2)
end
end
aux.FCheckAdditional=s.fcheck1(ct)
aux.FGoalCheckAdditional=s.fcheck2
local res=Duel.IsExistingMatchingCard(s.filter2,tp,LOCATION_EXTRA,0,1,nil,e,tp,mg,nil,chkf)
aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil
if not res then
local ce=Duel.GetChainMaterial(tp)
if ce~=nil then
local fgroup=ce:GetTarget()
local mg3=fgroup(ce,e,tp)
local mf=ce:GetValue()
res=Duel.IsExistingMatchingCard(s.filter2,tp,LOCATION_EXTRA,0,1,nil,e,tp,mg3,mf,chkf)
end
end
return res
---@type FUSION_FGCHECK_FUNCTION
function s.additional_fcheck(tp,mg,fc,all_mg)
--- material from extra deck by this fusion spell can not exceed monster opponent controls
local count_from_extra=mg:FilterCount(Card.IsLocation,nil,LOCATION_EXTRA)
local monster_count_of_opponet=Duel.GetMatchingGroupCount(aux.TRUE,tp,0,LOCATION_MZONE,nil)
if count_from_extra>monster_count_of_opponet then
return false
end
return true
end
function s.activate(e,tp,eg,ep,ev,re,r,rp)
local chkf=tp
local mg1=Duel.GetFusionMaterial(tp):Filter(aux.NOT(Card.IsImmuneToEffect),nil,e)
local ct=Duel.GetFieldGroupCount(tp,0,LOCATION_MZONE)
if ct>0 then
local mg2=Duel.GetMatchingGroup(s.filter0,tp,LOCATION_EXTRA,0,nil)
if mg2:GetCount()>0 then
mg1:Merge(mg2)
end
end
aux.FCheckAdditional=s.fcheck1(ct)
aux.FGoalCheckAdditional=s.fcheck2
local sg1=Duel.GetMatchingGroup(s.filter2,tp,LOCATION_EXTRA,0,nil,e,tp,mg1,nil,chkf)
local mg2=nil
local sg2=nil
local ce=Duel.GetChainMaterial(tp)
if ce~=nil then
local fgroup=ce:GetTarget()
mg2=fgroup(ce,e,tp)
local mf=ce:GetValue()
sg2=Duel.GetMatchingGroup(s.filter2,tp,LOCATION_EXTRA,0,nil,e,tp,mg2,mf,chkf)
end
local sg=sg1:Clone()
if sg2 then sg:Merge(sg2) end
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_SPSUMMON)
local tg=sg:Select(tp,1,1,nil)
local tc=tg:GetFirst()
if tc then
if sg1:IsContains(tc) and (sg2==nil or not sg2:IsContains(tc) or ce and not Duel.SelectYesNo(tp,ce:GetDescription())) then
aux.FCheckAdditional=s.fcheck1(ct)
aux.FGoalCheckAdditional=s.fcheck2
local mat1=Duel.SelectFusionMaterial(tp,tc,mg1,nil,chkf)
aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil
tc:SetMaterial(mat1)
local rg=mat1:Filter(Card.IsLocation,nil,LOCATION_EXTRA)
mat1:Sub(rg)
Duel.SendtoGrave(mat1,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION)
Duel.Remove(rg,POS_FACEUP,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION)
Duel.BreakEffect()
Duel.SpecialSummonStep(tc,SUMMON_TYPE_FUSION,tp,tp,false,false,POS_FACEUP)
elseif ce then
local mat2=Duel.SelectFusionMaterial(tp,tc,mg2,nil,chkf)
local fop=ce:GetOperation()
fop(ce,e,tp,tc,mat2)
end
local exmat=tc:GetMaterial():Filter(Card.IsPreviousLocation,nil,LOCATION_EXTRA)
---@type FUSION_FGCHECK_FUNCTION
function s.additional_fgoalcheck(tp,mg,fc,all_mg)
return all_mg:GetCount()>=3
end
---@type FUSION_SPELL_STAGE_X_CALLBACK_FUNCTION
function s.stage_x_operation(e,tc,tp,stage,mg_fuison_spell,mg_all)
if stage==FusionSpell.STAGE_BEFORE_SUMMON_COMPLETE then
local exmat=mg_fuison_spell:Filter(Card.IsPreviousLocation,nil,LOCATION_EXTRA)
if #exmat>0 then
local dam=exmat:GetSum(Card.GetAttack)
local lp=Duel.GetLP(tp)
if lp>=dam then
Duel.SetLP(tp,lp-dam)
else
Duel.SetLP(tp,0)
if dam>0 then
local lp=Duel.GetLP(tp)
if lp>=dam then
Duel.SetLP(tp,lp-dam)
else
Duel.SetLP(tp,0)
end
end
end
Duel.SpecialSummonComplete()
tc:CompleteProcedure()
end
aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil
end
......@@ -2285,9 +2285,9 @@ FusionSpell = {}
--- @field post_select_mat_location? integer
--- Location(s) to look for materials after they've been selected.
--- @field additional_fcheck? FUSION_FGCHECK_FUNCTION
--- Optional quick check to validate the selected material group.
--- @field additional_fgoalcheck? FUSION_FGCHECK_FUNCTION
--- Optional final check to validate the selected material group.
--- @field additional_gcheck? FUSION_FGCHECK_FUNCTION
--- Optional quick check to validate partial material groups (for performance).
--- @field fuslocation? integer
--- The location to summon Fusion Monsters from. Defaults to `LOCATION_EXTRA`.
--- @field sumtype? integer
......@@ -2372,7 +2372,7 @@ function FusionSpell.CreateSummonEffect(c,opts)
local mat_operation_code_map=opts.mat_operation_code_map or {}
local post_select_mat_location=opts.post_select_mat_location
local additional_fcheck=opts.additional_fcheck or aux.TRUE
local additional_gcheck=opts.additional_gcheck or aux.TRUE
local additional_fgoalcheck=opts.additional_fgoalcheck or aux.TRUE
local fuslocation=opts.fuslocation or LOCATION_EXTRA
local sumtype=opts.sumtype or SUMMON_TYPE_FUSION
local sumpos=opts.sumpos or POS_FACEUP
......@@ -2397,7 +2397,7 @@ function FusionSpell.CreateSummonEffect(c,opts)
mat_operation_code_map,
post_select_mat_location,
additional_fcheck,
additional_gcheck,
additional_fgoalcheck,
fuslocation,
sumtype,
sumpos,
......@@ -2412,7 +2412,7 @@ function FusionSpell.CreateSummonEffect(c,opts)
mat_operation_code_map,
post_select_mat_location,
additional_fcheck,
additional_gcheck,
additional_fgoalcheck,
fuslocation,
sumtype,
sumpos,
......@@ -2429,8 +2429,8 @@ end
---@param pre_select_mat_location integer|FUSION_SPELL_PRE_SELECT_MAT_LOCATION_FUNCTION location where to find the materials before known the materials
---@param mat_operation_code_map {[integer]:FUSION_OPERATION_CODE}[] operation code to do for the materials, it will be check in order
---@param post_select_mat_location integer? location where to find the materials after known the materials
---@param additional_fcheck FUSION_FGCHECK_FUNCTION function to check the final material group fits the requirement
---@param additional_gcheck FUSION_FGCHECK_FUNCTION function to check the part of potiential material group fits the requirement to improve performance
---@param additional_fcheck FUSION_FGCHECK_FUNCTION function to check the partial material group fits the requirement
---@param additional_fgoalcheck FUSION_FGCHECK_FUNCTION function to check the final material group fits the requirement
---@param fuslocation integer location where to summon fusion monsters from (default LOCATION_EXTRA), use it on Clock Lizard
---@param sumtype integer summon type
---@param sumpos integer summon position
......@@ -2444,7 +2444,7 @@ function FusionSpell.GetSummonTarget(
mat_operation_code_map,
post_select_mat_location,
additional_fcheck,
additional_gcheck,
additional_fgoalcheck,
fuslocation,
sumtype,
sumpos,
......@@ -2460,13 +2460,13 @@ function FusionSpell.GetSummonTarget(
local sg=Duel.IsExistingMatchingCard(
FusionSpell.SummonTargetFilter,tp,fuslocation,0,1,nil,
--- FusionSpell.SummonTargetFilter param
fusfilter,matfilter,e,tp,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,sumtype,sumpos,pre_select_mat_opponent_location,gc)
fusfilter,matfilter,e,tp,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,pre_select_mat_opponent_location,gc)
if sg==true then
return true
end
-- --- check for chain material targets
if sumtype&SUMMON_TYPE_FUSION~=0 then
local ce_sg=FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,fuslocation,sumtype,sumpos,gc)
local ce_sg=FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc)
if ce_sg==true then
return true
end
......@@ -2483,8 +2483,8 @@ end
---@param pre_select_mat_location integer|FUSION_SPELL_PRE_SELECT_MAT_LOCATION_FUNCTION location where to find the materials before known the materials
---@param mat_operation_code_map {[integer]:FUSION_OPERATION_CODE}[] operation code to do for the materials, it will be check in order
---@param post_select_mat_location integer? location where to find the materials after known the materials
---@param additional_fcheck function function to check the final material group fits the requirement
---@param additional_gcheck function function to check the part of potiential material group fits the requirement to improve performance
---@param additional_fcheck FUSION_FGCHECK_FUNCTION function to check the partial material group fits the requirement
---@param additional_fgoalcheck FUSION_FGCHECK_FUNCTION function to check the final material group fits the requirement
---@param fuslocation integer location where to summon fusion monsters from, use it on Clock Lizard
---@param sumtype integer summon type
---@param sumpos integer summon position
......@@ -2498,7 +2498,7 @@ function FusionSpell.GetSummonOperation(
mat_operation_code_map,
post_select_mat_location,
additional_fcheck,
additional_gcheck,
additional_fgoalcheck,
fuslocation,
sumtype,
sumpos,
......@@ -2510,12 +2510,12 @@ function FusionSpell.GetSummonOperation(
local sg=Duel.GetMatchingGroup(
FusionSpell.SummonTargetFilter,tp,fuslocation,0,nil,
--- FusionSpell.SummonTargetFilter param
fusfilter,matfilter,e,tp,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,sumtype,sumpos,pre_select_mat_opponent_location,gc)
fusfilter,matfilter,e,tp,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,pre_select_mat_opponent_location,gc)
--- check for chain material targets
local ce_sgs={}
local can_chain_material=false
if sumtype&SUMMON_TYPE_FUSION~=0 then
ce_sgs=FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,fuslocation,sumtype,sumpos,gc)
ce_sgs=FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc)
--- if there's any chain material effect has valid target
for _ in pairs(ce_sgs) do
can_chain_material=true
......@@ -2566,8 +2566,10 @@ function FusionSpell.GetSummonOperation(
sumtype,
pre_select_mat_opponent_location)
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunction(additional_fcheck,tp,tc,pre_select_mat_location,post_select_mat_location,pre_select_mat_opponent_location)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(additional_fgoalcheck,tp,tc,pre_select_mat_location)
materials=Duel.SelectFusionMaterial(tp,tc,mg,gc(e),tp)
aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil
else
--- use chain material effect
---@type function
......@@ -2575,8 +2577,10 @@ function FusionSpell.GetSummonOperation(
local chain_mg=chain_material_filter(fusion_effect,e,tp)
assert(#chain_mg>0, "we are trying to apply a chain material, but it has no possible material")
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(additional_fgoalcheck)
materials=Duel.SelectFusionMaterial(tp,tc,chain_mg,gc(e),tp)
aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil
end
end
......@@ -2584,6 +2588,7 @@ function FusionSpell.GetSummonOperation(
assert(fusion_effect~=nil)
if #materials>0 then
local materials_from_spell_card=Group.CreateGroup()
if fusion_effect==e then
--- fusion with fusion spell
tc:SetMaterial(materials)
......@@ -2591,6 +2596,7 @@ function FusionSpell.GetSummonOperation(
local applied_extra_effects={}
---@type {[FUSION_OPERATION_FUNCTION]:Group}
local material_grouped_by_op={}
local materials_with_one_material_effect=materials:Filter(function(mc) return (#FusionSpell.GetMaterialEffects(mc,tp,tc,pre_select_mat_location,post_select_mat_location,pre_select_mat_opponent_location))==1 end,nil)
for material in aux.Next(materials_with_one_material_effect) do
--For material that can be material only by 1 effect, either fusion spell or extra material effect, do the operation on it.
......@@ -2600,6 +2606,7 @@ function FusionSpell.GetSummonOperation(
if material_effect==true then
local fusion_operation_code=FusionSpell.GetOperationCodeByMaterialLocation(material:GetLocation(),mat_operation_code_map)
fusion_operation=FusionSpell.GetFusionOperationByCode(fusion_operation_code)
materials_from_spell_card:AddCard(material)
else
-- extra material effects
--- pay the operation cost, only valid in 影牢の呪縛 as of 2025 May
......@@ -2644,6 +2651,7 @@ function FusionSpell.GetSummonOperation(
local fusion_operation=FusionSpell.GetFusionOperationByCode(fusion_operation_code)
material_grouped_by_op[fusion_operation]=material_grouped_by_op[fusion_operation] or Group.CreateGroup()
material_grouped_by_op[fusion_operation]:AddCard(material)
materials_from_spell_card:AddCard(material)
end
end
if #materials_to_apply>0 then
......@@ -2687,13 +2695,13 @@ function FusionSpell.GetSummonOperation(
fusion_effect:Reset()
end
end
end
stage_x_operation(e,tc,tp,FusionSpell.STAGE_BEFORE_SUMMON_COMPLETE)
Duel.SpecialSummonComplete()
stage_x_operation(e,tc,tp,FusionSpell.STAGE_BEFORE_PROCEDURE_COMPLETE)
tc:CompleteProcedure()
stage_x_operation(e,tc,tp,FusionSpell.STAGE_AT_SUMMON_OPERATION_FINISH)
stage_x_operation(e,tc,tp,FusionSpell.STAGE_BEFORE_SUMMON_COMPLETE,materials_from_spell_card,materials)
Duel.SpecialSummonComplete()
stage_x_operation(e,tc,tp,FusionSpell.STAGE_BEFORE_PROCEDURE_COMPLETE,materials_from_spell_card,materials)
tc:CompleteProcedure()
stage_x_operation(e,tc,tp,FusionSpell.STAGE_AT_SUMMON_OPERATION_FINISH,materials_from_spell_card,materials)
end
end
stage_x_operation(e,tc,tp,FusionSpell.STAGE_AT_ALL_OPERATION_FINISH)
end
......@@ -2794,21 +2802,23 @@ end
---@param pre_select_mat_location integer|function location where to find the materials before known the materials (default LOCATION_HAND|LOCATION_MZONE)
---@param pre_select_mat_opponent_location integer|FUSION_SPELL_PRE_SELECT_MAT_LOCATION_FUNCTION location where to find the materials before known the materials on opponent location
---@param gc fun(e:Effect):Card|nil
function FusionSpell.SummonTargetFilter(c,fusfilter,matfilter,e,tp,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,sumtype,sumpos,pre_select_mat_opponent_location,gc)
function FusionSpell.SummonTargetFilter(c,fusfilter,matfilter,e,tp,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,pre_select_mat_opponent_location,gc)
local res=c:IsType(TYPE_FUSION) and fusfilter(c,tp) and c:IsCanBeSpecialSummoned(e,sumtype,tp,false,false,sumpos)
if res==false then
return false
end
local mg=FusionSpell.GetMaterialsGroupForTargetCard(c,tp,e,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,sumtype,pre_select_mat_opponent_location)
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunction(additional_fcheck,tp,c,pre_select_mat_location,post_select_mat_location,pre_select_mat_opponent_location)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(additional_fgoalcheck,tp,c,pre_select_mat_location)
res=c:CheckFusionMaterial(mg,gc(e),tp)
aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil
return res
end
---@return {[Effect]:Group} effect_targets_map Return a map of different chain material to potiential fusion targets
---@param gc fun(e:Effect):Card|nil
function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,fuslocation,sumtype,sumpos,gc)
function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc)
local chain_material_effects={Duel.IsPlayerAffectedByEffect(tp,EFFECT_CHAIN_MATERIAL)}
---@type {[Effect]:Group}
local chain_material_targets={}
......@@ -2820,7 +2830,7 @@ function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,additional_fc
local ce_fusfilter=ce:GetValue()
local ce_sg=Duel.GetMatchingGroup(FusionSpell.ChainMaterialSummonTargetFilter,tp,fuslocation,0,nil,
---FusionSpell.ChainMaterialSummonTargetFilter params
aux.AND(ce_fusfilter,fusfilter or aux.TRUE),e,tp,chain_mg,additional_fcheck,sumtype,sumpos,gc)
aux.AND(ce_fusfilter,fusfilter or aux.TRUE),e,tp,chain_mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc)
if #ce_sg>0 then
chain_material_targets[ce]=ce_sg
end
......@@ -2831,7 +2841,7 @@ end
---@return boolean res return whether there is a valid target for any chain material effect
---@param gc fun(e:Effect):Card|nil
function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,fuslocation,sumtype,sumpos,gc)
function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc)
local chain_material_effects={Duel.IsPlayerAffectedByEffect(tp,EFFECT_CHAIN_MATERIAL)}
---@type {[Effect]:Group}
for _,ce in ipairs(chain_material_effects) do
......@@ -2842,7 +2852,7 @@ function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,additiona
local ce_fusfilter=ce:GetValue()
local res=Duel.IsExistingMatchingCard(FusionSpell.ChainMaterialSummonTargetFilter,tp,fuslocation,0,1,nil,
---FusionSpell.ChainMaterialSummonTargetFilter params
aux.AND(ce_fusfilter,fusfilter or aux.TRUE),e,tp,chain_mg,additional_fcheck,sumtype,sumpos,gc)
aux.AND(ce_fusfilter,fusfilter or aux.TRUE),e,tp,chain_mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc)
if res==true then
return res
end
......@@ -2854,14 +2864,16 @@ end
---@param c Card
---@param gc fun(e:Effect):Card|nil
---@return boolean result Whether c could be fusion summoned by this chain material effect
function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additional_fcheck,sumtype,sumpos,gc)
function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc)
local res=c:IsType(TYPE_FUSION) and (not fusfilter or fusfilter(c,tp)) and c:IsCanBeSpecialSummoned(e,sumtype,tp,false,false,sumpos)
if res==false then
return false
end
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(additional_fgoalcheck)
res=c:CheckFusionMaterial(mg,gc(e),tp)
aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil
return res
end
......@@ -3099,8 +3111,8 @@ end
--- filter out materials that does not necessary come from fusion spell and pass to the gcheck of fusion spell
--- for each extra material effect, check the maximuim size is not exceeded.
--As of 2025 May, if a material could be used as extra material, it must be able to be used as fusion spell material. The code below is based on this assumption.
-- If we have Aiラブ融合 + 影牢の呪縛 or 多層融合 + アマゾネスの秘術 in same archetype, is code would fail in some scenario.
--- As of 2025 May, if a material could (but not forced) be used as extra material, it must be able to be used as fusion spell material. The code below is based on this assumption.
--- If we have Aiラブ融合 + 影牢の呪縛 or 多層融合 + アマゾネスの秘術 in same archetype, is code would fail in some scenario.
---@param fusion_spell_additional_fcheck_function FUSION_FGCHECK_FUNCTION
---@param tp integer
---@param tc Card
......@@ -3130,7 +3142,7 @@ function FusionSpell.GetFusionSpellFCheckAdditionalFunction(fusion_spell_additio
for extra_material_effect,materials in pairs(material_grouped_by_extra_material_effect) do
local labels={extra_material_effect:GetLabel()}
--- first element of label is the material count limit
if labels~=nil and #labels>0 and #materials>labels[1] then
if labels~=nil and #labels>0 and labels[1]>0 and #materials>labels[1] then
return false
end
end
......@@ -3140,10 +3152,32 @@ function FusionSpell.GetFusionSpellFCheckAdditionalFunction(fusion_spell_additio
end)
end
--- all material must come from chain material, only pass all material group to the gcheck of fusion spell
--- filter out materials that does not necessary come from fusion spell and pass to the gcheck of fusion spell
---@param fusion_spell_additional_fgoalcheck_function FUSION_FGCHECK_FUNCTION
---@param tp integer
---@param tc Card
---@param pre_select_mat_location integer|function location where to find the materials before known the materials (default LOCATION_HAND|LOCATION_MZONE)
function FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(fusion_spell_additional_fgoalcheck_function,tp,tc,pre_select_mat_location)
---@param mg Group
return (function(f_tp,mg,fc)
local extra_mg=mg:Filter(FusionSpell.GetExtraMaterialEffect,nil,tp,tc,pre_select_mat_location)
return fusion_spell_additional_fgoalcheck_function(f_tp,mg-extra_mg,fc,mg)
end)
end
--- all material must come from chain material, only pass all material group to the fcheck of fusion spell
--- @param fusion_spell_additional_fcheck_function FUSION_FGCHECK_FUNCTION
function FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(fusion_spell_additional_fcheck_function)
return (function(f_tp,mg,fc)
return fusion_spell_additional_fcheck_function(f_tp,Group.CreateGroup(),fc,mg)
end)
end
--- all material must come from chain material, only pass all material group to the gcheck of fusion spell
--- @param fusion_spell_additional_fgoalcheck_function FUSION_FGCHECK_FUNCTION
function FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(fusion_spell_additional_fgoalcheck_function)
return (function(f_tp,mg,fc)
return fusion_spell_additional_fgoalcheck_function(f_tp,Group.CreateGroup(),fc,mg)
end)
end
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