Commit dc1d0a9d authored by Vury Leo's avatar Vury Leo

init new fusion

parent dc8d834b
--プロキシー・F・マジシャン
local s,id,o=GetID()
function s.initial_effect(c)
--link summon
c:EnableReviveLimit()
aux.AddLinkProcedure(c,aux.FilterBoolFunction(Card.IsLinkType,TYPE_EFFECT),2)
--fusion
local e1=FusionSpell.CreateSummonEffect(c,nil,nil,LOCATION_ONFIELD)
e1:SetDescription(aux.Stringid(id,0))
e1:SetType(EFFECT_TYPE_IGNITION)
e1:SetRange(LOCATION_MZONE)
e1:SetCountLimit(1,id)
c:RegisterEffect(e1)
--spsummon
local e2=Effect.CreateEffect(c)
e2:SetDescription(aux.Stringid(id,1))
e2:SetCategory(CATEGORY_SPECIAL_SUMMON)
e2:SetType(EFFECT_TYPE_FIELD+EFFECT_TYPE_TRIGGER_O)
e2:SetCode(EVENT_SPSUMMON_SUCCESS)
e2:SetProperty(EFFECT_FLAG_DELAY)
e2:SetRange(LOCATION_MZONE)
e2:SetCountLimit(1,id+o)
e2:SetCondition(s.spcon)
e2:SetTarget(s.sptg)
e2:SetOperation(s.spop)
c:RegisterEffect(e2)
end
function s.cfilter(c,g)
return c:IsFaceup() and c:IsType(TYPE_FUSION) and c:IsSummonType(SUMMON_TYPE_FUSION) and g:IsContains(c)
end
function s.spfilter(c,e,tp)
return c:IsAttackBelow(1000) and c:IsCanBeSpecialSummoned(e,0,tp,false,false)
end
function s.spcon(e,tp,eg,ep,ev,re,r,rp)
local lg=e:GetHandler():GetLinkedGroup()
return lg and eg:IsExists(s.cfilter,1,nil,lg) and not eg:IsContains(e:GetHandler())
end
function s.sptg(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.GetLocationCount(tp,LOCATION_MZONE)>0
and Duel.IsExistingMatchingCard(s.spfilter,tp,LOCATION_HAND,0,1,nil,e,tp) end
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,nil,1,tp,LOCATION_HAND)
end
function s.spop(e,tp,eg,ep,ev,re,r,rp)
if Duel.GetLocationCount(tp,LOCATION_MZONE)<=0 then return end
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_SPSUMMON)
local g=Duel.SelectMatchingCard(tp,s.spfilter,tp,LOCATION_HAND,0,1,1,nil,e,tp)
if g:GetCount()>0 then
Duel.SpecialSummon(g,0,tp,tp,false,false,POS_FACEUP)
end
end
\ No newline at end of file
--月光舞踏会
local s,id,o=GetID()
function s.initial_effect(c)
aux.AddCodeList(c,24094653)
--Activate
local e1=Effect.CreateEffect(c)
e1:SetType(EFFECT_TYPE_ACTIVATE)
e1:SetCode(EVENT_FREE_CHAIN)
e1:SetCost(s.reg)
c:RegisterEffect(e1)
--send to GY
local e2=Effect.CreateEffect(c)
e2:SetDescription(aux.Stringid(id,0))
e2:SetCategory(CATEGORY_TOGRAVE)
e2:SetType(EFFECT_TYPE_IGNITION)
e2:SetRange(LOCATION_SZONE)
e2:SetCountLimit(1,id)
e2:SetCondition(s.tgcon)
e2:SetTarget(s.tgtg)
e2:SetOperation(s.tgop)
c:RegisterEffect(e2)
--to hand
local e3=Effect.CreateEffect(c)
e3:SetCategory(CATEGORY_TOHAND+CATEGORY_GRAVE_ACTION+CATEGORY_HANDES)
e3:SetType(EFFECT_TYPE_FIELD+EFFECT_TYPE_TRIGGER_O)
e3:SetProperty(EFFECT_FLAG_DELAY)
e3:SetCode(EVENT_SPSUMMON_SUCCESS)
e3:SetRange(LOCATION_SZONE)
e3:SetCountLimit(1,id+o)
e3:SetCondition(s.thcon)
e3:SetTarget(s.thtg)
e3:SetOperation(s.thop)
c:RegisterEffect(e3)
end
function s.reg(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return true end
e:GetHandler():RegisterFlagEffect(id,RESET_EVENT+RESETS_STANDARD+RESET_PHASE+PHASE_END,EFFECT_FLAG_OATH,1)
end
function s.tgcon(e,tp,eg,ep,ev,re,r,rp)
return e:GetHandler():GetFlagEffect(id)~=0
end
function s.tgfilter(c)
return c:IsSetCard(0xdf) and c:IsType(TYPE_MONSTER) and c:IsAbleToGrave()
end
function s.tgtg(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsExistingMatchingCard(s.tgfilter,tp,LOCATION_DECK,0,1,nil) end
Duel.SetOperationInfo(0,CATEGORY_TOGRAVE,nil,1,tp,LOCATION_DECK)
end
function s.tgop(e,tp,eg,ep,ev,re,r,rp)
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_TOGRAVE)
local g=Duel.SelectMatchingCard(tp,s.tgfilter,tp,LOCATION_DECK,0,1,1,nil)
if g:GetCount()>0 then
Duel.SendtoGrave(g,REASON_EFFECT)
end
end
function s.cfilter(c,tp)
return c:IsFaceup() and c:IsSetCard(0xdf) and c:IsSummonType(SUMMON_TYPE_FUSION) and c:IsSummonPlayer(tp)
and c:IsAllTypes(TYPE_FUSION+TYPE_MONSTER)
end
function s.thcon(e,tp,eg,ep,ev,re,r,rp)
return eg:IsExists(s.cfilter,1,nil,tp)
end
function s.thfilter(c)
return c:IsFaceupEx() and c:IsCode(24094653) and c:IsAbleToHand()
end
function s.thtg(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsExistingMatchingCard(s.thfilter,tp,LOCATION_GRAVE+LOCATION_REMOVED,0,1,nil) end
Duel.SetOperationInfo(0,CATEGORY_TOHAND,nil,1,tp,LOCATION_GRAVE+LOCATION_REMOVED)
end
function s.thop(e,tp,eg,ep,ev,re,r,rp)
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_ATOHAND)
local g=Duel.SelectMatchingCard(tp,aux.NecroValleyFilter(s.thfilter),tp,LOCATION_GRAVE+LOCATION_REMOVED,0,1,1,nil)
local tc=g:GetFirst()
if tc and Duel.SendtoHand(tc,nil,REASON_EFFECT)~=0 and tc:IsLocation(LOCATION_HAND) then
Duel.ConfirmCards(1-tp,g)
local sg=Duel.GetMatchingGroup(Card.IsDiscardable,tp,LOCATION_HAND,0,nil,REASON_EFFECT+REASON_DISCARD)
if sg:GetCount()>0 and Duel.SelectYesNo(tp,aux.Stringid(id,2)) then
Duel.BreakEffect()
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_DISCARD)
local dg=sg:Select(tp,1,1,nil)
Duel.ShuffleHand(tp)
Duel.SendtoGrave(dg,REASON_EFFECT+REASON_DISCARD)
--Once this turn, if you Fusion Summon a "Lunalight" monster, you can also banish monsters from your grave as material
local e1=Effect.CreateEffect(e:GetHandler())
e1:SetType(EFFECT_TYPE_FIELD)
e1:SetCode(EFFECT_EXTRA_FUSION_MATERIAL)
e1:SetCountLimit(1)
e1:SetTargetRange(LOCATION_GRAVE,0)
e1:SetTarget(function(_,c) return c:IsAbleToRemove() and c:IsType(TYPE_MONSTER) end)
e1:SetOperation(function() return FusionSpell.FUSION_OPERATION_BANISH end)
e1:SetValue(function(fusion_effect,c) return c and c:IsSetCard(0xdf) and c:IsControler(fusion_effect:GetHandlerPlayer()) end)
e1:SetReset(RESET_PHASE|PHASE_END)
Duel.RegisterEffect(e1,tp)
end
end
end
-- --月光舞踏会
-- local s,id=GetID()
-- function s.initial_effect(c)
-- --Activate
-- local e1=Effect.CreateEffect(c)
-- e1:SetType(EFFECT_TYPE_ACTIVATE)
-- e1:SetCode(EVENT_FREE_CHAIN)
-- c:RegisterEffect(e1)
-- --fake one, activate to get extra materials
-- local e2=Effect.CreateEffect(c)
-- e2:SetDescription(aux.Stringid(id,0))
-- e2:SetType(EFFECT_TYPE_IGNITION)
-- e2:SetRange(LOCATION_SZONE)
-- e2:SetOperation(s.op)
-- c:RegisterEffect(e2)
-- end
-- function s.op(e,tp,eg,ep,ev,re,r,rp)
-- --Once this turn, if you Fusion Summon a "Lunalight" monster, you can also banish monsters from your grave as material
-- local c=e:GetHandler()
-- local e1=Effect.CreateEffect(c)
-- e1:SetType(EFFECT_TYPE_FIELD)
-- e1:SetCode(EFFECT_EXTRA_FUSION_MATERIAL)
-- e1:SetCountLimit(1)
-- e1:SetTargetRange(LOCATION_GRAVE,0)
-- e1:SetTarget(function(e,c) return c:IsAbleToRemove() and c:IsType(TYPE_MONSTER) end)
-- e1:SetOperation(function() return FusionSpell.FUSION_OPERATION_BANISH end)
-- e1:SetValue(function(e,c) return c and c:IsSetCard(0xdf) and c:IsControler(e:GetHandlerPlayer()) end)
-- e1:SetReset(RESET_PHASE|PHASE_END)
-- Duel.RegisterEffect(e1,tp)
-- end
--融合
local s,id,o=GetID()
function s.initial_effect(c)
FusionSpell.RegisterSummonEffect(c)
end
--パワー・ボンド
local s,id,o=GetID()
function s.initial_effect(c)
--Activate
FusionSpell.RegisterSummonEffect(c,s.fusfilter,nil,nil,nil,nil,nil,nil,nil,nil,nil,s.stage_x_operation)
end
---@param c Card
function s.fusfilter(c)
return c:IsRace(RACE_MACHINE)
end
---@type FUSION_SPELL_STAGE_X_CALLBACK_FUNCTION
function s.stage_x_operation(e,tc,tp,stage,mg_fuison_spell,mg_all)
--- register if the summon is finished
if stage==FusionSpell.STAGE_AT_SUMMON_OPERATION_FINISH then
-- if base ATK is 0, do nothing
local atk=tc:GetBaseAttack()
if atk<=0 then
return
end
---increase ATK
local e1=Effect.CreateEffect(e:GetHandler())
e1:SetType(EFFECT_TYPE_SINGLE)
e1:SetCode(EFFECT_UPDATE_ATTACK)
e1:SetValue(tc:GetBaseAttack())
e1:SetReset(RESET_EVENT+RESETS_STANDARD)
tc:RegisterEffect(e1,true)
--- do damage on end phase
if e:IsHasType(EFFECT_TYPE_ACTIVATE) then
local e2=Effect.CreateEffect(e:GetHandler())
e2:SetType(EFFECT_TYPE_FIELD+EFFECT_TYPE_CONTINUOUS)
e2:SetCode(EVENT_PHASE+PHASE_END)
e2:SetCountLimit(1)
e2:SetLabel(tc:GetBaseAttack())
e2:SetReset(RESET_PHASE+PHASE_END)
e2:SetOperation(s.damop)
Duel.RegisterEffect(e2,tp)
end
end
end
function s.damop(e,tp,eg,ep,ev,re,r,rp)
Duel.Damage(tp,e:GetLabel(),REASON_EFFECT)
end
--サイバー・ダーク・キメラ
local s,id,o=GetID()
function s.initial_effect(c)
--to hand
local e1=Effect.CreateEffect(c)
e1:SetDescription(aux.Stringid(id,0))
e1:SetCategory(CATEGORY_TOHAND+CATEGORY_SEARCH)
e1:SetType(EFFECT_TYPE_IGNITION)
e1:SetRange(LOCATION_MZONE)
e1:SetCountLimit(1,id)
e1:SetCost(s.thcost)
e1:SetTarget(s.thtg)
e1:SetOperation(s.thop)
c:RegisterEffect(e1)
--to grave
local e2=Effect.CreateEffect(c)
e2:SetDescription(aux.Stringid(id,1))
e2:SetCategory(CATEGORY_TOGRAVE)
e2:SetType(EFFECT_TYPE_SINGLE+EFFECT_TYPE_TRIGGER_O)
e2:SetCode(EVENT_TO_GRAVE)
e2:SetProperty(EFFECT_FLAG_DELAY)
e2:SetCountLimit(1,id+o)
e2:SetTarget(s.tgtg)
e2:SetOperation(s.tgop)
c:RegisterEffect(e2)
end
function s.costfilter(c)
return c:IsType(TYPE_SPELL+TYPE_TRAP) and c:IsDiscardable()
end
function s.thcost(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsExistingMatchingCard(s.costfilter,tp,LOCATION_HAND,0,1,nil) end
Duel.DiscardHand(tp,s.costfilter,1,1,REASON_COST+REASON_DISCARD,nil)
end
function s.thfilter(c)
return c:IsCode(37630732) and c:IsAbleToHand()
end
function s.thtg(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsExistingMatchingCard(s.thfilter,tp,LOCATION_DECK,0,1,nil) end
Duel.SetOperationInfo(0,CATEGORY_TOHAND,nil,1,tp,LOCATION_DECK)
end
function s.thop(e,tp,eg,ep,ev,re,r,rp)
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_ATOHAND)
local g=Duel.SelectMatchingCard(tp,s.thfilter,tp,LOCATION_DECK,0,1,1,nil)
if g:GetCount()>0 then
Duel.SendtoHand(g,nil,REASON_EFFECT)
Duel.ConfirmCards(1-tp,g)
end
-- Can only use Dragon or Machine "Cyber" monsters as Fusion Material this turn
local e1=Effect.CreateEffect(e:GetHandler())
e1:SetType(EFFECT_TYPE_FIELD)
e1:SetCode(EFFECT_CANNOT_BE_FUSION_MATERIAL)
e1:SetProperty(EFFECT_FLAG_SET_AVAILABLE+EFFECT_FLAG_IGNORE_IMMUNE)
e1:SetTargetRange(0xff,0xff)
e1:SetTarget(s.limittg)
e1:SetValue(s.fuslimit)
e1:SetReset(RESET_PHASE+PHASE_END)
Duel.RegisterEffect(e1,tp)
--Can also banish monsters from your GY as material once when you Fusion Summon this turn
local e2=Effect.CreateEffect(e:GetHandler())
e2:SetDescription(aux.Stringid(id,2))
e2:SetType(EFFECT_TYPE_FIELD)
e2:SetCode(EFFECT_EXTRA_FUSION_MATERIAL)
e2:SetTargetRange(LOCATION_GRAVE,0)
e2:SetCountLimit(1)
e2:SetTarget(s.mttg)
e2:SetOperation(function() return FusionSpell.FUSION_OPERATION_BANISH end)
e2:SetValue(1)
e2:SetReset(RESET_PHASE+PHASE_END)
Duel.RegisterEffect(e2,tp)
end
function s.limittg(e,c)
return not (c:IsRace(RACE_DRAGON+RACE_MACHINE) and c:IsSetCard(0x93))
end
function s.fuslimit(e,c,sumtype)
if not c then return false end
return c:IsControler(e:GetHandlerPlayer())
end
function s.mttg(e,c)
return c:IsType(TYPE_MONSTER) and c:IsAbleToRemove()
end
function s.tgfilter(c,tp)
return c:IsSetCard(0x4093) and c:IsType(TYPE_MONSTER)
and not Duel.IsExistingMatchingCard(Card.IsCode,tp,LOCATION_GRAVE,0,1,nil,c:GetCode()) and c:IsAbleToGrave()
end
function s.tgtg(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsExistingMatchingCard(s.tgfilter,tp,LOCATION_DECK,0,1,nil,tp) end
Duel.SetOperationInfo(0,CATEGORY_TOGRAVE,nil,1,tp,LOCATION_DECK)
end
function s.tgop(e,tp,eg,ep,ev,re,r,rp)
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_TOGRAVE)
local g=Duel.SelectMatchingCard(tp,s.tgfilter,tp,LOCATION_DECK,0,1,1,nil,tp)
if g:GetCount()>0 then
Duel.SendtoGrave(g,REASON_EFFECT)
end
end
\ No newline at end of file
--月光融合
local s,id=GetID()
function s.initial_effect(c)
--Activate
local e1=FusionSpell.CreateSummonEffect(c,s.fusfilter,nil,s.pre_select_mat_location,nil,nil,s.fcheck,s.gcheck)
e1:SetCategory(CATEGORY_SPECIAL_SUMMON+CATEGORY_FUSION_SUMMON+CATEGORY_DECKDES)
e1:SetCountLimit(1,id+EFFECT_COUNT_CODE_OATH)
c:RegisterEffect(e1)
end
---@param c Card
function s.fusfilter(c)
return c:IsSetCard(0xdf)
end
---@type FUSION_SPELL_PRE_SELECT_MAT_LOCATION_FUNCTION
function s.pre_select_mat_location(tc,tp)
local res=LOCATION_HAND|LOCATION_ONFIELD
if Duel.IsExistingMatchingCard(s.cfilter,tp,0,LOCATION_MZONE,1,nil) then
res=res|LOCATION_DECK|LOCATION_EXTRA
end
return res
end
function s.cfilter(c)
return c:IsSummonLocation(LOCATION_EXTRA)
end
function s.fcheck(tp,mg,fc,all_mg)
---@type Group
local extra_mg=mg:Filter(Card.IsLocation,nil,LOCATION_DECK+LOCATION_EXTRA)
if #extra_mg==0 then
return true
end
--- by fusion spell, the material from deck/extra can only be at most 1
if #extra_mg>1 then
return false
end
--- by fusion spell, the material from deck/extra must be Lunalight monster
if extra_mg:FilterCount(Card.IsSetCard,nil,0xdf)~=#extra_mg then
return false
end
return true
end
function s.gcheck(sg)
return sg:FilterCount(Card.IsLocation,nil,LOCATION_DECK+LOCATION_EXTRA)<=1
end
......@@ -1982,3 +1982,572 @@ function Auxiliary.MonsterEffectPropertyFilter(flag)
return e:IsHasProperty(flag) and not e:IsHasRange(LOCATION_PZONE)
end
end
FusionSpell = {}
---@alias FUSION_SPELL_PRE_SELECT_MAT_LOCATION_FUNCTION fun(tc:Card,tp:integer):integer
---@alias FUSION_FCHECK_FUNCTION fun(tp:integer,mg:Group,fc:Card,all_mg:Group):boolean
--- Add LOCATION_EXTRA to EFFECT_EXTRA_FUSION_MATERIAL list, remove once core updated
function FusionSpell.GetFusionMaterial(tp,locations)
local res=Duel.GetFusionMaterial(tp,locations)
local g=Duel.GetMatchingGroup(Card.IsHasEffect,tp,LOCATION_EXTRA,0,nil,EFFECT_EXTRA_FUSION_MATERIAL)
if #g>0 then
res:Merge(g)
end
return res
end
---@param c Card card that uses the effect
---@param fusfilter (fun(c:Card):boolean)? filter for the monster to be Fusion Summoned
---@param matfilter (fun(c:Card):boolean)? 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 mat_operation_code_map {[integer]:FUSION_OPERATION_CODE}[]? operation code to do for the materials, it will be check in order (default [{ LOCATION_GRAVE: FUSION_OPERATION_BANISH}, { 0xff: FUSION_OPERATION_GRAVE}])
---@param post_select_mat_location integer? location where to find the materials after known the materials (default nil)
---@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 fuslocation integer? location where to summon fusion monsters from (default LOCATION_EXTRA), use it on Clock Lizard
---@param sumtype integer? summon type (default SUMMON_TYPE_FUSION)
---@param sumpos integer? summon position (default POS_FACEUP)
---@param stage_x_operation function? callback function when special summon is in progress. will be called with different stage name
function FusionSpell.RegisterSummonEffect(c,fusfilter,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,additional_gcheck,fuslocation,sumtype,sumpos,stage_x_operation)
local e1=FusionSpell.CreateSummonEffect(c,fusfilter,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,additional_gcheck,fuslocation,sumtype,sumpos,stage_x_operation)
Card.RegisterEffect(c,e1)
return e1
end
---@param c Card card that uses the effect
---@param fusfilter (fun(c:Card):boolean)? filter for the monster to be Fusion Summoned
---@param matfilter (fun(c:Card):boolean)? 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_ONFIELD)
---@param mat_operation_code_map {[integer]:FUSION_OPERATION_CODE}[]? operation code to do for the materials, it will be check in order (default [{ LOCATION_GRAVE: FUSION_OPERATION_BANISH}, { 0xff: FUSION_OPERATION_GRAVE}])
---@param post_select_mat_location integer? location where to find the materials after known the materials (default nil)
---@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 fuslocation integer? location where to summon fusion monsters from (default LOCATION_EXTRA), use it on Clock Lizard
---@param sumtype integer? summon type (default SUMMON_TYPE_FUSION)
---@param sumpos integer? summon position (default POS_FACEUP)
---@param stage_x_operation function? callback function when special summon is in progress. will be called with different stage name
function FusionSpell.CreateSummonEffect(c,fusfilter,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,additional_gcheck,fuslocation,sumtype,sumpos,stage_x_operation)
matfilter=matfilter or aux.TRUE
pre_select_mat_location=pre_select_mat_location or LOCATION_HAND|LOCATION_ONFIELD
mat_operation_code_map=mat_operation_code_map or {}
-- add last fallback, banish grave, grave others
table.insert(mat_operation_code_map,{[LOCATION_GRAVE]=FusionSpell.FUSION_OPERATION_BANISH})
table.insert(mat_operation_code_map,{[0xff]=FusionSpell.FUSION_OPERATION_GRAVE})
fuslocation=fuslocation or LOCATION_EXTRA
sumtype=sumtype or SUMMON_TYPE_FUSION
sumpos=sumpos or POS_FACEUP
stage_x_operation=stage_x_operation or aux.TRUE
local e1=Effect.CreateEffect(c)
e1:SetCategory(CATEGORY_SPECIAL_SUMMON+CATEGORY_FUSION_SUMMON)
e1:SetType(EFFECT_TYPE_ACTIVATE)
e1:SetCode(EVENT_FREE_CHAIN)
e1:SetTarget(FusionSpell.GetSummonTarget(fusfilter,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,additional_gcheck,fuslocation,sumtype,sumpos))
e1:SetOperation(FusionSpell.GetSummonOperation(fusfilter,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,additional_gcheck,fuslocation,sumtype,sumpos,stage_x_operation))
return e1
end
---@param fusfilter fun(c:Card):boolean? filter for the monster to be Fusion Summoned
---@param matfilter fun(c:Card):boolean? 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 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 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
function FusionSpell.GetSummonTarget(fusfilter,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,additional_gcheck,fuslocation,sumtype,sumpos)
return function(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then
local sg=Duel.GetMatchingGroup(FusionSpell.SummonTargetFilter,tp,fuslocation,0,nil,fusfilter,matfilter,e,tp,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,sumtype,sumpos)
-- --- check for chain material targets
-- if sumtype&SUMMON_TYPE_FUSION~=0 then
-- local ce_sg=FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,sumtype,sumpos)
-- if #ce_sg>0 then
-- sg:Merge(ce_sg)
-- end
-- end
return #sg>0
end
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,nil,1,tp,fuslocation)
end
end
---@param fusfilter fun(c:Card):boolean filter for the monster to be Fusion Summoned
---@param matfilter fun(c:Card):boolean 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 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 fuslocation integer location where to summon fusion monsters from, use it on Clock Lizard
---@param sumtype integer summon type
---@param sumpos integer summon position
---@param stage_x_operation function callback function when special summon is in progress. will be called with different stage name
function FusionSpell.GetSummonOperation(fusfilter,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,additional_gcheck,fuslocation,sumtype,sumpos,stage_x_operation)
return function(e,tp,eg,ep,ev,re,r,rp)
local sg=Duel.GetMatchingGroup(FusionSpell.SummonTargetFilter,tp,fuslocation,0,nil,fusfilter,matfilter,e,tp,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,sumtype,sumpos)
--- check for chain material targets
local ce_sg={}
-- if sumtype&SUMMON_TYPE_FUSION~=0 then
-- local ce_sgs=FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,sumtype,sumpos)
-- end
local tc=nil
if #sg>0 or #ce_sgs>0 then
local materials=Group.CreateGroup()
local fusion_effect=nil
while #materials==0 do
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_SPSUMMON)
---@type Group
local fusion_targets=sg:Clone()
-- for _, ce_sg in pairs(ce_sgs) do
-- fusion_targets:Merge(ce_sg)
-- end
tc=fusion_targets:Select(tp,1,1,nil):GetFirst()
---@type Effect[]
local avaliable_fusion_effect = {}
if sg:IsContains(tc) then
table.insert(avaliable_fusion_effect,e)
end
-- for ce, ce_sg in pairs(ce_sgs) do
-- if ce_sg:IsContains(tc) then
-- table.insert(avaliable_fusion_effect,ce)
-- end
-- end
assert(#avaliable_fusion_effect>0, "Selected a target card that has 0 fusion effect")
fusion_effect=avaliable_fusion_effect[1]
if #avaliable_fusion_effect>1 then
fusion_effect=FusionSpell.MultiFusionEffectPrompt(avaliable_fusion_effect)
end
if fusion_effect==e then
--- use fusion spell effect
local mg=FusionSpell.GetMaterialsGroupForTargetCard(tc,tp,e,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location)
if additional_fcheck~=nil then
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunction(additional_fcheck,tp,c)
end
materials=Duel.SelectFusionMaterial(tp,tc,mg,nil,tp)
aux.FCheckAdditional=nil
else
-- --- use chain material effect
-- ---@type function
-- local chain_material_filter=ce:GetTarget()
-- local chain_mg=chain_material_filter(ce,e,tp)
-- assert(#chain_mg>0, "we are trying to apply a chain material, but it has no possible material")
-- if additional_fcheck~=nil then
-- aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck,tp,c)
-- end
-- materials=Duel.SelectFusionMaterial(tp,tc,chain_mg)
-- aux.FCheckAdditional=nil
end
end
assert(tc~=nil)
assert(fusion_effect~=nil)
if #materials>0 then
if fusion_effect==e then
--- fusion with fusion spell
tc:SetMaterial(materials)
local all_locations=FusionSpell.GetAllLocationsForTargetCard(tc,tp,pre_select_mat_location,post_select_mat_location)
---@type Effect[]
local applied_extra_effects={}
---@type {[FUSION_OPERATION_FUNCTION]:Group}
local material_grouped_by_op={}
--For material that can be material only by 1 effect, either fusion spell or extra material effect, do the operation on it.
--For material that can be material by multiple effect, ask user which to apply.
for material in aux.Next(materials) do
local material_effects=FusionSpell.GetMaterialEffects(material,tc,all_locations,materials)
if material_effects~=nil and #material_effects>0 then
local material_effect=nil
if #material_effects==1 then
material_effect=material_effects[1]
else
-- more than one effect. ask player to choose from one.
material_effect=FusionSpell.MultiMaterialEffectPrompt(material_effects,tp,e)
end
local fusion_operation=nil
if material_effect==true then
local fusion_operation_code=FusionSpell.GetOperationCodeByMaterialLocation(material:GetLocation(),mat_operation_code_map)
fusion_operation=FusionSpell.GetFusionOperationByCode(fusion_operation_code)
else
-- extra material effects
local fusion_operation_code=material_effect:GetOperation()()
fusion_operation=FusionSpell.GetFusionOperationByCode(fusion_operation_code,material:GetLocation(),mat_operation_code_map)
table.insert(applied_extra_effects,material_effect)
end
assert(fusion_operation~=nil)
material_grouped_by_op[fusion_operation]=material_grouped_by_op[fusion_operation] or Group.CreateGroup()
material_grouped_by_op[fusion_operation]:AddCard(material)
else
--else we are in trouble
assert(false,string.format("card %d has no material effect",material:GetCode()))
end
end
-- perform operations on materials
for operation,materials in pairs(material_grouped_by_op) do
operation(materials,tp)
end
-- mark effect as used once. if count limit reached, reset the effect
for _,effect in ipairs(applied_extra_effects) do
effect:UseCountLimit(tp)
if effect:CheckCountLimit(tp)==false then
effect:Reset()
end
end
Duel.BreakEffect()
Duel.SpecialSummonStep(tc,SUMMON_TYPE_FUSION,tp,tp,false,false,sumpos)
else
-- --- fusion with chain material
-- fusion_effect:GetOperation()(e,e,tp,tc,materials,sumtype,sumpos)
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)
end
stage_x_operation(e,tc,tp,FusionSpell.STAGE_AT_ALL_OPERATION_FINISH)
end
end
---@param pre_select_mat_location integer|(fun(tc:Card,tp:integer):integer) location where to find the materials before known the materials
---@return integer locations all possible locations of the material
function FusionSpell.GetAllLocationsForTargetCard(tc,tp,pre_select_mat_location,post_select_mat_location)
local all_locations=0
if type(pre_select_mat_location)=="function" then
all_locations=all_locations|pre_select_mat_location(tc,tp)
else
assert(pre_select_mat_location~=nil, "pre_select_mat_location is nil")
all_locations=all_locations|pre_select_mat_location
end
if post_select_mat_location~=nil then
all_locations=all_locations|post_select_mat_location
end
return all_locations
end
---@param matfilter fun(c:Card):boolean filter for the materials, use it only under very strong limitation like D-Fusion.
---@param pre_select_mat_location integer|function location where to find the materials before known the materials
function FusionSpell.GetMaterialsGroupForTargetCard(tc,tp,e,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location)
local all_locations=FusionSpell.GetAllLocationsForTargetCard(tc,tp,pre_select_mat_location,post_select_mat_location)
local mg=FusionSpell.GetFusionMaterial(tp,all_locations)
-- filter by the strong material filter, target card can not be fusion material of itself
mg=mg:Filter(matfilter,tc)
--- filter out card can not be affected by effect
mg=mg:Filter(aux.NOT(Card.IsImmuneToEffect),nil,e)
--- filter out card can not be material
mg=mg:Filter(Card.IsCanBeFusionMaterial,nil,tc)
--- in order to be qualified for being material, it need to be able to perform the operation.
mg=mg:Filter(function(mc)
local can_be_fusion_spell_material=false
if mc:IsLocation(all_locations) then
---@type FUSION_FILTER_FUNCTION
local filter_by_operation=FusionSpell.GetFusionFilterByCode(FusionSpell.GetOperationCodeByMaterialLocation(mc:GetLocation(),mat_operation_code_map))
can_be_fusion_spell_material=filter_by_operation(mc,tp,e)
end
local can_be_extra_material=false
local extra_effect=FusionSpell.GetExtraMaterialEffect(mc,tp,tc)
if extra_effect~=nil then
---@type FUSION_OPERATION_CODE
local operation_code=FusionSpell.FUSION_OPERATION_INHERIT
if extra_effect:GetOperation()~=nil then
operation_code=extra_effect:GetOperation()()
end
operation_code=operation_code or FusionSpell.FUSION_OPERATION_INHERIT
---@type FUSION_FILTER_FUNCTION
local filter_by_operation=FusionSpell.GetFusionFilterByCode(operation_code,mc:GetLocation(),mat_operation_code_map)
can_be_extra_material=filter_by_operation(mc,tp,e)
end
return can_be_fusion_spell_material or can_be_extra_material
end,nil)
return mg
end
---@param location integer
---@param mat_operation_code_map {[integer]:FUSION_OPERATION_CODE}[]? operation code to do for the materials, it will be check in order
function FusionSpell.GetOperationCodeByMaterialLocation(location,mat_operation_code_map)
for _,map in ipairs(mat_operation_code_map) do
for key,value in pairs(map) do
if location&key~=0 then
return value
end
end
end
end
---@param fusfilter fun(c:Card,tp:integer):boolean
---@param matfilter fun(c:Card,tp:integer):boolean
---@param pre_select_mat_location integer|function location where to find the materials before known the materials (default LOCATION_HAND|LOCATION_MZONE)
function FusionSpell.SummonTargetFilter(c,fusfilter,matfilter,e,tp,pre_select_mat_location,mat_operation_code_map,post_select_mat_location,additional_fcheck,sumtype,sumpos)
local mg=FusionSpell.GetMaterialsGroupForTargetCard(c,tp,e,matfilter,pre_select_mat_location,mat_operation_code_map,post_select_mat_location)
Debug.Message(string.format("%d materials for %d",#mg,c:GetCode()))
if additional_fcheck~=nil then
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunction(additional_fcheck,tp,c)
end
local res=c:IsType(TYPE_FUSION) and (not fusfilter or fusfilter(c,tp)) and c:IsCanBeSpecialSummoned(e,sumtype,tp,false,false,sumpos) and c:CheckFusionMaterial(mg,nil,tp)
aux.FCheckAdditional=nil
return res
end
---@return {[Effect]:Group} effect_targets_map Return a map of different chain material to potiential fusion targets
function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,additional_fcheck,sumtype,sumpos)
local chain_material_effects={Duel.GetPlayerEffect(tp,EFFECT_CHAIN_MATERIAL)}
---@type {[Effect]:Group}
local chain_material_targets={}
for _,ce in ipairs(chain_material_effects) do
---@type function
local chain_material_filter=ce:GetTarget()
local chain_mg=chain_material_filter(ce,e,tp)
if #chain_mg>0 then
local ce_fusfilter=ce:GetValue()
local ce_sg=Duel.GetMatchingGroup(FusionSpell.ChainMaterialSummonTargetFilter,tp,fuslocation,0,nil,aux.AND(ce_fusfilter,fusfilter or aux.TRUE),e,tp,chain_mg,additional_fcheck,sumtype,sumpos)
if #ce_sg>0 then
chain_material_targets[ce]=ce_sg
end
end
end
return chain_material_targets
end
function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additional_fcheck,sumtype,sumpos)
if additional_fcheck~=nil then
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck)
end
local res=c:IsType(TYPE_FUSION) and (not fusfilter or fusfilter(c,tp)) and c:IsCanBeSpecialSummoned(e,sumtype,tp,false,false,sumpos) and c:CheckFusionMaterial(mg,nil,tp)
aux.FCheckAdditional=nil
return res
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)
-- different stage for call back
---@alias FUSION_SPELL_CALLBACK_STAGE integer
FusionSpell.STAGE_BEFORE_SUMMON_COMPLETE=1
FusionSpell.STAGE_BEFORE_PROCEDURE_COMPLETE=2
FusionSpell.STAGE_AT_SUMMON_OPERATION_FINISH=3
FusionSpell.STAGE_AT_ALL_OPERATION_FINISH=4
-- operation that would be applied on the material
---@alias FUSION_OPERATION_CODE integer
FusionSpell.FUSION_OPERATION_INHERIT=0x10000 -- used only on EFFECT_EXTRA_FUSION_MATERIAL effects, inherits the operation of fusion spell
FusionSpell.FUSION_OPERATION_GRAVE=0x1
FusionSpell.FUSION_OPERATION_BANISH=0x2
FusionSpell.FUSION_OPERATION_BANISH_FACEDOWN=0x3
FusionSpell.FUSION_OPERATION_SHUFFLE=0x4
FusionSpell.FUSION_OPERATION_DECK_BOTTOM=0x5
FusionSpell.FUSION_OPERATION_DESTROY=0x6
---@return FUSION_OPERATION_FUNCTION
function FusionSpell.GetFusionOperationByCode(code,matlocation,fusion_spell_operation_code_map)
if code==FusionSpell.FUSION_OPERATION_GRAVE then
return FusionSpell.GraveMaterial
elseif code==FusionSpell.FUSION_OPERATION_BANISH then
return FusionSpell.BanishMaterial
elseif code==FusionSpell.FUSION_OPERATION_BANISH_FACEDOWN then
return FusionSpell.BanishMaterialFaceDown
elseif code==FusionSpell.FUSION_OPERATION_SHUFFLE then
return FusionSpell.ShuffleMaterial
elseif code==FusionSpell.FUSION_OPERATION_DECK_BOTTOM then
return FusionSpell.SendDeckBottomMaterial
elseif code==FusionSpell.FUSION_OPERATION_DESTROY then
return FusionSpell.DestroyMaterial
elseif code==FusionSpell.FUSION_OPERATION_INHERIT then
if matlocation==nil or fusion_spell_operation_code_map==nil then
-- we are in trouble
assert(false, "we have an material that inhreits, but operation can be inhreited")
return FusionSpell.GraveMaterial
end
return FusionSpell.GetFusionOperationByCode(fusion_spell_operation_code_map[matlocation])
end
end
---@return FUSION_FILTER_FUNCTION
function FusionSpell.GetFusionFilterByCode(code,matlocation,fusion_spell_operation_code_map)
if code==FusionSpell.FUSION_OPERATION_GRAVE then
return FusionSpell.GraveMaterialFilter
elseif code==FusionSpell.FUSION_OPERATION_BANISH then
return FusionSpell.BanishMaterialFilter
elseif code==FusionSpell.FUSION_OPERATION_BANISH_FACEDOWN then
return FusionSpell.BanishMaterialFaceDownFilter
elseif code==FusionSpell.FUSION_OPERATION_SHUFFLE then
return FusionSpell.ShuffleMaterialFilter
elseif code==FusionSpell.FUSION_OPERATION_DECK_BOTTOM then
return FusionSpell.SendDeckBottomMaterialFilter
elseif code==FusionSpell.FUSION_OPERATION_DESTROY then
return FusionSpell.DestroyMaterialFilter
elseif code==FusionSpell.FUSION_OPERATION_INHERIT then
if matlocation==nil or fusion_spell_operation_code_map==nil then
-- we are in trouble
return nil
end
return FusionSpell.GetFusionFilterByCode(fusion_spell_operation_code_map[matlocation])
end
end
---@alias FUSION_OPERATION_FUNCTION fun(sg:Card|Group,tp:integer):integer
---@alias FUSION_FILTER_FUNCTION fun(c:Card,tp:integer?,e:Effect?):boolean
---@type FUSION_OPERATION_FUNCTION
function FusionSpell.DestroyMaterial(sg,tp)
return Duel.Destroy(sg,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION,nil,tp)
end
---@type FUSION_FILTER_FUNCTION
function FusionSpell.DestroyMaterialFilter(c,tp,e)
return c:IsDestructable(e)
end
---@type FUSION_OPERATION_FUNCTION
function FusionSpell.GraveMaterial(sg,tp)
return Duel.SendtoGrave(sg,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION,tp)
end
---@type FUSION_FILTER_FUNCTION
function FusionSpell.GraveMaterialFilter(c)
return c:IsAbleToGrave()
end
---@type FUSION_OPERATION_FUNCTION
function FusionSpell.BanishMaterial(sg,tp)
return Duel.Remove(sg,POS_FACEUP,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION,tp)
end
---@type FUSION_FILTER_FUNCTION
function FusionSpell.BanishMaterialFilter(c,tp)
return c:IsAbleToRemove(tp,POS_FACEUP,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION)
end
---@type FUSION_OPERATION_FUNCTION
function FusionSpell.BanishMaterialFaceDown(sg,tp)
return Duel.Remove(sg,POS_FACEDOWN,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION,tp)
end
---@type FUSION_FILTER_FUNCTION
function FusionSpell.BanishMaterialFaceDownFilter(c,tp)
return c:IsAbleToRemove(tp,POS_FACEDOWN,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION)
end
---@type FUSION_OPERATION_FUNCTION
function FusionSpell.ShuffleMaterial(sg,tp)
return Duel.SendtoDeck(sg,nil,SEQ_DECKSHUFFLE,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION,tp)
end
---@type FUSION_FILTER_FUNCTION
function FusionSpell.ShuffleMaterialFilter(c)
return c:IsAbleToDeck()
end
---@type FUSION_OPERATION_FUNCTION
function FusionSpell.SendDeckBottomMaterial(sg,tp)
-- prompt user to select order
return Duel.SendtoDeck(sg,nil,SEQ_DECKBOTTOM,REASON_EFFECT+REASON_MATERIAL+REASON_FUSION,tp)
end
---@type FUSION_FILTER_FUNCTION
function FusionSpell.SendDeckBottomMaterialFilter(c)
return c:IsAbleToDeck()
end
--Returns a list of effect, if element is the EFFECT_EXTRA_FUSION_MATERIAL, stands for it can be included by that extra material effect.
--if element is true, stands for it can be included by the fusion effect itself.
---@return (true|Effect)[]
function FusionSpell.GetMaterialEffects(c,summon_card,matlocation,materials)
local res={}
if c:IsLocation(matlocation) then
table.insert(res,true)
end
local extra_effs={c:IsHasEffect(EFFECT_EXTRA_FUSION_MATERIAL)}
for _,eff in ipairs(extra_effs) do
if not summon_card then
table.insert(res,eff)
end
local val=eff:GetValue()
if (type(val)=="function" and val(eff,summon_card)) or val==1 then
table.insert(res,eff)
end
end
return res
end
--Returns the 1st EFFECT_EXTRA_FUSION_MATERIAL is applied on Card c.
--If summon_card is provided, it will filter on whether the effect's value function applies to that card.
---@param c Card the material card card
---@param tp integer the player
---@param summon_card Card the target card
function FusionSpell.GetExtraMaterialEffect(c,tp,summon_card)
local effs={c:IsHasEffect(EFFECT_EXTRA_FUSION_MATERIAL)}
for _,eff in ipairs(effs) do
if eff:CheckCountLimit(tp)==true then
if summon_card==nil then
return eff
end
local val=eff:GetValue()
if (type(val)=="function" and val(eff,summon_card)) or val==1 then
return eff
end
end
end
end
-- when a target card can be summoned by multiple effect, ask for which to apply.
---@return true|Effect
function FusionSpell.MultiFusionEffectPrompt(effects,tp)
local ops={}
for i,eff in ipairs(effects) do
table.insert(ops,eff:GetDescription())
end
local op=Duel.SelectOption(tp,table.unpack(ops))
return effects[op+1]
end
-- when a material has multiple effect make it could be material, ask for which to apply.
---@return true|Effect
function FusionSpell.MultiMaterialEffectPrompt(effects,tp,e)
local ops= {}
for i,eff in ipairs(effects) do
if eff==true then
-- this can be used as default material
table.insert(ops,e:GetDescription())
else
table.insert(ops,eff:GetDescription())
end
end
local op=Duel.SelectOption(tp,table.unpack(ops))
return effects[op+1]
end
--- filter out materials that does not necessary come from fusion spell and pass to the gcheck of fusion spell
--- @param fusion_spell_additional_fcheck_function FUSION_FCHECK_FUNCTION
function FusionSpell.GetFusionSpellFCheckAdditionalFunction(fusion_spell_additional_fcheck_function,tp,tc)
return (function(f_tp,mg,fc)
local extra_mg=mg:Filter(FusionSpell.GetExtraMaterialEffect,nil,tp,tc)
return fusion_spell_additional_fcheck_function(f_tp,mg-extra_mg,fc,sg)
end)
end
--- all material must come from chain material, only pass all and pass to the gcheck of fusion spell
--- @param fusion_spell_additional_fcheck_function FUSION_FCHECK_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,sg)
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