Commit 340d2b38 authored by wind2009's avatar wind2009

Merge branch 'new-fusion-Clock-Lizard' into 'master'

Add クロック・リザード + add e,tp to fusfilter, and skip_summon_check to params

See merge request !52
parents d992ab56 a1348ff3
--クロック・リザード --クロック・リザード
function c51476410.initial_effect(c) local s,id,o=GetID()
function s.initial_effect(c)
--link summon --link summon
c:EnableReviveLimit() c:EnableReviveLimit()
aux.AddLinkProcedure(c,aux.FilterBoolFunction(Card.IsLinkRace,RACE_CYBERSE),2,2) aux.AddLinkProcedure(c,aux.FilterBoolFunction(Card.IsLinkRace,RACE_CYBERSE),2,2)
--fusion summon --fusion summon
local e1=Effect.CreateEffect(c) local e1=FusionSpell.CreateSummonEffect(c,{
e1:SetDescription(aux.Stringid(51476410,0)) fusfilter=s.fusfilter,
pre_select_mat_location=LOCATION_GRAVE,
fuslocation=LOCATION_GRAVE,
mat_operation_code_map={
{ [LOCATION_REMOVED]=FusionSpell.FUSION_OPERATION_GRAVE },
{ [0xff]=FusionSpell.FUSION_OPERATION_BANISH }
},
extra_target=s.extra_target,
stage_x_operation=s.stage_x_operation,
skip_summon_check=true
})
e1:SetDescription(aux.Stringid(id,0))
e1:SetCategory(CATEGORY_TOEXTRA+CATEGORY_SPECIAL_SUMMON+CATEGORY_FUSION_SUMMON) e1:SetCategory(CATEGORY_TOEXTRA+CATEGORY_SPECIAL_SUMMON+CATEGORY_FUSION_SUMMON)
e1:SetType(EFFECT_TYPE_IGNITION) e1:SetType(EFFECT_TYPE_IGNITION)
e1:SetRange(LOCATION_MZONE) e1:SetRange(LOCATION_MZONE)
e1:SetCost(c51476410.spcost) e1:SetCost(s.spcost)
e1:SetTarget(c51476410.sptg)
e1:SetOperation(c51476410.spop)
c:RegisterEffect(e1) c:RegisterEffect(e1)
--remove --remove
local e2=Effect.CreateEffect(c) local e2=Effect.CreateEffect(c)
e2:SetDescription(aux.Stringid(51476410,1)) e2:SetDescription(aux.Stringid(id,1))
e2:SetCategory(CATEGORY_ATKCHANGE) e2:SetCategory(CATEGORY_ATKCHANGE)
e2:SetType(EFFECT_TYPE_SINGLE+EFFECT_TYPE_TRIGGER_O) e2:SetType(EFFECT_TYPE_SINGLE+EFFECT_TYPE_TRIGGER_O)
e2:SetProperty(EFFECT_FLAG_DELAY) e2:SetProperty(EFFECT_FLAG_DELAY)
e2:SetCode(EVENT_REMOVE) e2:SetCode(EVENT_REMOVE)
e2:SetCondition(c51476410.atkcon) e2:SetCondition(s.atkcon)
e2:SetTarget(c51476410.atktg) e2:SetTarget(s.atktg)
e2:SetOperation(c51476410.atkop) e2:SetOperation(s.atkop)
c:RegisterEffect(e2) c:RegisterEffect(e2)
end end
function c51476410.spcost(e,tp,eg,ep,ev,re,r,rp,chk)
function s.spcost(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return e:GetHandler():IsReleasable() end if chk==0 then return e:GetHandler():IsReleasable() end
Duel.Release(e:GetHandler(),REASON_COST) Duel.Release(e:GetHandler(),REASON_COST)
end end
function c51476410.spfilter0(c)
return c:IsType(TYPE_MONSTER) and c:IsCanBeFusionMaterial() and c:IsAbleToRemove() --- @param c Card
function s.fusfilter(c,e,tp)
--- FIXME: this is just ignore revive limit
--- If player is under different oath about monsters can be special summoned from Grave and Extra deck, this will fail
--- e.g. 嗤う黒山羊, ヴァリアンツ etc
return c:IsAbleToExtra() and c:IsCanBeSpecialSummoned(e,SUMMON_TYPE_FUSION,tp,false,true)
end end
function c51476410.spfilter1(c,e)
return c:IsType(TYPE_MONSTER) and c:IsCanBeFusionMaterial() and c:IsAbleToRemove() and not c:IsImmuneToEffect(e) function s.extra_target(e,tp,eg,ep,ev,re,r,rp,chk)
end if chk==0 then
function c51476410.spfilter2(c,e,tp,m,f,chkf) return true
return (not f or f(c)) and c:IsCanBeSpecialSummoned(e,SUMMON_TYPE_FUSION,tp,false,true) and c:CheckFusionMaterial(m,nil,chkf)
end
function c51476410.spfilter3(c,e,tp,chkf,rc)
if not c:IsType(TYPE_FUSION) or not c:IsAbleToExtra() then return false end
if Duel.GetLocationCountFromEx(tp,tp,rc,TYPE_FUSION)<=0 then return false end
local mg=Duel.GetMatchingGroup(c51476410.spfilter0,tp,LOCATION_GRAVE,0,c)
local res=c51476410.spfilter2(c,e,tp,mg,nil,chkf)
if not res then
local ce=Duel.GetChainMaterial(tp)
if ce~=nil then
local fgroup=ce:GetTarget()
local mg2=fgroup(ce,e,tp)
local mf=ce:GetValue()
res=c51476410.spfilter2(c,e,tp,mg,mf,chkf)
end
end end
return res
end
function c51476410.sptg(e,tp,eg,ep,ev,re,r,rp,chk)
local chkf=PLAYER_NONE
if chk==0 then return Duel.IsPlayerCanRemove(tp)
and Duel.IsExistingMatchingCard(c51476410.spfilter3,tp,LOCATION_GRAVE,0,1,nil,e,tp,chkf,e:GetHandler()) end
Duel.SetOperationInfo(0,CATEGORY_TOEXTRA,nil,1,tp,LOCATION_GRAVE) Duel.SetOperationInfo(0,CATEGORY_TOEXTRA,nil,1,tp,LOCATION_GRAVE)
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,nil,1,tp,LOCATION_EXTRA)
end end
function c51476410.spop(e,tp,eg,ep,ev,re,r,rp)
if not Duel.IsPlayerCanRemove(tp) then return end --- @type FUSION_SPELL_STAGE_X_CALLBACK_FUNCTION
local chkf=tp function s.stage_x_operation(e,tc,tp,stage)
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_TODECK) if stage==FusionSpell.STAGE_BEFORE_MOVE_MATERIAL then
local g=Duel.SelectMatchingCard(tp,aux.NecroValleyFilter(c51476410.spfilter3),tp,LOCATION_GRAVE,0,1,1,nil,e,tp,chkf,nil) Duel.HintSelection(Group.FromCards(tc))
local tc=g:GetFirst() if Duel.SendtoDeck(tc,nil,SEQ_DECKSHUFFLE,REASON_EFFECT)==0 then
if tc and Duel.SendtoDeck(tc,nil,SEQ_DECKSHUFFLE,REASON_EFFECT)~=0 and tc:IsLocation(LOCATION_EXTRA) then return false
local mg1=Duel.GetMatchingGroup(c51476410.spfilter1,tp,LOCATION_GRAVE,0,nil,e)
local mgchk1=c51476410.spfilter2(tc,e,tp,mg1,nil,chkf)
local mg2=nil
local mgchk2=false
local ce=Duel.GetChainMaterial(tp)
if ce~=nil then
local fgroup=ce:GetTarget()
mg2=fgroup(ce,e,tp)
local mf=ce:GetValue()
mgchk2=c51476410.spfilter2(tc,e,tp,mg2,mf,chkf)
end end
if mgchk1 or mgchk2 then if not tc:IsLocation(LOCATION_EXTRA) then
if mgchk1 and (not mgchk2 or not Duel.SelectYesNo(tp,ce:GetDescription())) then return false
local mat1=Duel.SelectFusionMaterial(tp,tc,mg1,nil,chkf)
tc:SetMaterial(mat1)
Duel.Remove(mat1,POS_FACEUP,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION)
Duel.BreakEffect()
Duel.SpecialSummon(tc,SUMMON_TYPE_FUSION,tp,tp,false,false,POS_FACEUP)
else
local mat2=Duel.SelectFusionMaterial(tp,tc,mg2,nil,chkf)
local fop=ce:GetOperation()
fop(ce,e,tp,tc,mat2)
end
tc:CompleteProcedure()
end end
Duel.BreakEffect()
return true
end end
end end
function c51476410.atkcon(e,tp,eg,ep,ev,re,r,rp)
function s.atkcon(e,tp,eg,ep,ev,re,r,rp)
local c=e:GetHandler() local c=e:GetHandler()
return c:IsFaceup() and c:IsPreviousLocation(LOCATION_GRAVE) return c:IsFaceup() and c:IsPreviousLocation(LOCATION_GRAVE)
end end
function c51476410.atkfilter(c)
function s.atkfilter(c)
return c:IsFaceup() and c:IsSummonType(SUMMON_TYPE_SPECIAL) return c:IsFaceup() and c:IsSummonType(SUMMON_TYPE_SPECIAL)
end end
function c51476410.atktg(e,tp,eg,ep,ev,re,r,rp,chk)
function s.atktg(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsExistingMatchingCard(Card.IsRace,tp,LOCATION_GRAVE,0,1,nil,RACE_CYBERSE) if chk==0 then return Duel.IsExistingMatchingCard(Card.IsRace,tp,LOCATION_GRAVE,0,1,nil,RACE_CYBERSE)
and Duel.IsExistingMatchingCard(c51476410.atkfilter,tp,0,LOCATION_MZONE,1,nil) end and Duel.IsExistingMatchingCard(s.atkfilter,tp,0,LOCATION_MZONE,1,nil) end
end end
function c51476410.atkop(e,tp,eg,ep,ev,re,r,rp)
local g=Duel.GetMatchingGroup(c51476410.atkfilter,tp,0,LOCATION_MZONE,nil) function s.atkop(e,tp,eg,ep,ev,re,r,rp)
local g=Duel.GetMatchingGroup(s.atkfilter,tp,0,LOCATION_MZONE,nil)
if g:GetCount()==0 then return end if g:GetCount()==0 then return end
local atk=Duel.GetMatchingGroupCount(Card.IsRace,tp,LOCATION_GRAVE,0,nil,RACE_CYBERSE)*400 local atk=Duel.GetMatchingGroupCount(Card.IsRace,tp,LOCATION_GRAVE,0,nil,RACE_CYBERSE)*400
local tc=g:GetFirst() local tc=g:GetFirst()
......
...@@ -2276,8 +2276,8 @@ FusionSpell = {} ...@@ -2276,8 +2276,8 @@ FusionSpell = {}
---@alias FUSION_FGCHECK_FUNCTION fun(tp:integer,mg:Group,fc:Card,mg_all:Group,e:Effect):boolean ---@alias FUSION_FGCHECK_FUNCTION fun(tp:integer,mg:Group,fc:Card,mg_all:Group,e:Effect):boolean
--- @class FusionEffectParams --- @class FusionEffectParams
--- @field fusfilter? fun(c:Card):boolean --- Optional filter to restrict which Fusion Monsters can be summoned.
--- Optional filter to restrict which Fusion Monsters can be summoned. --- @field fusfilter? fun(c:Card,e:Effect,tp:integer):boolean
--- Optional filter for valid Fusion Materials. --- Optional filter for valid Fusion Materials.
--- Use only under strong constraints (e.g., D-Fusion effects). --- Use only under strong constraints (e.g., D-Fusion effects).
--- If some card can not be used even under Chain Material or EXTRA_FUSION_MATERIAL, use this filter. --- If some card can not be used even under Chain Material or EXTRA_FUSION_MATERIAL, use this filter.
...@@ -2322,6 +2322,8 @@ FusionSpell = {} ...@@ -2322,6 +2322,8 @@ FusionSpell = {}
--- If some card can not be used by fusion spell, but could be used with EXTRA_FUSION_MATERIAL, use this filter. --- If some card can not be used by fusion spell, but could be used with EXTRA_FUSION_MATERIAL, use this filter.
--- Fusion with Chain Material will never call this function, as no material comes from fusion spell. --- Fusion with Chain Material will never call this function, as no material comes from fusion spell.
--- @field fusion_spell_matfilter? FUSION_SPELL_MATFILTER_FUNCTION --- @field fusion_spell_matfilter? FUSION_SPELL_MATFILTER_FUNCTION
--- Whether skip the IsCanBeSpecialSummoned check, for クロック・リザード, default false
--- @field skip_summon_check? boolean
--- 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
...@@ -2400,6 +2402,7 @@ function FusionSpell.CreateSummonEffect(c,opts) ...@@ -2400,6 +2402,7 @@ function FusionSpell.CreateSummonEffect(c,opts)
local post_select_mat_opponent_location=opts.post_select_mat_opponent_location or 0 local post_select_mat_opponent_location=opts.post_select_mat_opponent_location or 0
local gc=opts.gc or function() return nil end local gc=opts.gc or function() return nil end
local fusion_spell_matfilter=opts.fusion_spell_matfilter or aux.TRUE local fusion_spell_matfilter=opts.fusion_spell_matfilter or aux.TRUE
local skip_summon_check=opts.skip_summon_check or false
-- 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 })
...@@ -2425,7 +2428,8 @@ function FusionSpell.CreateSummonEffect(c,opts) ...@@ -2425,7 +2428,8 @@ function FusionSpell.CreateSummonEffect(c,opts)
pre_select_mat_opponent_location, pre_select_mat_opponent_location,
post_select_mat_opponent_location, post_select_mat_opponent_location,
gc, gc,
fusion_spell_matfilter fusion_spell_matfilter,
skip_summon_check
)) ))
e1:SetOperation(FusionSpell.GetSummonOperation( e1:SetOperation(FusionSpell.GetSummonOperation(
fusfilter, fusfilter,
...@@ -2442,13 +2446,14 @@ function FusionSpell.CreateSummonEffect(c,opts) ...@@ -2442,13 +2446,14 @@ function FusionSpell.CreateSummonEffect(c,opts)
pre_select_mat_opponent_location, pre_select_mat_opponent_location,
post_select_mat_opponent_location, post_select_mat_opponent_location,
gc, gc,
fusion_spell_matfilter fusion_spell_matfilter,
skip_summon_check
)) ))
e1:SetDescription(1169) --- 融合召喚 e1:SetDescription(1169) --- 融合召喚
return e1 return e1
end end
---@param fusfilter fun(c:Card):boolean filter for the monster to be Fusion Summoned ---@param fusfilter fun(c:Card,e:Effect,tp:integer):boolean filter for the monster to be Fusion Summoned
---@param matfilter FUSION_SPELL_MATFILTER_FUNCTION filter for the materials, use it only under very strong limitation like D-Fusion. ---@param matfilter FUSION_SPELL_MATFILTER_FUNCTION filter for the materials, use it only under very strong limitation like D-Fusion.
---@param pre_select_mat_location integer|FUSION_SPELL_PRE_SELECT_MAT_LOCATION_FUNCTION location where to find the materials before known the materials ---@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 mat_operation_code_map {[integer]:FUSION_OPERATION_CODE}[] operation code to do for the materials, it will be check in order
...@@ -2463,6 +2468,7 @@ end ...@@ -2463,6 +2468,7 @@ end
---@param post_select_mat_opponent_location integer location where to find the materials after known the materials on opponent location ---@param post_select_mat_opponent_location integer location where to find the materials after known the materials on opponent location
---@param gc fun(e:Effect):Card|nil Function that returns a card that must be included in the fusion materials ---@param gc fun(e:Effect):Card|nil Function that returns a card that must be included in the fusion materials
---@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 クロック・リザード
function FusionSpell.GetSummonTarget( function FusionSpell.GetSummonTarget(
fusfilter, fusfilter,
matfilter, matfilter,
...@@ -2478,7 +2484,8 @@ function FusionSpell.GetSummonTarget( ...@@ -2478,7 +2484,8 @@ function FusionSpell.GetSummonTarget(
pre_select_mat_opponent_location, pre_select_mat_opponent_location,
post_select_mat_opponent_location, post_select_mat_opponent_location,
gc, gc,
fusion_spell_matfilter fusion_spell_matfilter,
skip_summon_check
) )
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
...@@ -2501,7 +2508,8 @@ function FusionSpell.GetSummonTarget( ...@@ -2501,7 +2508,8 @@ function FusionSpell.GetSummonTarget(
pre_select_mat_opponent_location, pre_select_mat_opponent_location,
post_select_mat_opponent_location, post_select_mat_opponent_location,
gc, gc,
fusion_spell_matfilter) fusion_spell_matfilter,
skip_summon_check)
end, end,
tp,fuslocation,0,1,nil) tp,fuslocation,0,1,nil)
if sg==true then if sg==true then
...@@ -2509,7 +2517,7 @@ function FusionSpell.GetSummonTarget( ...@@ -2509,7 +2517,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) local ce_sg=FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check)
if ce_sg==true then if ce_sg==true then
return true return true
end end
...@@ -2521,7 +2529,7 @@ function FusionSpell.GetSummonTarget( ...@@ -2521,7 +2529,7 @@ function FusionSpell.GetSummonTarget(
end end
end end
---@param fusfilter fun(c:Card):boolean filter for the monster to be Fusion Summoned ---@param fusfilter fun(c:Card,e:Effect,tp:integer):boolean filter for the monster to be Fusion Summoned
---@param matfilter FUSION_SPELL_MATFILTER_FUNCTION filter for the materials, use it only under very strong limitation like D-Fusion. ---@param matfilter FUSION_SPELL_MATFILTER_FUNCTION filter for the materials, use it only under very strong limitation like D-Fusion.
---@param pre_select_mat_location integer|FUSION_SPELL_PRE_SELECT_MAT_LOCATION_FUNCTION location where to find the materials before known the materials ---@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 mat_operation_code_map {[integer]:FUSION_OPERATION_CODE}[] operation code to do for the materials, it will be check in order
...@@ -2536,6 +2544,7 @@ end ...@@ -2536,6 +2544,7 @@ end
---@param post_select_mat_opponent_location integer location where to find the materials after known the materials on opponent location ---@param post_select_mat_opponent_location integer location where to find the materials after known the materials on opponent location
---@param gc fun(e:Effect):Card|nil Function that returns a card that must be included in the fusion materials ---@param gc fun(e:Effect):Card|nil Function that returns a card that must be included in the fusion materials
---@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 クロック・リザード
function FusionSpell.GetSummonOperation( function FusionSpell.GetSummonOperation(
fusfilter, fusfilter,
matfilter, matfilter,
...@@ -2551,7 +2560,8 @@ function FusionSpell.GetSummonOperation( ...@@ -2551,7 +2560,8 @@ function FusionSpell.GetSummonOperation(
pre_select_mat_opponent_location, pre_select_mat_opponent_location,
post_select_mat_opponent_location, post_select_mat_opponent_location,
gc, gc,
fusion_spell_matfilter fusion_spell_matfilter,
skip_summon_check
) )
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
...@@ -2574,14 +2584,15 @@ function FusionSpell.GetSummonOperation( ...@@ -2574,14 +2584,15 @@ function FusionSpell.GetSummonOperation(
pre_select_mat_opponent_location, pre_select_mat_opponent_location,
post_select_mat_opponent_location, post_select_mat_opponent_location,
gc, gc,
fusion_spell_matfilter) fusion_spell_matfilter,
skip_summon_check)
end, end,
tp,fuslocation,0,nil) tp,fuslocation,0,nil)
fusion_targets:Merge(sg) fusion_targets:Merge(sg)
--- check for chain material targets --- check for chain material targets
local ce_sgs={} local ce_sgs={}
if sumtype&SUMMON_TYPE_FUSION~=0 then if sumtype&SUMMON_TYPE_FUSION~=0 then
ce_sgs=FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,aux.NecroValleyFilter(matfilter),additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc) ce_sgs=FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,aux.NecroValleyFilter(matfilter),additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check)
--- add chain material targets --- add chain material targets
for _,ce_sg in pairs(ce_sgs) do for _,ce_sg in pairs(ce_sgs) do
fusion_targets:Merge(ce_sg) fusion_targets:Merge(ce_sg)
...@@ -2761,52 +2772,55 @@ function FusionSpell.GetSummonOperation( ...@@ -2761,52 +2772,55 @@ function FusionSpell.GetSummonOperation(
end end
end end
-- before do the operations to the materials, hint the opponent selected materials if stage_x_operation(e,tc,tp,FusionSpell.STAGE_BEFORE_MOVE_MATERIAL,materials_from_spell_card,materials)~=false then
local confirm_materials=materials:Filter(function(c) return c:IsLocation(LOCATION_HAND|LOCATION_EXTRA|LOCATION_DECK) or c:IsFacedown() end,nil) -- before do the operations to the materials, hint the opponent selected materials
if #confirm_materials>0 then local confirm_materials=materials:Filter(function(c) return c:IsLocation(LOCATION_HAND|LOCATION_EXTRA|LOCATION_DECK) or c:IsFacedown() end,nil)
Duel.ConfirmCards(1-tp,confirm_materials) if #confirm_materials>0 then
end Duel.ConfirmCards(1-tp,confirm_materials)
Duel.HintSelection(materials-confirm_materials) end
Duel.HintSelection(materials-confirm_materials)
stage_x_operation(e,tc,tp,FusionSpell.STAGE_BEFORE_MOVE_MATERIAL,materials_from_spell_card,materials)
local operated_material_count=0 local operated_material_count=0
-- perform operations on grouped materials -- perform operations on grouped materials
for operation,grouped_materials in pairs(material_grouped_by_op) do for operation,grouped_materials in pairs(material_grouped_by_op) do
operated_material_count=operated_material_count+operation(grouped_materials,tp) operated_material_count=operated_material_count+operation(grouped_materials,tp)
end end
-- mark effect as used once. if count limit reached, reset the effect -- mark effect as used once. if count limit reached, reset the effect
for effect,_ in pairs(applied_extra_effects) do for effect,_ in pairs(applied_extra_effects) do
--- hint opponent that this effect is applied --- hint opponent that this effect is applied
Duel.Hint(HINT_OPSELECTED,1-tp,effect:GetDescription()) Duel.Hint(HINT_OPSELECTED,1-tp,effect:GetDescription())
effect:UseCountLimit(tp) effect:UseCountLimit(tp)
if effect:CheckCountLimit(tp)==false then if effect:CheckCountLimit(tp)==false then
effect:Reset() effect:Reset()
end
end end
end
-- check if all materials are moved successfully (ラピッド・トリガー) -- check if all materials are moved successfully (ラピッド・トリガー)
fusion_succeeded=(operated_material_count==#materials) fusion_succeeded=(operated_material_count==#materials)
if fusion_succeeded==true then if fusion_succeeded==true then
Duel.BreakEffect() Duel.BreakEffect()
Duel.SpecialSummonStep(tc,sumtype,tp,tp,false,false,sumpos) Duel.SpecialSummonStep(tc,sumtype,tp,tp,false,false,sumpos)
end
end end
else else
--- hint opponent that this effect is applied if stage_x_operation(e,tc,tp,FusionSpell.STAGE_BEFORE_MOVE_MATERIAL,materials_from_spell_card,materials)~=false then
Duel.Hint(HINT_OPSELECTED,1-tp,fusion_effect:GetDescription()) --- hint opponent that this effect is applied
Duel.Hint(HINT_OPSELECTED,1-tp,fusion_effect:GetDescription())
--- fusion with chain material
fusion_effect:GetOperation()(e,e,tp,tc,materials,sumtype,sumpos) --- fusion with chain material
--- use the chain material effect, reset if exhausted fusion_effect:GetOperation()(e,e,tp,tc,materials,sumtype,sumpos)
fusion_effect:UseCountLimit(tp) --- use the chain material effect, reset if exhausted
if fusion_effect:CheckCountLimit(tp)==false then fusion_effect:UseCountLimit(tp)
fusion_effect:Reset() if fusion_effect:CheckCountLimit(tp)==false then
fusion_effect:Reset()
end
-- for chain material effects as of 2025 May it always succeeds
fusion_succeeded=true
end end
-- for chain material effects as of 2025 May it always succeeds
fusion_succeeded=true
end end
if fusion_succeeded==true then if fusion_succeeded==true then
...@@ -2903,14 +2917,15 @@ function FusionSpell.GetOperationCodeByMaterialLocation(location,mat_operation_c ...@@ -2903,14 +2917,15 @@ function FusionSpell.GetOperationCodeByMaterialLocation(location,mat_operation_c
end end
end end
---@param fusfilter fun(c:Card,tp:integer):boolean ---@param fusfilter fun(c:Card,e:Effect,tp:integer):boolean
---@param matfilter FUSION_SPELL_MATFILTER_FUNCTION filter for the materials, use it only under very strong limitation like D-Fusion. ---@param matfilter FUSION_SPELL_MATFILTER_FUNCTION filter for the materials, use it only under very strong limitation like D-Fusion.
---@param pre_select_mat_location integer|FUSION_SPELL_PRE_SELECT_MAT_LOCATION_FUNCTION location where to find the materials before known the materials (default LOCATION_HAND|LOCATION_MZONE) ---@param pre_select_mat_location integer|FUSION_SPELL_PRE_SELECT_MAT_LOCATION_FUNCTION location where to find the materials before known the materials (default LOCATION_HAND|LOCATION_MZONE)
---@param post_select_mat_location integer location where to find the materials after known the materials ---@param post_select_mat_location integer location where to find the materials after known the materials
---@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 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 post_select_mat_opponent_location integer location where to find the materials before known the materials on opponent location ---@param post_select_mat_opponent_location integer location where to find the materials before known the materials on opponent location
---@param gc fun(e:Effect):Card|nil ---@param gc fun(e:Effect):Card|nil
---@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 fun(c:Card):boolean 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 クロック・リザード
function FusionSpell.SummonTargetFilter( function FusionSpell.SummonTargetFilter(
c, c,
fusfilter, fusfilter,
...@@ -2927,11 +2942,16 @@ function FusionSpell.SummonTargetFilter( ...@@ -2927,11 +2942,16 @@ function FusionSpell.SummonTargetFilter(
pre_select_mat_opponent_location, pre_select_mat_opponent_location,
post_select_mat_opponent_location, post_select_mat_opponent_location,
gc, gc,
fusion_spell_matfilter) fusion_spell_matfilter,
local res=c:IsType(TYPE_FUSION) and fusfilter(c,tp) and c:IsCanBeSpecialSummoned(e,sumtype,tp,false,false,sumpos) skip_summon_check)
if res==false then if not c:IsType(TYPE_FUSION) or fusfilter(c,e,tp)==false then
return false return false
end end
if not skip_summon_check then
if not c:IsCanBeSpecialSummoned(e,sumtype,tp,false,false,sumpos) then
return false
end
end
local mg=FusionSpell.GetMaterialsGroupForTargetCard( local mg=FusionSpell.GetMaterialsGroupForTargetCard(
c, c,
tp, tp,
...@@ -2956,7 +2976,7 @@ function FusionSpell.SummonTargetFilter( ...@@ -2956,7 +2976,7 @@ function FusionSpell.SummonTargetFilter(
e, e,
mat_operation_code_map) mat_operation_code_map)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(additional_fgoalcheck,tp,c,pre_select_mat_location,e) aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(additional_fgoalcheck,tp,c,pre_select_mat_location,e)
res=c:CheckFusionMaterial(mg,gc(e),tp) local res=c:CheckFusionMaterial(mg,gc(e),tp)
aux.FCheckAdditional=nil aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil aux.FGoalCheckAdditional=nil
return res return res
...@@ -2964,8 +2984,9 @@ end ...@@ -2964,8 +2984,9 @@ end
---@param matfilter FUSION_SPELL_MATFILTER_FUNCTION filter for the materials, use it only under very strong limitation like D-Fusion. ---@param matfilter FUSION_SPELL_MATFILTER_FUNCTION filter for the materials, use it only under very strong limitation like D-Fusion.
---@param gc fun(e:Effect):Card|nil ---@param gc fun(e:Effect):Card|nil
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@return {[Effect]:Group} effect_targets_map Return a map of different chain material to potiential fusion targets ---@return {[Effect]:Group} effect_targets_map Return a map of different chain material to potiential fusion targets
function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc) function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check)
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}
local chain_material_targets={} local chain_material_targets={}
...@@ -2977,7 +2998,7 @@ function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,matfilter,add ...@@ -2977,7 +2998,7 @@ function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,matfilter,add
if #chain_mg>0 then if #chain_mg>0 then
local ce_fusfilter=ce:GetValue() local ce_fusfilter=ce:GetValue()
local ce_sg=Duel.GetMatchingGroup(function(c) local ce_sg=Duel.GetMatchingGroup(function(c)
return FusionSpell.ChainMaterialSummonTargetFilter(c,aux.AND(ce_fusfilter,fusfilter),e,tp,chain_mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc) return FusionSpell.ChainMaterialSummonTargetFilter(c,aux.AND(ce_fusfilter,fusfilter),e,tp,chain_mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc,skip_summon_check)
end,tp,fuslocation,0,nil) end,tp,fuslocation,0,nil)
if #ce_sg>0 then if #ce_sg>0 then
chain_material_targets[ce]=ce_sg chain_material_targets[ce]=ce_sg
...@@ -2987,10 +3008,12 @@ function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,matfilter,add ...@@ -2987,10 +3008,12 @@ function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,matfilter,add
return chain_material_targets return chain_material_targets
end end
---@param fusfilter fun(c:Card,e:Effect,tp:integer):boolean
---@param matfilter FUSION_SPELL_MATFILTER_FUNCTION filter for the materials, use it only under very strong limitation like D-Fusion. ---@param matfilter FUSION_SPELL_MATFILTER_FUNCTION filter for the materials, use it only under very strong limitation like D-Fusion.
---@param gc fun(e:Effect):Card|nil ---@param gc fun(e:Effect):Card|nil
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, 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) function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check)
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
...@@ -3000,7 +3023,7 @@ function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter ...@@ -3000,7 +3023,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) 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)
end, end,
tp,fuslocation,0,1,nil) tp,fuslocation,0,1,nil)
if res==true then if res==true then
...@@ -3012,22 +3035,28 @@ function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter ...@@ -3012,22 +3035,28 @@ function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter
end end
---@param c Card ---@param c Card
---@param fusfilter fun(c:Card,e:Effect,tp:integer):boolean
---@param gc fun(e:Effect):Card|nil ---@param gc fun(e:Effect):Card|nil
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, 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) function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc,skip_summon_check)
local res=c:IsType(TYPE_FUSION) and fusfilter(c,tp) and c:IsCanBeSpecialSummoned(e,sumtype,tp,false,false,sumpos) if not c:IsType(TYPE_FUSION) or fusfilter(c,e,tp)==false then
if res==false then
return false return false
end end
if not skip_summon_check then
if not c:IsCanBeSpecialSummoned(e,sumtype,tp,false,false,sumpos) then
return false
end
end
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck,e) aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck,e)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(additional_fgoalcheck,e) aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(additional_fgoalcheck,e)
res=c:CheckFusionMaterial(mg,gc(e),tp) local res=c:CheckFusionMaterial(mg,gc(e),tp)
aux.FCheckAdditional=nil aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil aux.FGoalCheckAdditional=nil
return res return res
end end
---@alias FUSION_SPELL_STAGE_X_CALLBACK_FUNCTION fun(e:Effect,tc:Card,tp:integer,stage:FUSION_SPELL_CALLBACK_STAGE,mg_fuison_spell:Group,mg_all:Group) ---@alias FUSION_SPELL_STAGE_X_CALLBACK_FUNCTION fun(e:Effect,tc:Card,tp:integer,stage:FUSION_SPELL_CALLBACK_STAGE,mg_fuison_spell:Group,mg_all:Group):boolean|nil
-- different stage for call back -- different stage for call back
---@alias FUSION_SPELL_CALLBACK_STAGE integer ---@alias FUSION_SPELL_CALLBACK_STAGE integer
-- Right before the Fusion Monster is officially summoned -- Right before the Fusion Monster is officially summoned
...@@ -3038,7 +3067,7 @@ FusionSpell.STAGE_BEFORE_PROCEDURE_COMPLETE=2 ...@@ -3038,7 +3067,7 @@ FusionSpell.STAGE_BEFORE_PROCEDURE_COMPLETE=2
FusionSpell.STAGE_AT_SUMMON_OPERATION_FINISH=3 FusionSpell.STAGE_AT_SUMMON_OPERATION_FINISH=3
-- After **all** operations have run, whether the summon succeeded or not -- After **all** operations have run, whether the summon succeeded or not
FusionSpell.STAGE_AT_ALL_OPERATION_FINISH=4 FusionSpell.STAGE_AT_ALL_OPERATION_FINISH=4
-- Right before the selected materials are moved -- Right before the selected materials are moved, the return value of this stage will be checked, fusion procedure will be terminated if returned false
FusionSpell.STAGE_BEFORE_MOVE_MATERIAL=5 FusionSpell.STAGE_BEFORE_MOVE_MATERIAL=5
-- operation that would be applied on the material -- operation that would be applied on the material
......
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