Commit a5578101 authored by Vury Leo's avatar Vury Leo

remove core from fusion

parent 27ffa9d1
...@@ -28,7 +28,8 @@ function s.initial_effect(c) ...@@ -28,7 +28,8 @@ function s.initial_effect(c)
local e4=FusionSpell.CreateSummonEffect(c,{ local e4=FusionSpell.CreateSummonEffect(c,{
fusfilter=s.fusfilter, fusfilter=s.fusfilter,
pre_select_mat_location=s.pre_select_mat_location, pre_select_mat_location=s.pre_select_mat_location,
additional_fcheck=s.fcheck additional_fcheck=s.fcheck,
fcheck_signature=s.fcheck_signature,
}) })
e4:SetCategory(CATEGORY_SPECIAL_SUMMON+CATEGORY_FUSION_SUMMON+CATEGORY_DECKDES) e4:SetCategory(CATEGORY_SPECIAL_SUMMON+CATEGORY_FUSION_SUMMON+CATEGORY_DECKDES)
e4:SetType(EFFECT_TYPE_IGNITION) e4:SetType(EFFECT_TYPE_IGNITION)
...@@ -72,3 +73,8 @@ function s.fcheck(tp,mg,fc,mg_all) ...@@ -72,3 +73,8 @@ function s.fcheck(tp,mg,fc,mg_all)
end end
return true return true
end end
--- Helper function to speed up select material, for this fusion, only location of the material matters for fcheck
function s.fcheck_signature(mc)
return mc:IsLocation(LOCATION_DECK)
end
...@@ -2256,6 +2256,8 @@ FusionSpell = {} ...@@ -2256,6 +2256,8 @@ FusionSpell = {}
--- @field skip_location_count_check? boolean --- @field skip_location_count_check? boolean
--- Locked code, material code that can not use substitutes --- Locked code, material code that can not use substitutes
--- @field locked_codes? (integer[]|fun(tc:Card):integer[]) --- @field locked_codes? (integer[]|fun(tc:Card):integer[])
--- A helper function to speed to material check. if 2 cards that would contribute same effect to fcheck, the signature should return same thingy (that could be a key of table), used for 煉獄の虚夢
--- @field fcheck_signature? fun(mc:Card):any
--- Add LOCATION_EXTRA and opponent mzone to EFFECT_EXTRA_FUSION_MATERIAL list, remove once core updated --- Add LOCATION_EXTRA and opponent mzone to EFFECT_EXTRA_FUSION_MATERIAL list, remove once core updated
...@@ -2337,6 +2339,7 @@ function FusionSpell.CreateSummonEffect(c,opts) ...@@ -2337,6 +2339,7 @@ function FusionSpell.CreateSummonEffect(c,opts)
local skip_summon_check=opts.skip_summon_check or false local skip_summon_check=opts.skip_summon_check or false
local skip_location_count_check=opts.skip_location_count_check or false local skip_location_count_check=opts.skip_location_count_check or false
local locked_codes=opts.locked_codes or {} local locked_codes=opts.locked_codes or {}
local fcheck_signature=opts.fcheck_signature or nil
-- Ensure material operation fallbacks are present -- Ensure material operation fallbacks are present
table.insert(mat_operation_code_map,{ [LOCATION_GRAVE] = FusionSpell.FUSION_OPERATION_BANISH }) table.insert(mat_operation_code_map,{ [LOCATION_GRAVE] = FusionSpell.FUSION_OPERATION_BANISH })
...@@ -2365,7 +2368,8 @@ function FusionSpell.CreateSummonEffect(c,opts) ...@@ -2365,7 +2368,8 @@ function FusionSpell.CreateSummonEffect(c,opts)
fusion_spell_matfilter, fusion_spell_matfilter,
skip_summon_check, skip_summon_check,
skip_location_count_check, skip_location_count_check,
locked_codes locked_codes,
fcheck_signature
)) ))
e1:SetOperation(FusionSpell.GetSummonOperation( e1:SetOperation(FusionSpell.GetSummonOperation(
fusfilter, fusfilter,
...@@ -2384,7 +2388,8 @@ function FusionSpell.CreateSummonEffect(c,opts) ...@@ -2384,7 +2388,8 @@ function FusionSpell.CreateSummonEffect(c,opts)
gc, gc,
fusion_spell_matfilter, fusion_spell_matfilter,
skip_summon_check, skip_summon_check,
locked_codes locked_codes,
fcheck_signature
)) ))
e1:SetDescription(1169) --- 融合召喚 e1:SetDescription(1169) --- 融合召喚
return e1 return e1
...@@ -2408,6 +2413,7 @@ end ...@@ -2408,6 +2413,7 @@ end
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード ---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使 ---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合 ---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合
---@param fcheck_signature (fun(mc:Card):any)|nil A helper function to speed to material check. if 2 cards that would contribute same effect to fcheck, the signature should return same thingy (that could be a key of table), used for 煉獄の虚夢
function FusionSpell.GetSummonTarget( function FusionSpell.GetSummonTarget(
fusfilter, fusfilter,
matfilter, matfilter,
...@@ -2426,7 +2432,8 @@ function FusionSpell.GetSummonTarget( ...@@ -2426,7 +2432,8 @@ function FusionSpell.GetSummonTarget(
fusion_spell_matfilter, fusion_spell_matfilter,
skip_summon_check, skip_summon_check,
skip_location_count_check, skip_location_count_check,
locked_codes locked_codes,
fcheck_signature
) )
return function(e,tp,eg,ep,ev,re,r,rp,chk) return function(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then if chk==0 then
...@@ -2452,7 +2459,8 @@ function FusionSpell.GetSummonTarget( ...@@ -2452,7 +2459,8 @@ function FusionSpell.GetSummonTarget(
fusion_spell_matfilter, fusion_spell_matfilter,
skip_summon_check, skip_summon_check,
skip_location_count_check, skip_location_count_check,
locked_codes) locked_codes,
fcheck_signature)
end, end,
tp,fuslocation,0,1,nil) tp,fuslocation,0,1,nil)
if sg==true then if sg==true then
...@@ -2460,7 +2468,7 @@ function FusionSpell.GetSummonTarget( ...@@ -2460,7 +2468,7 @@ function FusionSpell.GetSummonTarget(
end end
-- --- check for chain material targets -- --- check for chain material targets
if sumtype&SUMMON_TYPE_FUSION~=0 then if sumtype&SUMMON_TYPE_FUSION~=0 then
local ce_sg=FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes) local ce_sg=FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes,fcheck_signature)
if ce_sg==true then if ce_sg==true then
return true return true
end end
...@@ -2489,6 +2497,7 @@ end ...@@ -2489,6 +2497,7 @@ end
---@param fusion_spell_matfilter FUSION_SPELL_MATFILTER_FUNCTION a material must pass this to be legal as material come from fusion spell ---@param fusion_spell_matfilter FUSION_SPELL_MATFILTER_FUNCTION a material must pass this to be legal as material come from fusion spell
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード ---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合 ---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合
---@param fcheck_signature (fun(mc:Card):any)|nil A helper function to speed to material check. if 2 cards that would contribute same effect to fcheck, the signature should return same thingy (that could be a key of table), used for 煉獄の虚夢
function FusionSpell.GetSummonOperation( function FusionSpell.GetSummonOperation(
fusfilter, fusfilter,
matfilter, matfilter,
...@@ -2506,7 +2515,8 @@ function FusionSpell.GetSummonOperation( ...@@ -2506,7 +2515,8 @@ function FusionSpell.GetSummonOperation(
gc, gc,
fusion_spell_matfilter, fusion_spell_matfilter,
skip_summon_check, skip_summon_check,
locked_codes locked_codes,
fcheck_signature
) )
return function(e,tp,eg,ep,ev,re,r,rp) return function(e,tp,eg,ep,ev,re,r,rp)
local tc=nil local tc=nil
...@@ -2585,7 +2595,7 @@ function FusionSpell.GetSummonOperation( ...@@ -2585,7 +2595,7 @@ function FusionSpell.GetSummonOperation(
pre_select_mat_opponent_location, pre_select_mat_opponent_location,
post_select_mat_opponent_location, post_select_mat_opponent_location,
fusion_spell_matfilter) fusion_spell_matfilter)
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunction( local patched_additional_fcheck=FusionSpell.GetFusionSpellFCheckAdditionalFunction(
additional_fcheck, additional_fcheck,
tp, tp,
tc, tc,
...@@ -2596,33 +2606,35 @@ function FusionSpell.GetSummonOperation( ...@@ -2596,33 +2606,35 @@ function FusionSpell.GetSummonOperation(
fusion_spell_matfilter, fusion_spell_matfilter,
e, e,
mat_operation_code_map) mat_operation_code_map)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(additional_fgoalcheck,tp,tc,pre_select_mat_location,e) local patched_additional_fgoalcheck=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(additional_fgoalcheck,tp,tc,pre_select_mat_location,e)
local calculated_locked_codes=locked_codes
if type(locked_codes)=='function' then if type(locked_codes)=='function' then
Fusion.LockedCodes=locked_codes(tc) calculated_locked_codes=locked_codes(tc)
else
Fusion.LockedCodes=locked_codes
end end
materials=Duel.SelectFusionMaterial(tp,tc,mg,gc(e),tp) materials=Fusion.SelectFusionMaterial(tp,tc,mg,gc(e),tp,{
aux.FCheckAdditional=nil additional_fcheck=patched_additional_fcheck,
aux.FGoalCheckAdditional=nil additional_fgoalcheck=patched_additional_fgoalcheck,
Fusion.LockedCodes=nil locked_codes=calculated_locked_codes,
fcheck_signature=fcheck_signature,
})
else else
--- use chain material effect --- use chain material effect
---@type function ---@type function
local chain_material_filter=fusion_effect:GetTarget() local chain_material_filter=fusion_effect:GetTarget()
local chain_mg=chain_material_filter(fusion_effect,e,tp):Filter(aux.NecroValleyFilter(function(c) return matfilter(c,e,tp) end),nil) local chain_mg=chain_material_filter(fusion_effect,e,tp):Filter(aux.NecroValleyFilter(function(c) return matfilter(c,e,tp) end),nil)
assert(#chain_mg>0, "we are trying to apply a chain material, but it has no possible material") assert(#chain_mg>0, "we are trying to apply a chain material, but it has no possible material")
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck,e) local patched_additional_fcheck=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck,e)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(additional_fgoalcheck,e) local patched_additional_fgoalcheck=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(additional_fgoalcheck,e)
local calculated_locked_codes=locked_codes
if type(locked_codes)=='function' then if type(locked_codes)=='function' then
Fusion.LockedCodes=locked_codes(tc) calculated_locked_codes=locked_codes(tc)
else
Fusion.LockedCodes=locked_codes
end end
materials=Duel.SelectFusionMaterial(tp,tc,chain_mg,gc(e),tp) materials=Fusion.SelectFusionMaterial(tp,tc,chain_mg,gc(e),tp,{
aux.FCheckAdditional=nil additional_fcheck=patched_additional_fcheck,
aux.FGoalCheckAdditional=nil additional_fgoalcheck=patched_additional_fgoalcheck,
Fusion.LockedCodes=nil locked_codes=calculated_locked_codes,
fcheck_signature=fcheck_signature,
})
end end
end end
...@@ -2888,6 +2900,7 @@ end ...@@ -2888,6 +2900,7 @@ end
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード ---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使 ---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合 ---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合
---@param fcheck_signature (fun(mc:Card):any)|nil A helper function to speed to material check. if 2 cards that would contribute same effect to fcheck, the signature should return same thingy (that could be a key of table), used for 煉獄の虚夢
function FusionSpell.SummonTargetFilter( function FusionSpell.SummonTargetFilter(
c, c,
fusfilter, fusfilter,
...@@ -2907,7 +2920,8 @@ function FusionSpell.SummonTargetFilter( ...@@ -2907,7 +2920,8 @@ function FusionSpell.SummonTargetFilter(
fusion_spell_matfilter, fusion_spell_matfilter,
skip_summon_check, skip_summon_check,
skip_location_count_check, skip_location_count_check,
locked_codes) locked_codes,
fcheck_signature)
if not c:IsType(TYPE_FUSION) or fusfilter(c,e,tp)==false then if not c:IsType(TYPE_FUSION) or fusfilter(c,e,tp)==false then
return false return false
end end
...@@ -2928,7 +2942,7 @@ function FusionSpell.SummonTargetFilter( ...@@ -2928,7 +2942,7 @@ function FusionSpell.SummonTargetFilter(
pre_select_mat_opponent_location, pre_select_mat_opponent_location,
post_select_mat_opponent_location, post_select_mat_opponent_location,
fusion_spell_matfilter) fusion_spell_matfilter)
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunction( local patched_additional_fcheck=FusionSpell.GetFusionSpellFCheckAdditionalFunction(
additional_fcheck, additional_fcheck,
tp, tp,
c, c,
...@@ -2939,17 +2953,18 @@ function FusionSpell.SummonTargetFilter( ...@@ -2939,17 +2953,18 @@ function FusionSpell.SummonTargetFilter(
fusion_spell_matfilter, fusion_spell_matfilter,
e, e,
mat_operation_code_map) mat_operation_code_map)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(additional_fgoalcheck,tp,c,pre_select_mat_location,e) local patched_additional_fgoalcheck=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(additional_fgoalcheck,tp,c,pre_select_mat_location,e)
local calculated_locked_codes=locked_codes
if type(locked_codes)=='function' then if type(locked_codes)=='function' then
Fusion.LockedCodes=locked_codes(c) calculated_locked_codes=locked_codes(c)
else
Fusion.LockedCodes=locked_codes
end end
local chkf=FusionSpell.GetCheckFieldPlayer(tp,skip_location_count_check) local chkf=FusionSpell.GetCheckFieldPlayer(tp,skip_location_count_check)
local res=Fusion.CheckFusionMaterial(c,mg,gc(e),chkf) local res=Fusion.CheckFusionMaterial(c,mg,gc(e),chkf,{
aux.FCheckAdditional=nil additional_fcheck=patched_additional_fcheck,
aux.FGoalCheckAdditional=nil additional_fgoalcheck=patched_additional_fgoalcheck,
Fusion.LockedCodes=nil locked_codes=calculated_locked_codes,
fcheck_signature=fcheck_signature,
})
return res return res
end end
...@@ -2986,8 +3001,9 @@ end ...@@ -2986,8 +3001,9 @@ end
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード ---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使 ---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合 ---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合
---@param fcheck_signature (fun(mc:Card):any)|nil A helper function to speed to material check. if 2 cards that would contribute same effect to fcheck, the signature should return same thingy (that could be a key of table), used for 煉獄の虚夢
---@return boolean res return whether there is a valid target for any chain material effect ---@return boolean res return whether there is a valid target for any chain material effect
function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes) function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes,fcheck_signature)
local chain_material_effects={Duel.IsPlayerAffectedByEffect(tp,EFFECT_CHAIN_MATERIAL)} local chain_material_effects={Duel.IsPlayerAffectedByEffect(tp,EFFECT_CHAIN_MATERIAL)}
---@type {[Effect]:Group} ---@type {[Effect]:Group}
for _,ce in ipairs(chain_material_effects) do for _,ce in ipairs(chain_material_effects) do
...@@ -2997,7 +3013,7 @@ function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter ...@@ -2997,7 +3013,7 @@ function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter
if #chain_mg>0 then if #chain_mg>0 then
local ce_fusfilter=ce:GetValue() local ce_fusfilter=ce:GetValue()
local res=Duel.IsExistingMatchingCard(function(c) local res=Duel.IsExistingMatchingCard(function(c)
return FusionSpell.ChainMaterialSummonTargetFilter(c,aux.AND(ce_fusfilter,fusfilter or aux.TRUE),e,tp,chain_mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes) return FusionSpell.ChainMaterialSummonTargetFilter(c,aux.AND(ce_fusfilter,fusfilter or aux.TRUE),e,tp,chain_mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes,fcheck_signature)
end, end,
tp,fuslocation,0,1,nil) tp,fuslocation,0,1,nil)
if res==true then if res==true then
...@@ -3014,8 +3030,9 @@ end ...@@ -3014,8 +3030,9 @@ end
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード ---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使 ---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合 ---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合
---@param fcheck_signature (fun(mc:Card):any)|nil A helper function to speed to material check. if 2 cards that would contribute same effect to fcheck, the signature should return same thingy (that could be a key of table), used for 煉獄の虚夢
---@return boolean result Whether c could be fusion summoned by this chain material effect ---@return boolean result Whether c could be fusion summoned by this chain material effect
function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes) function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes,fcheck_signature)
if not c:IsType(TYPE_FUSION) or fusfilter(c,e,tp)==false then if not c:IsType(TYPE_FUSION) or fusfilter(c,e,tp)==false then
return false return false
end end
...@@ -3024,18 +3041,19 @@ function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additio ...@@ -3024,18 +3041,19 @@ function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additio
return false return false
end end
end end
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck,e) local patched_additional_fcheck=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck,e)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(additional_fgoalcheck,e) local patched_additional_fgoalcheck=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(additional_fgoalcheck,e)
local calculated_locked_codes=locked_codes
if type(locked_codes)=='function' then if type(locked_codes)=='function' then
Fusion.LockedCodes=locked_codes(c) calculated_locked_codes=locked_codes(c)
else
Fusion.LockedCodes=locked_codes
end end
local chkf=FusionSpell.GetCheckFieldPlayer(tp,skip_location_count_check) local chkf=FusionSpell.GetCheckFieldPlayer(tp,skip_location_count_check)
local res=Fusion.CheckFusionMaterial(c,mg,gc(e),chkf) local res=Fusion.CheckFusionMaterial(c,mg,gc(e),chkf,{
aux.FCheckAdditional=nil additional_fcheck=patched_additional_fcheck,
aux.FGoalCheckAdditional=nil additional_fgoalcheck=patched_additional_fgoalcheck,
Fusion.LockedCodes=nil locked_codes=calculated_locked_codes,
fcheck_signature=fcheck_signature,
})
return res return res
end end
...@@ -3414,10 +3432,6 @@ end ...@@ -3414,10 +3432,6 @@ end
Fusion={} Fusion={}
--- locked codes
Fusion.LockedCodes=nil
-- Refactored Fusion.AddFusionProcedure using the above helpers -- Refactored Fusion.AddFusionProcedure using the above helpers
function Fusion.AddFusionProcedure(c, opts) function Fusion.AddFusionProcedure(c, opts)
local patterns=Fusion.BuildPatterns(opts) local patterns=Fusion.BuildPatterns(opts)
...@@ -3476,7 +3490,7 @@ function Fusion.AddFusionProcedure(c, opts) ...@@ -3476,7 +3490,7 @@ function Fusion.AddFusionProcedure(c, opts)
end end
function Fusion.BasicCondition(tc,slots,matfilter,fgoalcheck,selected) function Fusion.BasicCondition(tc,slots,matfilter,fgoalcheck,selected)
return function(e,g,gc,chkf,allow_extras) return function(e,g,gc,chkf,allow_extras,locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature)
if not g then return false end if not g then return false end
-- Collect cards and apply global matfilter -- Collect cards and apply global matfilter
...@@ -3507,8 +3521,8 @@ function Fusion.BasicCondition(tc,slots,matfilter,fgoalcheck,selected) ...@@ -3507,8 +3521,8 @@ function Fusion.BasicCondition(tc,slots,matfilter,fgoalcheck,selected)
-- Prepare locked flags for substitute materials -- Prepare locked flags for substitute materials
local locked={} local locked={}
if Fusion.LockedCodes then if locked_codes then
for _, code in ipairs(Fusion.LockedCodes) do for _, code in ipairs(locked_codes) do
for i,slot in ipairs(single_slots) do for i,slot in ipairs(single_slots) do
-- direct match_code? -- direct match_code?
if slot.match_code==code then if slot.match_code==code then
...@@ -3551,16 +3565,16 @@ function Fusion.BasicCondition(tc,slots,matfilter,fgoalcheck,selected) ...@@ -3551,16 +3565,16 @@ function Fusion.BasicCondition(tc,slots,matfilter,fgoalcheck,selected)
-- No group slot? Just do final checks -- No group slot? Just do final checks
if not grp then if not grp then
return Fusion.FinalCheck(e,mg_base,tc,fgoalcheck,chkf) return Fusion.FinalCheck(mg_base,tc,fgoalcheck,chkf,additional_fcheck,additional_fgoalcheck)
end end
-- Group slot exists: branch on allow_extras -- Group slot exists: branch on allow_extras
if allow_extras then if allow_extras then
-- search mode: try to find some subset of size grp.min -- search mode: try to find some subset of size grp.min
return Fusion.SearchGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf) return Fusion.SearchGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf,additional_fcheck,additional_fgoalcheck)
else else
-- strict mode: leftovers must *all* satisfy grp -- strict mode: leftovers must *all* satisfy grp
return Fusion.StrictGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf) return Fusion.StrictGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf,additional_fcheck,additional_fgoalcheck)
end end
end end
...@@ -3600,10 +3614,10 @@ function Fusion.BasicCondition(tc,slots,matfilter,fgoalcheck,selected) ...@@ -3600,10 +3614,10 @@ function Fusion.BasicCondition(tc,slots,matfilter,fgoalcheck,selected)
end end
-- Final, post‐fusion checks (common to both modes) -- Final, post‐fusion checks (common to both modes)
function Fusion.FinalCheck(e,mg,tc,fgoalcheck,chkf) function Fusion.FinalCheck(mg,tc,fgoalcheck,chkf,additional_fcheck,additional_fgoalcheck)
if fgoalcheck and not fgoalcheck(mg) then return false end if fgoalcheck and not fgoalcheck(mg) then return false end
if aux.FCheckAdditional and not aux.FCheckAdditional(tc:GetOwner(),mg,tc) then return false end if additional_fcheck and not additional_fcheck(tc:GetOwner(),mg,tc) then return false end
if aux.FGoalCheckAdditional and not aux.FGoalCheckAdditional(tc:GetOwner(),mg,tc) then return false end if additional_fgoalcheck and not additional_fgoalcheck(tc:GetOwner(),mg,tc) then return false end
if not aux.TuneMagicianCheckAdditionalX(EFFECT_TUNE_MAGICIAN_F)(mg) then return false end if not aux.TuneMagicianCheckAdditionalX(EFFECT_TUNE_MAGICIAN_F)(mg) then return false end
if (chkf&0xf)~=PLAYER_NONE then if (chkf&0xf)~=PLAYER_NONE then
local tp=chkf&0xf local tp=chkf&0xf
...@@ -3615,7 +3629,7 @@ function Fusion.FinalCheck(e,mg,tc,fgoalcheck,chkf) ...@@ -3615,7 +3629,7 @@ function Fusion.FinalCheck(e,mg,tc,fgoalcheck,chkf)
end end
-- Strict mode: *all* leftovers must fit grp, then final check -- Strict mode: *all* leftovers must fit grp, then final check
function Fusion.StrictGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf) function Fusion.StrictGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf,additional_fcheck,additional_fgoalcheck)
-- filter leftovers by grp.filter -- filter leftovers by grp.filter
local matched={} local matched={}
for _,c in ipairs(leftovers) do for _,c in ipairs(leftovers) do
...@@ -3643,12 +3657,12 @@ function Fusion.StrictGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf) ...@@ -3643,12 +3657,12 @@ function Fusion.StrictGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf)
-- merge and final -- merge and final
local mg=mg_base:Clone() local mg=mg_base:Clone()
for _,c in ipairs(matched) do mg:AddCard(c) end for _,c in ipairs(matched) do mg:AddCard(c) end
return Fusion.FinalCheck(e,mg,tc,fgoalcheck,chkf) return Fusion.FinalCheck(mg,tc,fgoalcheck,chkf,additional_fcheck,additional_fgoalcheck)
end end
--- @param mg_base Group --- @param mg_base Group
-- Search mode: find *some* subset of size [grp.min…grp.max] that passes -- Search mode: find *some* subset of size [grp.min…grp.max] that passes
function Fusion.SearchGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf) function Fusion.SearchGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf,additional_fcheck,additional_fgoalcheck)
-- pre‐filter by grp.filter -- pre‐filter by grp.filter
local matched={} local matched={}
for _,c in ipairs(leftovers) do for _,c in ipairs(leftovers) do
...@@ -3726,7 +3740,7 @@ function Fusion.SearchGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf) ...@@ -3726,7 +3740,7 @@ function Fusion.SearchGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf)
ok_unique=matcher(sub_g_arr) ok_unique=matcher(sub_g_arr)
end end
-- final fusion checks -- final fusion checks
if ok_same and ok_unique and Fusion.FinalCheck(e,mg_tmp,tc,fgoalcheck,chkf) then if ok_same and ok_unique and Fusion.FinalCheck(mg_tmp,tc,fgoalcheck,chkf,additional_fcheck,additional_fgoalcheck) then
return true return true
end end
end end
...@@ -3903,8 +3917,9 @@ end ...@@ -3903,8 +3917,9 @@ end
--- @param cards_sel Card[] currently picked materials --- @param cards_sel Card[] currently picked materials
--- @param slots table[] your original slots spec --- @param slots table[] your original slots spec
--- @param tc Card the fusion monster (for substitutes) --- @param tc Card the fusion monster (for substitutes)
--- @param locked_codes integer[]|nil the list of locked slot code
--- @return table[] an array of mapping tables (or empty if none) --- @return table[] an array of mapping tables (or empty if none)
function Fusion.FindAllMappings(cards_sel, slots, tc) function Fusion.FindAllMappings(cards_sel,slots,tc,locked_codes)
--- empty selection, just return one “empty” mapping --- empty selection, just return one “empty” mapping
if #cards_sel==0 then if #cards_sel==0 then
return {{}} return {{}}
...@@ -3923,8 +3938,8 @@ function Fusion.FindAllMappings(cards_sel, slots, tc) ...@@ -3923,8 +3938,8 @@ function Fusion.FindAllMappings(cards_sel, slots, tc)
-- Prepare locked_slots for substitute‐material restrictions -- Prepare locked_slots for substitute‐material restrictions
local locked_slots={} local locked_slots={}
if Fusion.LockedCodes then if locked_codes then
for _, code in ipairs(Fusion.LockedCodes) do for _, code in ipairs(locked_codes) do
for idx, slot in ipairs(slots) do for idx, slot in ipairs(slots) do
local matched=false local matched=false
-- direct code match? -- direct code match?
...@@ -4076,7 +4091,7 @@ end ...@@ -4076,7 +4091,7 @@ end
--- @param slots table[] your slot definitions --- @param slots table[] your slot definitions
--- @param tc Card the Fusion monster (for substitutes) --- @param tc Card the Fusion monster (for substitutes)
--- @return boolean true if ∃ a mapping + completion path --- @return boolean true if ∃ a mapping + completion path
function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,gc,chkf) function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,gc,chkf,locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature)
-- arrayify sel so we can refer by index -- arrayify sel so we can refer by index
local cards_sel={} local cards_sel={}
for c in aux.Next(sel) do for c in aux.Next(sel) do
...@@ -4084,7 +4099,7 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,g ...@@ -4084,7 +4099,7 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,g
end end
-- get every possible assignment of sel→slots -- get every possible assignment of sel→slots
local mappings=Fusion.FindAllMappings(cards_sel,slots,tc) local mappings=Fusion.FindAllMappings(cards_sel,slots,tc,locked_codes)
if #mappings==0 then if #mappings==0 then
return false return false
end end
...@@ -4124,10 +4139,9 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,g ...@@ -4124,10 +4139,9 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,g
local rem_slots={} local rem_slots={}
-- rebuild dynamic locks per mapping -- rebuild dynamic locks per mapping
local old_locked=Fusion.LockedCodes
local new_locked={} local new_locked={}
if old_locked then if locked_codes then
for _,code in ipairs(old_locked) do for _,code in ipairs(locked_codes) do
-- find slot index for this code -- find slot index for this code
for j,slot in ipairs(slots) do for j,slot in ipairs(slots) do
local matches=(slot.match_code==code or (slot.match_codes and (function() local matches=(slot.match_code==code or (slot.match_codes and (function()
...@@ -4141,7 +4155,6 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,g ...@@ -4141,7 +4155,6 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,g
end end
end end
end end
Fusion.LockedCodes=new_locked
for i,slot in ipairs(slots) do for i,slot in ipairs(slots) do
if slot.group then if slot.group then
...@@ -4242,22 +4255,18 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,g ...@@ -4242,22 +4255,18 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,g
-- if nothing remains, we exhausted slots, check fgoal -- if nothing remains, we exhausted slots, check fgoal
if #rem_slots==0 then if #rem_slots==0 then
if Fusion.FinalCheck(e,sel,tc,fgoalcheck,chkf) then if Fusion.FinalCheck(sel,tc,fgoalcheck,chkf,additional_fcheck,additional_fgoalcheck) then
Fusion.LockedCodes=old_locked
return true return true
else else
Fusion.LockedCodes=old_locked
return false return false
end end
end end
-- delegate to BasicCondition (allow_extras=true) -- delegate to BasicCondition (allow_extras=true)
local cond=Fusion.BasicCondition(tc,rem_slots,matfilter,fgoalcheck,sel) local cond=Fusion.BasicCondition(tc,rem_slots,matfilter,fgoalcheck,sel)
if cond(e,rem_pool,gc,chkf,true--[[allow_extras]]) then if cond(e,rem_pool,gc,chkf,true--[[allow_extras]],new_locked,additional_fcheck,additional_fgoalcheck,fcheck_signature) then
Fusion.LockedCodes=old_locked
return true return true
end end
Fusion.LockedCodes=old_locked
end end
return false return false
...@@ -4390,14 +4399,13 @@ end ...@@ -4390,14 +4399,13 @@ end
-- Helper: combine multiple patterns into one condition function -- Helper: combine multiple patterns into one condition function
function Fusion.MultiCondition(tc,patterns) function Fusion.MultiCondition(tc,patterns)
return function(e,g,gc,chkf,selected,allow_extras,slots_only) return function(e,g,gc,chkf,selected,allow_extras,slots_only,locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature)
if not g then return false end if not g then return false end
local locked=Fusion.LockedCodes
for _,pat in ipairs(patterns) do for _,pat in ipairs(patterns) do
-- skip patterns that don't include all locked codes -- skip patterns that don't include all locked codes
local ok=true local ok=true
if locked then if locked_codes then
for _,code in ipairs(locked) do for _,code in ipairs(locked_codes) do
if not Fusion.PatternIncludesCode(pat,code) then if not Fusion.PatternIncludesCode(pat,code) then
ok=false ok=false
break break
...@@ -4407,12 +4415,12 @@ function Fusion.MultiCondition(tc,patterns) ...@@ -4407,12 +4415,12 @@ function Fusion.MultiCondition(tc,patterns)
if ok then if ok then
if not slots_only then if not slots_only then
local cond=Fusion.BasicCondition(tc,pat.slots,pat.matfilter,pat.fgoalcheck,selected) local cond=Fusion.BasicCondition(tc,pat.slots,pat.matfilter,pat.fgoalcheck,selected)
if cond(e,g,gc,chkf,allow_extras) then if cond(e,g,gc,chkf,allow_extras,locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature) then
return true return true
end end
else else
local cond=Fusion.BasicCondition(tc,pat.slots,aux.TRUE,aux.TRUE,selected) local cond=Fusion.BasicCondition(tc,pat.slots,aux.TRUE,aux.TRUE,selected)
if cond(e,g,gc,chkf,allow_extras) then if cond(e,g,gc,chkf,allow_extras,locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature) then
return true return true
end end
end end
...@@ -4445,14 +4453,13 @@ end ...@@ -4445,14 +4453,13 @@ end
-- Helper: combine patterns into one operation function -- Helper: combine patterns into one operation function
function Fusion.MultiOperation(tc,patterns) function Fusion.MultiOperation(tc,patterns)
return function(e,tp,eg,ep,ev,re,r,rp,gc,chkf,selected) return function(e,tp,mg,gc,chkf,selected,locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature)
-- filter patterns by any locked codes, once per operation -- filter patterns by any locked codes, once per operation
local locked=Fusion.LockedCodes
local active_patterns={} local active_patterns={}
if locked then if locked_codes then
for _,pat in ipairs(patterns) do for _,pat in ipairs(patterns) do
local ok=true local ok=true
for _, code in ipairs(locked) do for _, code in ipairs(locked_codes) do
if not Fusion.PatternIncludesCode(pat,code) then if not Fusion.PatternIncludesCode(pat,code) then
ok=false ok=false
break break
...@@ -4467,7 +4474,7 @@ function Fusion.MultiOperation(tc,patterns) ...@@ -4467,7 +4474,7 @@ function Fusion.MultiOperation(tc,patterns)
-- compute min/max over active patterns -- compute min/max over active patterns
local min_req,max_req=Fusion.PatternsMinMax(active_patterns) local min_req,max_req=Fusion.PatternsMinMax(active_patterns)
max_req=math.min(max_req,eg:GetCount()) max_req=math.min(max_req,mg:GetCount())
-- strict condition uses only active patterns -- strict condition uses only active patterns
local cond=Fusion.MultiCondition(tc,active_patterns) local cond=Fusion.MultiCondition(tc,active_patterns)
...@@ -4477,18 +4484,18 @@ function Fusion.MultiOperation(tc,patterns) ...@@ -4477,18 +4484,18 @@ function Fusion.MultiOperation(tc,patterns)
--- arraify eg --- arraify eg
local eg_arr={} local eg_arr={}
for mc in aux.Next(eg) do for mc in aux.Next(mg) do
table.insert(eg_arr,mc) table.insert(eg_arr,mc)
end end
while true do while true do
local finishable=sg:GetCount()>=min_req and cond(e,sg,gc,chkf,selected,false--[[allow_extras]]) local finishable=sg:GetCount()>=min_req and cond(e,sg,gc,chkf,selected,false--[[allow_extras]],false--[[slots_only]],locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature)
local addable=Group.CreateGroup() local addable=Group.CreateGroup()
-- check fcheck on the *current* sg -- check fcheck on the *current* sg
local prev_ok=true local prev_ok=true
if aux.FCheckAdditional~=nil then if additional_fcheck~=nil then
prev_ok=aux.FCheckAdditional(tc:GetOwner(),sg,tc) prev_ok=additional_fcheck(tc:GetOwner(),sg,tc)
end end
for _,mc in ipairs(eg_arr) do for _,mc in ipairs(eg_arr) do
...@@ -4497,15 +4504,15 @@ function Fusion.MultiOperation(tc,patterns) ...@@ -4497,15 +4504,15 @@ function Fusion.MultiOperation(tc,patterns)
-- early FCheckAdditional prune: if adding this card would cause fcheck to fail, we can not add it -- early FCheckAdditional prune: if adding this card would cause fcheck to fail, we can not add it
-- check fcheck again -- check fcheck again
local new_ok=true local new_ok=true
if aux.FCheckAdditional~=nil then if additional_fcheck~=nil then
new_ok=aux.FCheckAdditional(tc:GetOwner(),sg,tc) new_ok=additional_fcheck(tc:GetOwner(),sg,tc)
end end
-- prune if it was OK before but fails now -- prune if it was OK before but fails now
if not (prev_ok and not new_ok) then if not (prev_ok and not new_ok) then
-- completion test against active patterns -- completion test against active patterns
for _,pat in ipairs(active_patterns) do for _,pat in ipairs(active_patterns) do
if Fusion.CanCompleteFromMappings(e,sg,eg,pat.slots,pat.matfilter,pat.fgoalcheck,tc,gc,chkf) then if Fusion.CanCompleteFromMappings(e,sg,mg,pat.slots,pat.matfilter,pat.fgoalcheck,tc,gc,chkf,locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature) then
addable:AddCard(mc) addable:AddCard(mc)
break break
end end
...@@ -4517,20 +4524,19 @@ function Fusion.MultiOperation(tc,patterns) ...@@ -4517,20 +4524,19 @@ function Fusion.MultiOperation(tc,patterns)
if addable:GetCount()==0 then if addable:GetCount()==0 then
assert(finishable) assert(finishable)
Duel.SetFusionMaterial(sg) return sg
return
end end
local picked=Group.SelectUnselect(addable,sg,tp,finishable,true,min_req,max_req) local picked=Group.SelectUnselect(addable,sg,tp,finishable,true,min_req,max_req)
if not picked then if not picked then
if finishable then if finishable then
Duel.SetFusionMaterial(sg) return sg
else else
Duel.SetFusionMaterial(Group.CreateGroup()) return Group.CreateGroup()
end end
return
end end
assert(picked~=nil)
if sg:IsContains(picked) then if sg:IsContains(picked) then
-- If EFFECT_MUST_BE_FMATERIAL is on your field, ensure it's in selected -- If EFFECT_MUST_BE_FMATERIAL is on your field, ensure it's in selected
local must_materials=Duel.GetMustMaterial(tp,EFFECT_MUST_BE_FMATERIAL) local must_materials=Duel.GetMustMaterial(tp,EFFECT_MUST_BE_FMATERIAL)
...@@ -4564,7 +4570,7 @@ end ...@@ -4564,7 +4570,7 @@ end
--- @param patterns table[] --- @param patterns table[]
function Fusion.FusionCondition(tc,patterns) function Fusion.FusionCondition(tc,patterns)
return function(e,g,gc,chkf,opts,not_core) return function(e,g,gc,chkf,opts,not_core)
--- to bypass core check showing up in Card.IsHasEffect, we need this hack, used in Fusion.CheckFusionMaterial --- to bypass core check showing up in Card.IsHasEffect, we need this hack, used in Fusion.CheckFusionMaterial/Fusion.SelectFusinMaterial
if not_core==nil then return true end if not_core==nil then return true end
if not g then return false end if not g then return false end
opts=opts or {} opts=opts or {}
...@@ -4573,6 +4579,11 @@ function Fusion.FusionCondition(tc,patterns) ...@@ -4573,6 +4579,11 @@ function Fusion.FusionCondition(tc,patterns)
allow_extras=false allow_extras=false
end end
local slots_only=opts.slots_only or false local slots_only=opts.slots_only or false
local locked_codes=opts.locked_codes or nil
local additional_fcheck=opts.additional_fcheck or nil
local additional_fgoalcheck=opts.additional_fgoalcheck or nil
local fcheck_signature=opts.fcheck_signature or nil
-- build your seed group -- build your seed group
local selected=Group.CreateGroup() local selected=Group.CreateGroup()
if gc then selected:AddCard(gc) end if gc then selected:AddCard(gc) end
...@@ -4583,12 +4594,11 @@ function Fusion.FusionCondition(tc,patterns) ...@@ -4583,12 +4594,11 @@ function Fusion.FusionCondition(tc,patterns)
if allow_extras then if allow_extras then
-- attempt "search mode" on each pattern -- attempt "search mode" on each pattern
local locked=Fusion.LockedCodes
for _,pat in ipairs(patterns) do for _,pat in ipairs(patterns) do
-- skip patterns that don't include all locked codes -- skip patterns that don't include all locked codes
local ok=true local ok=true
if locked then if locked_codes then
for _,code in ipairs(locked) do for _,code in ipairs(locked_codes) do
if not Fusion.PatternIncludesCode(pat,code) then if not Fusion.PatternIncludesCode(pat,code) then
ok=false ok=false
break break
...@@ -4596,14 +4606,14 @@ function Fusion.FusionCondition(tc,patterns) ...@@ -4596,14 +4606,14 @@ function Fusion.FusionCondition(tc,patterns)
end end
end end
if ok then if ok then
if Fusion.CanCompleteFromMappings(e,selected,g,pat.slots,pat.matfilter,pat.fgoalcheck or aux.TRUE,tc,gc,chkf) then if Fusion.CanCompleteFromMappings(e,selected,g,pat.slots,pat.matfilter,pat.fgoalcheck or aux.TRUE,tc,gc,chkf,locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature) then
return true return true
end end
end end
end end
else else
-- attempt "strict mode" -- attempt "strict mode"
if Fusion.MultiCondition(tc,patterns)(e,g,gc,chkf,selected,allow_extras,slots_only) then if Fusion.MultiCondition(tc,patterns)(e,g,gc,chkf,selected,allow_extras,slots_only,locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature) then
return true return true
end end
end end
...@@ -4612,7 +4622,11 @@ function Fusion.FusionCondition(tc,patterns) ...@@ -4612,7 +4622,11 @@ function Fusion.FusionCondition(tc,patterns)
end end
function Fusion.FusionOperation(c,patterns) function Fusion.FusionOperation(c,patterns)
return function(e,tp,eg,ep,ev,re,r,rp,gc,chkf) return function(e,tp,mg,gc,chkf,opts)
local locked_codes=opts.locked_codes or nil
local additional_fcheck=opts.additional_fcheck or nil
local additional_fgoalcheck=opts.additional_fgoalcheck or nil
local fcheck_signature=opts.fcheck_signature or nil
-- build selected = {gc} -- build selected = {gc}
local selected = Group.CreateGroup() local selected = Group.CreateGroup()
if gc then selected:AddCard(gc) end if gc then selected:AddCard(gc) end
...@@ -4620,7 +4634,7 @@ function Fusion.FusionOperation(c,patterns) ...@@ -4620,7 +4634,7 @@ function Fusion.FusionOperation(c,patterns)
local must_materials=Duel.GetMustMaterial(tp,EFFECT_MUST_BE_FMATERIAL) local must_materials=Duel.GetMustMaterial(tp,EFFECT_MUST_BE_FMATERIAL)
selected:Merge(must_materials) selected:Merge(must_materials)
-- call the original op, swapping in selected for gc -- call the original op, swapping in selected for gc
return Fusion.MultiOperation(c,patterns)(e,tp,eg,ep,ev,re,r,rp,gc,chkf,selected) return Fusion.MultiOperation(c,patterns)(e,tp,mg,gc,chkf,selected,locked_codes,additional_fcheck,additional_fgoalcheck,fcheck_signature)
end end
end end
...@@ -4635,3 +4649,12 @@ function Fusion.CheckFusionMaterial(tc,mg,gc,chkf,opts) ...@@ -4635,3 +4649,12 @@ function Fusion.CheckFusionMaterial(tc,mg,gc,chkf,opts)
end end
return false return false
end end
--- shadowing Duel.SelectFusionMaterial as it core does not pass all param back to lua
function Fusion.SelectFusionMaterial(tp,tc,mg,gc,chkf,opts)
opts=opts or {}
local effs={tc:IsHasEffect(EFFECT_FUSION_MATERIAL,tp)}
local eff=effs[1]
local sg=eff:GetOperation()(eff,tp,mg,gc,chkf,opts)
return sg
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