Commit 510631bb authored by 未闻皂名's avatar 未闻皂名

2025/10/22 卡片选择整合

parent 6643da66
Pipeline #41196 passed with stages
in 6 minutes and 46 seconds
This diff is collapsed.
......@@ -307,7 +307,7 @@ end
-- 条件: 可以改变攻击对象
function RushDuel.IsCanChangeAttackTarget(card)
local g = card:GetAttackableTarget()
return g:GetCount() > 1
return #g > 1
end
-- 条件: 玩家是否能够使用特定种族进行攻击
......
-- Rush Duel 代价
RushDuel = RushDuel or {}
-- 当前的融合效果
RushDuel.CostCancelable = false
-- 内部方法: 获取选择范围
function RushDuel._private_get_select_range(min, max, ...)
......@@ -20,12 +22,18 @@ function RushDuel._private_cost_select_match(hint, filter, s_range, o_range, min
expect = e:GetHandler()
end
local min, max = RushDuel._private_get_select_range(min, max, e, tp, eg, ep, ev, re, r, rp, chk)
local g = Duel.GetMatchingGroup(filter, tp, s_range, o_range, expect, e, tp, eg, ep, ev, re, r, rp)
if chk == 0 then
return Duel.IsExistingMatchingCard(filter, tp, s_range, o_range, min, expect, e, tp, eg, ep, ev, re, r, rp)
return #g >= min
end
local cancelable = RushDuel.CostCancelable
local sg = RushDuel.Select(hint, tp, g, nil, cancelable, min, max)
if sg and #sg > 0 then
action(sg, e, tp, eg, ep, ev, re, r, rp)
return true
else
return false
end
Duel.Hint(HINT_SELECTMSG, tp, hint)
local g = Duel.SelectMatchingCard(tp, filter, tp, s_range, o_range, min, max, expect, e, tp, eg, ep, ev, re, r, rp)
action(g, e, tp, eg, ep, ev, re, r, rp)
end
end
-- 内部方法: 选择子卡片组, 执行操作
......@@ -40,9 +48,14 @@ function RushDuel._private_cost_select_group(hint, filter, check, s_range, o_ran
if chk == 0 then
return g:CheckSubGroup(check, min, max, e, tp, eg, ep, ev, re, r, rp)
end
Duel.Hint(HINT_SELECTMSG, tp, hint)
local sg = g:SelectSubGroup(tp, check, false, min, max, e, tp, eg, ep, ev, re, r, rp)
action(sg, e, tp, eg, ep, ev, re, r, rp)
local cancelable = RushDuel.CostCancelable
local sg = RushDuel.Select(hint, tp, g, check, cancelable, min, max, e, tp, eg, ep, ev, re, r, rp)
if sg and #sg > 0 then
action(sg, e, tp, eg, ep, ev, re, r, rp)
return true
else
return false
end
end
end
-- 内部方法: 送去墓地动作
......@@ -428,12 +441,19 @@ function RushDuel.CostChoose(hit1, cost1, hit2, cost2)
if chk == 0 then
return s1 or s2
end
RushDuel.CostCancelable = true
::cancel::
local op = aux.SelectFromOptions(tp, {s1, hit1}, {s2, hit2})
if op == 1 then
cost1(e, tp, eg, ep, ev, re, r, rp, 1)
if not cost1(e, tp, eg, ep, ev, re, r, rp, 1) then
goto cancel
end
elseif op == 2 then
cost2(e, tp, eg, ep, ev, re, r, rp, 1)
if not cost2(e, tp, eg, ep, ev, re, r, rp, 1) then
goto cancel
end
end
RushDuel.CostCancelable = false
end
end
-- 代价: 从2个代价中选择1个(同时选)
......
......@@ -28,6 +28,34 @@ function RushDuel.Check(check, ...)
end
end
-- 选择卡片组 (功能整合)
function RushDuel.Select(hint, player, group, check, cancelable, min, max, ...)
Duel.Hint(HINT_SELECTMSG, player, hint)
if check == nil then
if cancelable then
return group:CancelableSelect(player, min, max, nil)
else
return group:Select(player, min, max, nil)
end
else
return group:SelectSubGroup(player, check, cancelable, min, max, ...)
end
end
-- 可以选择卡片组 (功能整合)
function RushDuel.CanSelect(desc, hint, player, group, check, min, max, ...)
::cancel::
if Duel.SelectYesNo(player, desc) then
local sg = RushDuel.Select(hint, player, group, check, true, min, max, ...)
if sg == nil then
goto cancel
else
return sg
end
else
return nil
end
end
-- 对卡片组里的全部卡片作位或运算
function RushDuel.GroupBor(g, func, ...)
local result = 0
......@@ -104,7 +132,7 @@ end
-- 获取卡组底的N张卡
function RushDuel.GetDeckBottomGroup(player, count)
local dg = Duel.GetFieldGroup(player, LOCATION_DECK, 0)
local ct = dg:GetCount()
local ct = #dg
if (count < ct) then
local top = Duel.GetDecktopGroup(player, ct - count)
dg:Sub(top)
......@@ -149,37 +177,6 @@ function RushDuel.GetBaseAttackOnDestroy(c)
return math.max(0, atk)
end
-- 让玩家选择卡片组的 min ~ max 张卡,可以取消
function RushDuel.SelectGroup(player, group, min, max)
-- 单选优化
if min == 1 and max == 1 then
local tc = group:SelectUnselect(nil, player, false, true, 1, 1)
if tc then
return Group.FromCards(tc)
else
return nil
end
end
-- 多选
return group:CancelableSelect(player, min, max, nil)
end
-- 让玩家可以选择卡片组的 min ~ max 张卡
function RushDuel.CanSelectGroup(player, desc, hint, group, min, max)
::cancel::
if Duel.SelectYesNo(player, desc) then
Duel.Hint(HINT_SELECTMSG, player, hint)
local sg = RushDuel.SelectGroup(player, group, min, max)
if sg == nil then
goto cancel
else
return sg
end
else
return nil
end
end
-- 让玩家从多个卡名中宣言一个
function RushDuel.AnnounceCodes(player, codes)
if #codes == 0 then
......
......@@ -186,7 +186,6 @@ function RushDuel.FusionProcedureOperation(sub, insf, funcs, rep, min, max, chec
if gc then
Duel.SetSelectedCard(gc)
end
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_FUSION_MATERIAL)
local minc, maxc = #funcs + min, #funcs + max
if RushDuel.MinFusionMaterialCount ~= nil then
minc = math.max(minc, RushDuel.MinFusionMaterialCount)
......@@ -195,7 +194,7 @@ function RushDuel.FusionProcedureOperation(sub, insf, funcs, rep, min, max, chec
maxc = math.min(maxc, RushDuel.MaxFusionMaterialCount)
end
maxc = math.min(maxc, #mg)
local sg = mg:SelectSubGroup(tp, RushDuel.FusionProcedureMaterialChecker, true, minc, maxc, tp, c, chkfnf, sub, funcs, rep, checker)
local sg = RushDuel.Select(HINTMSG_FUSION_MATERIAL, tp, mg, RushDuel.FusionProcedureMaterialChecker, true, minc, maxc, tp, c, chkfnf, sub, funcs, rep, checker)
if sg == nil then
sg = Group.CreateGroup()
end
......@@ -561,7 +560,7 @@ end
-- 素材去向: 卡组
function RushDuel.FusionToDeck(tp, mat)
local g = mat:Filter(Card.IsFacedown, nil)
if g:GetCount() > 0 then
if #g > 0 then
Duel.ConfirmCards(1 - tp, g)
end
Duel.SendtoDeck(mat, nil, SEQ_DECKSHUFFLE, REASON_EFFECT + REASON_MATERIAL + REASON_FUSION)
......@@ -569,7 +568,7 @@ end
-- 素材去向: 卡组下面
function RushDuel.FusionToDeckBottom(tp, mat)
local g = mat:Filter(Card.IsFacedown, nil)
if g:GetCount() > 0 then
if #g > 0 then
Duel.ConfirmCards(1 - tp, g)
end
Auxiliary.PlaceCardsOnDeckBottom(tp, mat, REASON_EFFECT + REASON_MATERIAL + REASON_FUSION)
......
......@@ -70,7 +70,7 @@ function RushDuel.MaximumSummonFilter(c, e, tp, left_code, right_code)
return c:IsCode(left_code, right_code) and c:IsCanBeSpecialSummoned(e, 0, tp, false, false, POS_FACEUP)
end
function RushDuel.MaximumSummonCheck(g)
return g:GetClassCount(Card.GetCode) == g:GetCount()
return g:GetClassCount(Card.GetCode) == #g
end
function RushDuel.MaximumSummonCondition(left_code, right_code)
return function(e, c, og, min, max)
......@@ -86,12 +86,11 @@ end
function RushDuel.MaximumSummonTarget(left_code, right_code)
return function(e, tp, eg, ep, ev, re, r, rp, chk, c, og, min, max)
local mg = Duel.GetMatchingGroup(RushDuel.MaximumSummonFilter, tp, LOCATION_HAND, 0, nil, e, tp, left_code, right_code)
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_MAXMATERIAL)
local cancel = Duel.GetCurrentChain() == 0
local g = mg:SelectSubGroup(tp, RushDuel.MaximumSummonCheck, cancel, 2, 2)
if g then
g:KeepAlive()
e:SetLabelObject(g)
local cancelable = Duel.GetCurrentChain() == 0
local sg = RushDuel.Select(HINTMSG_MAXMATERIAL, tp, mg, RushDuel.MaximumSummonCheck, cancelable, 2, 2)
if sg then
sg:KeepAlive()
e:SetLabelObject(sg)
return true
else
return false
......
......@@ -136,9 +136,8 @@ end
-- 仪式召唤 - 选择仪式素材
function RushDuel.SelectRitualMaterial(tp, rc, type, mat, gc)
local mg, max = RushDuel.GetRitualMaterial(tp, rc, type, mat)
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_RITUAL_MATERIAL)
Auxiliary.GCheckAdditional = RushDuel.RitualCheckAdditional(rc, type)
local sg = mg:SelectSubGroup(tp, RushDuel.RitualChecker, true, 1, max, rc, tp, type, gc)
local sg = RushDuel.Select(HINTMSG_RITUAL_MATERIAL, tp, mg, RushDuel.RitualChecker, true, 1, max, rc, tp, type, gc)
Auxiliary.GCheckAdditional = nil
return sg
end
......@@ -380,7 +379,7 @@ end
-- 素材去向: 卡组
function RushDuel.RitualToDeck(tp, mat)
local g = mat:Filter(Card.IsFacedown, nil)
if g:GetCount() > 0 then
if #g > 0 then
Duel.ConfirmCards(1 - tp, g)
end
Duel.SendtoDeck(mat, nil, SEQ_DECKSHUFFLE, REASON_EFFECT + REASON_MATERIAL + REASON_RITUAL)
......@@ -388,7 +387,7 @@ end
-- 素材去向: 卡组下面
function RushDuel.RitualToDeckBottom(tp, mat)
local g = mat:Filter(Card.IsFacedown, nil)
if g:GetCount() > 0 then
if #g > 0 then
Duel.ConfirmCards(1 - tp, g)
end
Auxiliary.PlaceCardsOnDeckBottom(tp, mat, REASON_EFFECT + REASON_MATERIAL + REASON_RITUAL)
......
......@@ -173,7 +173,7 @@ function RushDuel.CreateAdvanceCheck(card, filter, count, flag)
e1:SetCode(EFFECT_MATERIAL_CHECK)
e1:SetValue(function(e, c)
local mg = c:GetMaterial()
local ct = math.min(count, mg:GetCount())
local ct = math.min(count, #mg)
local label = 0
if c:IsLevelBelow(6) and count == 2 then
-- 当前等级小于解放要求
......@@ -247,7 +247,7 @@ function RushDuel.AdvanceMaterialCheckValue(getter)
return function(e, c)
local g = c:GetMaterial()
local mat = RushDuel.GetTributeCount(c)
local count = g:GetCount()
local count = #g
local value1, value2 = 0, 0
if count == 1 then
value1 = getter(g:GetFirst(), count, mat) * mat
......@@ -259,7 +259,7 @@ function RushDuel.AdvanceMaterialCheckValue(getter)
value2 = value1
elseif mat == 3 then
local ng, dg = RushDuel.SplitTribute(c)
if dg:GetCount() == 1 then
if #dg == 1 then
value1 = getter(ng:GetFirst(), count, mat) + getter(dg:GetFirst(), count, mat) * 2
value2 = value1
else
......@@ -419,7 +419,7 @@ function RushDuel.HandConfirmSpecialSummonTarget(filter)
return function(e, tp, eg, ep, ev, re, r, rp, chk, c)
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_CONFIRM)
local g = Duel.SelectMatchingCard(tp, filter, tp, LOCATION_HAND, 0, 0, 1, nil, e, tp, c)
if g:GetCount() > 0 then
if #g > 0 then
g:KeepAlive()
e:SetLabelObject(g)
return true
......
......@@ -35,8 +35,7 @@ function cm.activate(e,tp,eg,ep,ev,re,r,rp)
local ft=Duel.GetLocationCount(1-tp,LOCATION_SZONE)
local og=g:Filter(cm.setfilter,nil)
if ft>0 and og:GetCount()>0 and Duel.SelectYesNo(tp,aux.Stringid(m,1)) then
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_SET)
local sg=og:SelectSubGroup(tp,cm.setcheck,false,1,3,ft)
local sg=RD.Select(HINTMSG_SET,tp,og,cm.setcheck,false,1,3,ft)
local dam=Duel.SSet(1-tp,sg)
Duel.Damage(1-tp,dam*300,REASON_EFFECT)
end
......
......@@ -30,7 +30,7 @@ function cm.condition(e,tp,eg,ep,ev,re,r,rp)
end
function cm.activate(e,tp,eg,ep,ev,re,r,rp)
local g=Duel.GetMatchingGroup(Card.IsFaceup,tp,LOCATION_MZONE,0,nil)
if #g>0 then
if g:GetCount()>0 then
g:ForEach(function(tc)
RD.AttachAtkDef(e,tc,200,0,RESET_EVENT+RESETS_STANDARD+RESET_PHASE+PHASE_END)
end)
......
......@@ -16,26 +16,26 @@ end
function cm.confilter(c)
return c:IsFaceup() and c:IsAttribute(ATTRIBUTE_LIGHT) and c:IsRace(RACE_SPELLCASTER)
end
function cm.costfilter1(c)
return c:IsFaceup() and c:IsType(TYPE_EQUIP) and c:IsAbleToDeckOrExtraAsCost()
end
function cm.costfilter2(c)
return c:IsAttribute(ATTRIBUTE_LIGHT) and c:IsRace(RACE_SPELLCASTER) and c:IsAbleToDeckOrExtraAsCost()
function cm.costfilter(c)
if c:IsOnField() then
return c:IsFaceup() and c:IsType(TYPE_EQUIP) and c:IsAbleToDeckOrExtraAsCost()
else
return c:IsAttribute(ATTRIBUTE_LIGHT) and c:IsRace(RACE_SPELLCASTER) and c:IsAbleToDeckOrExtraAsCost()
end
end
function cm.filter(c)
return c:IsAttackPos() and c:IsAbleToHand()
end
function cm.costcheck(g)
if g:GetClassCount(Card.GetLocation)~=1 then return false end
if g:IsExists(Card.IsOnField,1,nil) then return g:GetCount()==1 end
return g:GetCount()==4
end
function cm.condition(e,tp,eg,ep,ev,re,r,rp)
return Duel.GetAttacker():IsControler(1-tp)
and Duel.IsExistingMatchingCard(cm.confilter,tp,LOCATION_MZONE,0,1,nil)
end
cm.cost=RD.CostChooseAction(HINTMSG_TODECK,HINTMSG_TODECK,HINTMSG_TODECK,
cm.costfilter1,nil,LOCATION_ONFIELD,1,function(g)
Duel.SendtoDeck(g,nil,SEQ_DECKSHUFFLE,REASON_COST)
end,
cm.costfilter2,nil,LOCATION_GRAVE,4,function(g)
Duel.SendtoDeck(g,nil,SEQ_DECKSHUFFLE,REASON_COST)
end)
cm.cost=CostSendGroupToDeckSort(cm.costfilter,cm.costcheck,LOCATION_ONFIELD+LOCATION_GRAVE,1,4,false,SEQ_DECKSHUFFLE,false,true)
function cm.target(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsExistingMatchingCard(cm.filter,tp,0,LOCATION_MZONE,1,nil) end
local g=Duel.GetMatchingGroup(cm.filter,tp,0,LOCATION_MZONE,nil)
......
......@@ -22,13 +22,9 @@ function cm.filter(c,e,tp)
return c:IsPosition(POS_FACEUP_ATTACK) and c:IsAttribute(ATTRIBUTE_LIGHT) and c:IsRace(RACE_FIEND)
and RD.IsCanChangePosition(c,e,tp,REASON_EFFECT)
end
cm.cost=RD.CostChooseAction(HINTMSG_TOGRAVE,HINTMSG_TODECK,aux.Stringid(m,1),
cm.costfilter1,nil,LOCATION_HAND,1,function(g)
Duel.SendtoGrave(g,REASON_COST)
end,
cm.costfilter2,nil,LOCATION_GRAVE,3,function(g)
Duel.SendtoDeck(g,nil,SEQ_DECKSHUFFLE,REASON_COST)
end)
cm.cost=RushDuel.CostChoose(HINTMSG_TOGRAVE,cm.cost1,HINTMSG_TODECK,cm.cost2)
cm.cost1=RD.CostSendHandToGrave(cm.costfilter1,1,1)
cm.cost2=RD.CostSendGraveToDeck(cm.costfilter2,3,3)
function cm.target(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsExistingMatchingCard(cm.filter,tp,LOCATION_MZONE,0,1,nil,e,tp) end
local g=Duel.GetMatchingGroup(cm.filter,tp,LOCATION_MZONE,0,nil,e,tp)
......
local cm,m=GetID()
cm.name="魔人扫描器"
cm.name="机器检查员"
function cm.initial_effect(c)
--Activate
local e1=Effect.CreateEffect(c)
......@@ -33,7 +33,7 @@ function cm.activate(e,tp,eg,ep,ev,re,r,rp)
local mg=g3:Filter(cm.filter,nil)
local draw=false
if mg:GetCount()>0 then
local sg=RD.CanSelectGroup(tp,aux.Stringid(m,1),HINTMSG_TOGRAVE,mg,1,2)
local sg=RD.CanSelect(aux.Stringid(m,1),HINTMSG_TOGRAVE,tp,mg,nil,1,2)
if sg then
Duel.DisableShuffleCheck()
if Duel.SendtoGrave(sg,REASON_EFFECT)~=0 then
......
......@@ -21,13 +21,9 @@ end
function cm.costcheck2(g)
return g:GetClassCount(Card.GetLevel)==g:GetCount()
end
cm.cost=RD.CostChooseAction(HINTMSG_TOGRAVE,HINTMSG_TODECK,aux.Stringid(m,1),
cm.costfilter1,nil,LOCATION_HAND,1,function(g)
Duel.SendtoGrave(g,REASON_COST)
end,
cm.costfilter2,cm.costcheck2,LOCATION_GRAVE,5,function(g)
Duel.SendtoDeck(g,nil,SEQ_DECKSHUFFLE,REASON_COST)
end)
cm.cost=RushDuel.CostChoose(HINTMSG_TOGRAVE,cm.cost1,HINTMSG_TODECK,cm.cost2)
cm.cost1=RD.CostSendHandToGrave(cm.costfilter1,1,1)
cm.cost2=RD.CostSendGraveSubToDeck(cm.costfilter2,cm.costcheck2,5,5)
function cm.target(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsPlayerCanDraw(tp,2) end
RD.TargetDraw(tp,2)
......
......@@ -29,8 +29,7 @@ end
function cm.cost(e,tp,eg,ep,ev,re,r,rp,chk)
local g=Duel.GetMatchingGroup(cm.costfilter,tp,LOCATION_EXTRA+LOCATION_HAND,0,nil)
if chk==0 then return g:CheckSubGroup(cm.check,2,2) end
Duel.Hint(HINT_SELECTMSG,tp,aux.Stringid(m,1))
local sg=g:SelectSubGroup(tp,cm.check,false,2,2)
local sg=RD.Select(aux.Stringid(m,1),tp,g,cm.check,false,2,2)
local mc,fc=sg:GetFirst(),sg:GetNext()
if mc:IsLocation(LOCATION_EXTRA) then mc,fc=fc,mc end
Duel.ConfirmCards(1-tp,fc)
......
......@@ -37,13 +37,9 @@ end
function cm.condition(e,tp,eg,ep,ev,re,r,rp)
return eg:IsExists(cm.confilter,1,nil,1-tp)
end
cm.cost=RD.CostChooseAction(HINTMSG_TODECK,HINTMSG_POSCHANGE,aux.Stringid(m,1),
cm.costfilter1,nil,LOCATION_HAND,1,function(g,e,tp)
RD.SendToDeckSort(g,SEQ_DECKBOTTOM,REASON_COST,tp)
end,
cm.costfilter2,nil,LOCATION_MZONE,1,function(g,e,tp)
RD.ChangePosition(g,e,tp,REASON_COST)
end)
cm.cost=RushDuel.CostChoose(HINTMSG_TODECK,cm.cost1,HINTMSG_POSCHANGE,cm.cost2)
cm.cost1=RD.CostSendHandToDeckBottom(cm.costfilter1,1,1,false)
cm.cost2=RD.CostChangePosition(cm.costfilter2,1,1)
function cm.target(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsExistingMatchingCard(cm.filter,tp,0,LOCATION_MZONE,1,nil,e,tp) end
local g=Duel.GetMatchingGroup(cm.filter,tp,0,LOCATION_MZONE,nil,e,tp)
......
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