Commit 6384ba05 authored by 未闻皂名's avatar 未闻皂名

2024/12/23 融合术逻辑修改

parent d1de102a
Pipeline #32020 passed with stages
in 9 minutes and 3 seconds
......@@ -2,62 +2,76 @@
RushDuel = RushDuel or {}
-- 当前的融合效果
RushDuel.CurrentFusionEffect = nil
-- 额外的融合检测
RushDuel.FusionExtraChecker = nil
-- 内部方法: 生成融合素材的函数
function RushDuel._private_make_fusion_material(card, sub, insf, mat, codes, ...)
local fun = {}
-- 生成融合素材
function RushDuel.MakeFusionMaterial(card, ...)
local codes = {}
local funcs = {}
local unspecified = false
for _, val in ipairs {...} do
local val_type = type(val)
if val_type == "number" then
table.insert(fun, RushDuel._private_make_fusion_material_code(val))
if not mat[val] then
mat[val] = true
table.insert(codes, val)
end
RushDuel.AddCodeFusionMaterial(codes, funcs, val)
elseif val_type == "function" then
table.insert(fun, RushDuel._private_make_fusion_material_func(val))
unspecified = true
RushDuel.AddFuncFusionMaterial(codes, funcs, val)
elseif val_type == "table" then
local funs = RushDuel._private_make_fusion_material(card, sub, insf, mat, codes, table.unpack(val))
table.insert(fun, RushDuel._private_make_fusion_material_mix(funs))
local res = RushDuel.AddMixFusionMaterial(codes, funcs, val)
unspecified = unspecified or res
end
end
return fun, unspecified
return codes, funcs, unspecified
end
-- 内部方法: 融合素材 - 卡名
function RushDuel._private_make_fusion_material_code(code)
return function(c, fc, sub, mg, sg)
-- 融合素材 - 卡名
function RushDuel.AddCodeFusionMaterial(codes, funcs, code)
table.insert(codes, code)
table.insert(funcs, function(c, fc, sub, mg, sg)
return c:IsFusionCode(code) or (sub and c:CheckFusionSubstitute(fc))
end
end)
end
-- 内部方法: 融合素材 - 条件
function RushDuel._private_make_fusion_material_func(func)
return function(c, fc, sub, mg, sg)
-- 融合素材 - 条件
function RushDuel.AddFuncFusionMaterial(codes, funcs, func)
table.insert(funcs, function(c, fc, sub, mg, sg)
return func(c, fc, sub, mg, sg) and not c:IsHasEffect(6205579)
end
end)
end
-- 内部方法: 融合素材 - 混合
function RushDuel._private_make_fusion_material_mix(funs)
return function(c, fc, sub, mg, sg)
for _, fun in ipairs(funs) do
if fun(c, fc, sub, mg, sg) then
-- 融合素材 - 混合
function RushDuel.AddMixFusionMaterial(codes, funcs, list)
local mixs = {}
local unspecified = true
for _, val in ipairs(list) do
local val_type = type(val)
if val_type == "number" then
RushDuel.AddCodeFusionMaterial(codes, mixs, val)
unspecified = false
elseif val_type == "function" then
RushDuel.AddFuncFusionMaterial(codes, mixs, val)
end
end
table.insert(funcs, function(c, fc, sub, mg, sg)
for _, func in ipairs(mixs) do
if func(c, fc, sub, mg, sg) then
return true
end
end
return false
end
end)
return unspecified
end
-- 内部方法: 添加融合素材数据
function RushDuel._private_set_fusion_material_data(card, mat, min, max, unspecified, codes)
-- 设置融合素材数据
function RushDuel.SetFusionMaterialData(card, codes, min, max, unspecified)
local mt = getmetatable(card)
-- 卡名记述的素材
if mt.material == nil then
if codes ~= nil then
local mat = {}
for _, code in ipairs(codes) do
mat[code] = true
end
mt.material = mat
mt.material_codes = codes
end
-- 素材的数量
if mt.material_count == nil then
......@@ -67,23 +81,112 @@ function RushDuel._private_set_fusion_material_data(card, mat, min, max, unspeci
if unspecified ~= nil then
mt.unspecified_funsion = unspecified
end
-- 素材的卡名
if codes ~= nil then
mt.material_codes = codes
end
end
-- 内部方法: 创建融合效果
function RushDuel._private_create_fusion_effect(card, insf, sub, checker, min, max, ...)
-- 创建融合手续
function RushDuel.CreateFusionProcedure(card, insf, sub, mats, extra, max, checker)
local e = Effect.CreateEffect(card)
e:SetType(EFFECT_TYPE_SINGLE)
e:SetCode(EFFECT_FUSION_MATERIAL)
e:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
e:SetCondition(RushDuel.FusionProcedureCondition(insf, sub, checker, min, max, ...))
e:SetOperation(RushDuel.FusionProcedureOperation(insf, sub, checker, min, max, ...))
e:SetCondition(RushDuel.FusionProcedureCondition(insf, sub, mats, extra, max, checker))
e:SetOperation(RushDuel.FusionProcedureOperation(insf, sub, mats, extra, max, checker))
card:RegisterEffect(e)
return e
end
-- 融合手续 - 条件
function RushDuel.FusionProcedureCondition(insf, sub, mats, extra, max, checker)
return function(e, g, gc, chkfnf)
local c = e:GetHandler()
local tp = c:GetControler()
if g == nil then
return insf and Auxiliary.MustMaterialCheck(nil, tp, EFFECT_MUST_BE_FMATERIAL)
end
local mg = g:Filter(RushDuel.FusionProcedureMaterialFilter, c, c, sub, mats)
if gc then
if not mg:IsContains(gc) then
return false
end
Duel.SetSelectedCard(gc)
end
local minc, maxc = #mats, #mats + max
return mg:CheckSubGroup(RushDuel.FusionProcedureMaterialChecker, minc, maxc, tp, c, chkfnf, sub, mats, extra, max, checker)
end
end
-- 融合手续 - 操作
function RushDuel.FusionProcedureOperation(insf, sub, mats, extra, max, checker)
return function(e, tp, eg, ep, ev, re, r, rp, gc, chkfnf)
local c = e:GetHandler()
local tp = c:GetControler()
local mg = eg:Filter(RushDuel.FusionProcedureMaterialFilter, c, c, sub, mats)
if gc then
Duel.SetSelectedCard(gc)
end
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_FMATERIAL)
local minc, maxc = #mats, #mats + max
local sg = mg:SelectSubGroup(tp, RushDuel.FusionProcedureMaterialChecker, true, minc, maxc, tp, c, chkfnf, sub, mats, extra, max, checker)
if sg == nil then
sg = Group.CreateGroup()
end
Duel.SetFusionMaterial(sg)
end
end
-- 融合手续 - 素材过滤
function RushDuel.FusionProcedureMaterialFilter(c, fc, sub, funcs)
if not c:IsCanBeFusionMaterial(fc, SUMMON_TYPE_FUSION) then
return false
end
for _, func in ipairs(funcs) do
if func(c, fc, sub) then
return true
end
end
return false
end
-- 融合手续 - 素材选择
function RushDuel.FusionProcedureMaterialChecker(mg, tp, fc, chkfnf, sub, mats, extra, max, checker)
local chkf = chkfnf & 0xff
if mg:IsExists(Auxiliary.TuneMagicianCheckX, 1, nil, mg, EFFECT_TUNE_MAGICIAN_F) then
return false
elseif not Auxiliary.MustMaterialCheck(mg, tp, EFFECT_MUST_BE_FMATERIAL) then
return false
elseif checker and not checker(mg, tp, fc, chkf) then
return false
elseif RushDuel.FusionExtraChecker and not RushDuel.FusionExtraChecker(mg, tp, fc, chkf) then
return false
elseif Auxiliary.FCheckAdditional and not Auxiliary.FCheckAdditional(mg, tp, fc, chkf) then
return false
elseif Auxiliary.FGoalCheckAdditional and not Auxiliary.FGoalCheckAdditional(mg, tp, fc, chkf) then
return false
else
local sg = Group.CreateGroup()
return mg:IsExists(RushDuel.FusionProcedureCheckStep, 1, nil, mg, sg, fc, sub, extra, max, table.unpack(mats))
end
end
-- 融合手续 - 素材组合
function RushDuel.FusionProcedureCheckStep(c, mg, sg, fc, sub, extra, max, fun1, fun2, ...)
local res = false
if fun2 then
sg:AddCard(c)
if fun1(c, fc, false, mg, sg) then
res = mg:IsExists(RushDuel.FusionProcedureCheckStep, 1, sg, mg, sg, fc, sub, extra, max, fun2, ...)
elseif sub and fun1(c, fc, true, mg, sg) then
res = mg:IsExists(RushDuel.FusionProcedureCheckStep, 1, sg, mg, sg, fc, false, extra, max, fun2, ...)
end
sg:RemoveCard(c)
elseif fun1(c, fc, sub, mg, sg) then
if max == 0 then
return true
end
-- 额外的素材选择
local eg = Group.CreateGroup()
eg:Merge(mg)
eg:Sub(sg)
eg:RemoveCard(c)
return eg:FilterCount(extra, nil, fc, false, mg, sg) == #eg
end
return res
end
-- 添加融合手续: 指定卡名/条件, 固定数量
function RushDuel.AddFusionProcedure(card, sub, insf, ...)
......@@ -101,33 +204,10 @@ function RushDuel.AddFusionProcedure(card, sub, insf, ...)
table.insert(vals, 1, sub)
sub = true
end
-- 有卡名记述的融合素材
local mat = {}
local codes = {}
local funs, unspecified = RushDuel._private_make_fusion_material(card, sub, insf, mat, codes, table.unpack(vals))
RushDuel._private_set_fusion_material_data(card, mat, #funs, #funs, unspecified, codes)
local checker = RushDuel.FusionProcedureChecker(RushDuel.FusionProcedureCheckStart, nil)
return RushDuel._private_create_fusion_effect(card, insf, sub, checker, #funs, #funs, table.unpack(funs))
end
-- 融合手续 - 检测: 指定卡名/条件, 固定数量
function RushDuel.FusionProcedureCheckStart(mg, fc, sub, ...)
local sg = Group.CreateGroup()
return mg:IsExists(RushDuel.FusionProcedureCheckStep, 1, nil, mg, sg, fc, sub, ...)
end
function RushDuel.FusionProcedureCheckStep(c, mg, sg, fc, sub, fun1, fun2, ...)
if fun2 then
sg:AddCard(c)
local res = false
if fun1(c, fc, false, mg, sg) then
res = mg:IsExists(RushDuel.FusionProcedureCheckStep, 1, sg, mg, sg, fc, sub, fun2, ...)
elseif sub and fun1(c, fc, true, mg, sg) then
res = mg:IsExists(RushDuel.FusionProcedureCheckStep, 1, sg, mg, sg, fc, false, fun2, ...)
end
sg:RemoveCard(c)
return res
else
return fun1(c, fc, sub, mg, sg)
end
-- 融合素材
local codes, funcs, unspecified = RushDuel.MakeFusionMaterial(card, table.unpack(vals))
RushDuel.SetFusionMaterialData(card, codes, #funcs, #funcs, unspecified)
return RushDuel.CreateFusionProcedure(card, insf, sub, funcs, nil, 0, nil)
end
-- 添加融合手续: 指定条件, 不固定数量
......@@ -137,17 +217,11 @@ function RushDuel.AddFusionProcedureSP(card, matfilter, matcheck, min, max, sub,
end
local insf = (insf ~= false)
local sub = (sub ~= false)
local checker = RushDuel.FusionProcedureChecker(RushDuel.FusionProcedureCheckSP, matcheck)
return RushDuel._private_create_fusion_effect(card, insf, sub, checker, min, max, matfilter)
end
-- 融合手续 - 检测: 指定条件, 不固定数量
function RushDuel.FusionProcedureCheckSP(mg, fc, sub, matfilter)
local ct = mg:FilterCount(matfilter, nil, fc, false)
if not sub then
return ct == mg:GetCount()
else
return ct >= mg:GetCount() - 1
local funcs = {}
for i = 1, min do
table.insert(funcs, matfilter)
end
return RushDuel.CreateFusionProcedure(card, insf, sub, funcs, matfilter, max - #funcs, matcheck)
end
-- 手动添加融合素材列表
......@@ -155,11 +229,7 @@ function RushDuel.SetFusionMaterial(card, codes, min, max)
if card:IsStatus(STATUS_COPYING_EFFECT) then
return
end
local mat = {}
for _, code in ipairs(codes) do
mat[code] = true
end
RushDuel._private_set_fusion_material_data(card, mat, min, max)
RushDuel.SetFusionMaterialData(card, codes, min, max)
end
-- 手动添加传说卡融合素材列表
......@@ -182,65 +252,6 @@ function RushDuel.GetFusionMaterialCodes(card)
return card.material_codes or {}
end
-- 融合手续 - 检测
function RushDuel.FusionProcedureChecker(condition, checker)
return function(sg, tp, fc, sub, chkfnf, ...)
local chkf = chkfnf & 0xff
local concat_fusion = chkfnf & 0x200 > 0
if not concat_fusion and sg:IsExists(Auxiliary.TuneMagicianCheckX, 1, nil, sg, EFFECT_TUNE_MAGICIAN_F) then
return false
end
if not Auxiliary.MustMaterialCheck(sg, tp, EFFECT_MUST_BE_FMATERIAL) then
return false
end
return condition(sg, fc, sub, ...) and (not checker or checker(sg, tp, fc, chkf)) and (not Auxiliary.FCheckAdditional or Auxiliary.FCheckAdditional(tp, sg, fc, chkf)) and
(not Auxiliary.FGoalCheckAdditional or Auxiliary.FGoalCheckAdditional(tp, sg, fc))
end
end
-- 融合手续 - 条件
function RushDuel.FusionProcedureCondition(insf, sub, checker, min, max, ...)
local funs = {...}
return function(e, g, gc, chkfnf)
if g == nil then
return insf and Auxiliary.MustMaterialCheck(nil, e:GetHandlerPlayer(), EFFECT_MUST_BE_FMATERIAL)
end
local c = e:GetHandler()
local tp = c:GetControler()
local notfusion = chkfnf & 0x100 > 0
local concat_fusion = chkfnf & 0x200 > 0
local sub = (sub or notfusion) and not concat_fusion
local mg = g:Filter(Auxiliary.FConditionFilterMix, c, c, sub, concat_fusion, table.unpack(funs))
if gc then
if not mg:IsContains(gc) then
return false
end
Duel.SetSelectedCard(gc)
end
return mg:CheckSubGroup(checker, min, max, tp, c, sub, chkfnf, table.unpack(funs))
end
end
-- 融合手续 - 操作
function RushDuel.FusionProcedureOperation(insf, sub, checker, min, max, ...)
local funs = {...}
return function(e, tp, eg, ep, ev, re, r, rp, gc, chkfnf)
local c = e:GetHandler()
local tp = c:GetControler()
local notfusion = chkfnf & 0x100 > 0
local concat_fusion = chkfnf & 0x200 > 0
local sub = (sub or notfusion) and not concat_fusion
local mg = eg:Filter(Auxiliary.FConditionFilterMix, c, c, sub, concat_fusion, table.unpack(funs))
if gc then
Duel.SetSelectedCard(gc)
end
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_FMATERIAL)
local sg = mg:SelectSubGroup(tp, checker, true, min, max, tp, c, sub, chkfnf, table.unpack(funs))
if sg == nil then
sg = Group.CreateGroup()
end
Duel.SetFusionMaterial(sg)
end
end
-- 创建效果: 融合术/结合 召唤
function RushDuel.CreateFusionEffect(card, matfilter, spfilter, exfilter, s_range, o_range, mat_check, mat_move, target_action, operation_action, limit_action, including_self, self_leave)
local self_range = s_range or 0
......@@ -355,12 +366,14 @@ function RushDuel.ExecuteFusionSummon(e, tp, list, chkf, gc, mat_move)
fc:CompleteProcedure()
return fc, mat
end
function RushDuel.FusionCheckAdditional(e, self_leave)
return function(tp, sg, fc, chkf)
if chkf == PLAYER_NONE then
-- 判断条件: 怪兽区域判断
function RushDuel.FusionCheckLocation(e, self_leave, extra)
return function(sg, tp, fc, chkf)
if extra and not extra(tp, sg, fc, chkf) then
return false
elseif chkf == PLAYER_NONE then
return true
end
if self_leave then
elseif self_leave then
local mg = Group.FromCards(e:GetHandler())
mg:Merge(sg)
return Duel.GetLocationCountFromEx(tp, tp, mg, fc) > 0
......@@ -371,11 +384,9 @@ function RushDuel.FusionCheckAdditional(e, self_leave)
end
-- 判断条件: 是否可以进行融合召唤
function RushDuel.IsCanFusionSummon(e, tp, matfilter, spfilter, exfilter, s_range, o_range, mat_check, including_self, self_leave, except)
Auxiliary.FCheckAdditional = RushDuel.FusionCheckAdditional(e, self_leave)
Auxiliary.FGoalCheckAdditional = mat_check
RushDuel.FusionExtraChecker = RushDuel.FusionCheckLocation(e, self_leave, mat_check)
local fusionable = RushDuel.GetFusionSummonData(e, tp, matfilter, spfilter, exfilter, s_range, o_range, including_self, self_leave, except)
Auxiliary.FCheckAdditional = nil
Auxiliary.FGoalCheckAdditional = nil
RushDuel.FusionExtraChecker = nil
return fusionable
end
-- 融合效果 - 目标
......@@ -393,8 +404,7 @@ end
-- 融合效果 - 操作
function RushDuel.FusionOperation(matfilter, spfilter, exfilter, s_range, o_range, mat_check, mat_move, including_self, self_leave, action, limit)
return function(e, tp, eg, ep, ev, re, r, rp)
Auxiliary.FCheckAdditional = RushDuel.FusionCheckAdditional(e, self_leave)
Auxiliary.FGoalCheckAdditional = mat_check
RushDuel.FusionExtraChecker = RushDuel.FusionCheckLocation(e, self_leave, mat_check)
local fusionable, list, chkf, gc = RushDuel.GetFusionSummonData(e, tp, matfilter, spfilter, exfilter, s_range, o_range, including_self, self_leave, nil, e)
if fusionable then
local fc, mat = RushDuel.ExecuteFusionSummon(e, tp, list, chkf, gc, mat_move)
......@@ -402,8 +412,7 @@ function RushDuel.FusionOperation(matfilter, spfilter, exfilter, s_range, o_rang
action(e, tp, eg, ep, ev, re, r, rp, mat, fc)
end
end
Auxiliary.FCheckAdditional = nil
Auxiliary.FGoalCheckAdditional = nil
RushDuel.FusionExtraChecker = nil
if limit ~= nil then
limit(e, tp, eg, ep, ev, re, r, rp)
end
......@@ -414,8 +423,7 @@ end
function RushDuel.FusionSummon(matfilter, spfilter, exfilter, s_range, o_range, mat_check, mat_move, e, tp, break_effect, including_self, self_leave)
local include = including_self or false
local leave = self_leave or false
Auxiliary.FCheckAdditional = RushDuel.FusionCheckAdditional(e, leave)
Auxiliary.FGoalCheckAdditional = mat_check
RushDuel.FusionExtraChecker = RushDuel.FusionCheckLocation(e, self_leave, mat_check)
local fusionable, list, chkf, gc = RushDuel.GetFusionSummonData(e, tp, matfilter, spfilter, exfilter, s_range, o_range, include, leave, nil, e)
local fc = nil
if fusionable then
......@@ -424,8 +432,7 @@ function RushDuel.FusionSummon(matfilter, spfilter, exfilter, s_range, o_range,
end
fc = RushDuel.ExecuteFusionSummon(e, tp, list, chkf, gc, mat_move)
end
Auxiliary.FCheckAdditional = nil
Auxiliary.FGoalCheckAdditional = nil
RushDuel.FusionExtraChecker = nil
return fc
end
......@@ -433,8 +440,7 @@ end
function RushDuel.CanFusionSummon(desc, matfilter, spfilter, exfilter, s_range, o_range, mat_check, mat_move, e, tp, break_effect, including_self, self_leave)
local include = including_self or false
local leave = self_leave or false
Auxiliary.FCheckAdditional = RushDuel.FusionCheckAdditional(e, leave)
Auxiliary.FGoalCheckAdditional = mat_check
RushDuel.FusionExtraChecker = RushDuel.FusionCheckLocation(e, self_leave, mat_check)
local fusionable, list, chkf, gc = RushDuel.GetFusionSummonData(e, tp, matfilter, spfilter, exfilter, s_range, o_range, include, leave, nil, e)
local fc = nil
if fusionable and Duel.SelectYesNo(tp, desc) then
......@@ -443,8 +449,7 @@ function RushDuel.CanFusionSummon(desc, matfilter, spfilter, exfilter, s_range,
end
fc = RushDuel.ExecuteFusionSummon(e, tp, list, chkf, gc, mat_move)
end
Auxiliary.FCheckAdditional = nil
Auxiliary.FGoalCheckAdditional = nil
RushDuel.FusionExtraChecker = nil
return fc
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