Commit ff455bd4 authored by 未闻皂名's avatar 未闻皂名

2022/2/21 尝试模块化RD

parent 01fbde75
-- New Races
RACE_CYBORG = 0x2000000
RACE_MAGICALKNIGHT = 0x4000000
RACE_HYDRAGON = 0x8000000
RACE_OMEGAPSYCHO = 0x10000000
RACE_CELESTIALKNIGHT = 0x20000000
-- Base
RushDuel = {}
RD = RushDuel
function RushDuel.CreatePlayerTargetGlobalEffect(code, value)
local e = Effect.GlobalEffect()
e:SetType(EFFECT_TYPE_FIELD)
e:SetCode(code)
e:SetProperty(EFFECT_FLAG_PLAYER_TARGET)
e:SetTargetRange(1, 1)
if value ~= nil then
e:SetValue(value)
end
Duel.RegisterEffect(e, 0)
return e
end
function RushDuel.CreateFieldGlobalEffect(continuous, code, operation)
local e = Effect.GlobalEffect()
if continuous then
e:SetType(EFFECT_TYPE_FIELD + EFFECT_TYPE_CONTINUOUS)
else
e:SetType(EFFECT_TYPE_FIELD)
end
e:SetCode(code)
e:SetOperation(operation)
Duel.RegisterEffect(e, 0)
return e
end
-- Initialize
function RushDuel.Init()
RushDuel.InitRule()
Duel.BreakEffect = function()
-- Don't Break Effect
end
-- Duel Start
RushDuel.CreateFieldGlobalEffect(true, EVENT_PHASE_START + PHASE_DRAW, function(e)
-- Draw 1 For First Hand
if not Auxiliary.Load2PickRule then
Duel.Draw(0, 1, REASON_RULE)
end
-- Legend Card
local g = Duel.GetMatchingGroup(Card.IsCode, 0, 0xff, 0xff, nil, 120000000)
local legend = g:GetFirst()
while legend do
RushDuel.InitLegend(legend)
legend = g:GetNext()
end
e:Reset()
end)
end
function RushDuel.InitRule()
-- Lock Zone
RushDuel.CreateFieldGlobalEffect(false, EFFECT_DISABLE_FIELD, function(e, tp)
return 0x11711171
end)
-- Draw Phase
RushDuel.CreatePlayerTargetGlobalEffect(EFFECT_DRAW_COUNT, function(e)
return math.max(1, 5 - Duel.GetFieldGroupCount(Duel.GetTurnPlayer(), LOCATION_HAND, 0))
end)
-- Standby Phase
RushDuel.CreatePlayerTargetGlobalEffect(EFFECT_SKIP_SP)
-- Summon Unlimited
RushDuel.CreatePlayerTargetGlobalEffect(EFFECT_SET_SUMMON_COUNT_LIMIT, 100)
-- Once Per Turn
local function get_effect_owner_code(e)
if e:GetType() & EFFECT_TYPE_XMATERIAL == EFFECT_TYPE_XMATERIAL then
-- Maximum L/R Effect
return e:GetLabel()
else
return e:GetOwner():GetCode()
end
end
RushDuel.CreatePlayerTargetGlobalEffect(EFFECT_CANNOT_ACTIVATE, function(e, re, tp)
return re:GetHandler():GetFlagEffect(get_effect_owner_code(re)) ~= 0
end)
RushDuel.CreateFieldGlobalEffect(true, EVENT_CHAIN_SOLVING, function(e, tp, eg, ep, ev, re, r, rp)
local te = Duel.GetChainInfo(ev, CHAININFO_TRIGGERING_EFFECT)
local code = get_effect_owner_code(te)
te:GetHandler():RegisterFlagEffect(code, RESET_EVENT + RESETS_STANDARD + RESET_PHASE + PHASE_END, 0, 1)
end)
-- Trap Activate Limit
local function is_trap(e)
return e:IsHasType(EFFECT_TYPE_ACTIVATE) and e:IsActiveType(TYPE_TRAP)
end
local function tarp_limit(e, rp, tp)
return not is_trap(e)
end
RushDuel.CreateFieldGlobalEffect(true, EVENT_CHAINING, function(e, tp, eg, ep, ev, re, r, rp)
if is_trap(re) then
Duel.SetChainLimit(tarp_limit)
end
end)
-- Main Phase 2
RushDuel.CreatePlayerTargetGlobalEffect(EFFECT_SKIP_M2)
-- Hand Unlimited
RushDuel.CreatePlayerTargetGlobalEffect(EFFECT_HAND_LIMIT, 100)
end
-- Legend
function RushDuel.InitLegend(c)
local e = Effect.GlobalEffect()
e:SetType(EFFECT_TYPE_SINGLE)
e:SetCode(EFFECT_ADD_CODE)
e:SetProperty(EFFECT_FLAG_IGNORE_IMMUNE + EFFECT_FLAG_CANNOT_DISABLE)
e:SetRange(0xff)
e:SetValue(c:GetOriginalCode())
c:RegisterEffect(e)
end
function RushDuel.IsLegendCode(c, ...)
for _, code in ipairs {...} do
if c:GetOriginalCode() == code and c:IsCode(120000000) then
return true
end
end
return false
end
-- Select Effect
function RushDuel.BaseSelectEffect(c, eff1hint, eff1con, eff1op, eff2hint, eff2con, eff2op)
local e = Effect.CreateEffect(c)
e:SetType(EFFECT_TYPE_IGNITION)
e:SetRange(LOCATION_MZONE)
e:SetTarget(RushDuel.SelectEffectTarget(eff1con, eff2con))
e:SetOperation(RushDuel.SelectEffectOperation(eff1hint, eff1con, eff1op, eff2hint, eff2con, eff2op))
return e
end
function RushDuel.SelectEffectCondition(eff1con, eff2con)
return function(e, tp, eg, ep, ev, re, r, rp)
return eff1con(e, tp, eg, ep, ev, re, r, rp, false) or eff2con(e, tp, eg, ep, ev, re, r, rp, false)
end
end
function RushDuel.SelectEffectTarget(eff1con, eff2con)
return function(e, tp, eg, ep, ev, re, r, rp, chk)
if chk == 0 then
return eff1con(e, tp, eg, ep, ev, re, r, rp, false) or eff2con(e, tp, eg, ep, ev, re, r, rp, false)
end
end
end
function RushDuel.SelectEffectOperation(eff1hint, eff1con, eff1op, eff2hint, eff2con, eff2op)
return function(e, tp, eg, ep, ev, re, r, rp)
local eff1 = eff1con(e, tp, eg, ep, ev, re, r, rp, true)
local eff2 = eff2con(e, tp, eg, ep, ev, re, r, rp, true)
local select = 0
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_EFFECT)
if eff1 and eff2 then
select = Duel.SelectOption(tp, eff1hint, eff2hint) + 1
elseif eff1 then
Duel.SelectOption(tp, eff1hint)
select = 1
elseif eff2 then
Duel.SelectOption(tp, eff2hint)
select = 2
end
if select == 1 then
eff1op(e, tp, eg, ep, ev, re, r, rp)
elseif select == 2 then
eff2op(e, tp, eg, ep, ev, re, r, rp)
end
end
end
-- Expand
-- Special Summon Count
function RushDuel.GetSPCount(tp, max)
if Duel.IsPlayerAffectedByEffect(tp, 59822133) then
max = 1
end
local ct = Duel.GetMZoneCount(tp)
if ct < 1 then
return 0
elseif ct > max then
return max
else
return ct
end
end
-- Maximum
TYPE_MAXIMUM = 0x400
SUMMON_TYPE_MAXIMUM = 0x45000000
function RushDuel.AddMaximumProcedure(c, max_atk, left_code, right_code)
-- Maximum Summon
local e1 = Effect.CreateEffect(c)
e1:SetDescription(aux.Stringid(120000000, 0))
e1:SetType(EFFECT_TYPE_FIELD)
e1:SetCode(EFFECT_SPSUMMON_PROC_G)
e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
e1:SetRange(LOCATION_HAND)
e1:SetCondition(function(e, c, og)
if c == nil then
return true
end
local tp = c:GetControler()
local mg = Duel.GetMatchingGroup(RushDuel.MaximumSummonFilter, tp, LOCATION_HAND, 0, nil, e, tp, left_code, right_code)
local fg = Duel.GetFieldGroup(tp, LOCATION_MZONE, 0)
return Duel.GetMZoneCount(tp, fg) > 0 and not Duel.IsPlayerAffectedByEffect(tp, 59822133) and mg:CheckSubGroup(RushDuel.MaximumSummonCheck, 2, 2)
end)
e1:SetOperation(function(e, tp, eg, ep, ev, re, r, rp, c, sg, og)
local mg = Duel.GetMatchingGroup(RushDuel.MaximumSummonFilter, tp, LOCATION_HAND, 0, nil, e, tp, left_code, right_code)
Duel.Hint(HINT_SELECTMSG, tp, aux.Stringid(120000000, 1))
local cancel = Duel.GetCurrentChain() == 0
local g = mg:SelectSubGroup(tp, RushDuel.MaximumSummonCheck, cancel, 2, 2)
if not g then
return
end
local fg = Duel.GetFieldGroup(tp, LOCATION_MZONE, 0)
Duel.SendtoGrave(fg, REASON_RULE)
c:SetMaterial(g)
sg:AddCard(c)
sg:Merge(g)
end)
e1:SetValue(SUMMON_TYPE_MAXIMUM)
c:RegisterEffect(e1)
-- Maximum Material
local e2 = Effect.CreateEffect(c)
e2:SetType(EFFECT_TYPE_SINGLE + EFFECT_TYPE_CONTINUOUS)
e2:SetCode(EVENT_SPSUMMON_SUCCESS)
e2:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
e2:SetCondition(RushDuel.IsMaximumMode)
e2:SetOperation(RushDuel.MaximumOverlay)
c:RegisterEffect(e2)
-- Maximun Atk
local e3 = Effect.CreateEffect(c)
e3:SetType(EFFECT_TYPE_SINGLE)
e3:SetCode(EFFECT_SET_BASE_ATTACK)
e3:SetProperty(EFFECT_FLAG_SINGLE_RANGE + EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
e3:SetRange(LOCATION_MZONE)
e3:SetCondition(RushDuel.IsMaximumMode)
e3:SetValue(max_atk)
c:RegisterEffect(e3)
-- Position
local e4 = Effect.CreateEffect(c)
e4:SetType(EFFECT_TYPE_SINGLE)
e4:SetCode(EFFECT_SET_POSITION)
e4:SetProperty(EFFECT_FLAG_SINGLE_RANGE + EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
e4:SetRange(LOCATION_MZONE)
e4:SetValue(POS_FACEUP_ATTACK)
e4:SetCondition(RushDuel.IsMaximumMode)
c:RegisterEffect(e4)
local e5 = Effect.CreateEffect(c)
e5:SetType(EFFECT_TYPE_SINGLE)
e5:SetCode(EFFECT_CANNOT_CHANGE_POSITION)
e5:SetProperty(EFFECT_FLAG_SINGLE_RANGE + EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
e5:SetRange(LOCATION_MZONE)
e5:SetCondition(RushDuel.IsMaximumMode)
c:RegisterEffect(e5)
local e6 = e5:Clone()
e6:SetCode(EFFECT_CANNOT_CHANGE_POS_E)
e6:SetCondition(RushDuel.MaximumPositionCondition)
c:RegisterEffect(e6)
local e7 = Effect.CreateEffect(c)
e7:SetType(EFFECT_TYPE_SINGLE)
e7:SetCode(EFFECT_CANNOT_TURN_SET)
e7:SetProperty(EFFECT_FLAG_SINGLE_RANGE + EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
e7:SetRange(LOCATION_MZONE)
e7:SetCondition(RushDuel.IsMaximumMode)
c:RegisterEffect(e7)
-- Use 3 MZone
local e8 = Effect.CreateEffect(c)
e8:SetType(EFFECT_TYPE_FIELD)
e8:SetCode(EFFECT_MAX_MZONE)
e8:SetProperty(EFFECT_FLAG_PLAYER_TARGET + EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
e8:SetRange(LOCATION_MZONE)
e8:SetTargetRange(1, 0)
e8:SetCondition(RushDuel.IsMaximumMode)
e8:SetValue(1)
c:RegisterEffect(e8)
-- Leave Field
local e9 = Effect.CreateEffect(c)
e9:SetType(EFFECT_TYPE_SINGLE + EFFECT_TYPE_CONTINUOUS)
e9:SetCode(EVENT_LEAVE_FIELD_P)
e9:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
e9:SetCondition(RushDuel.IsMaximumMode)
e9:SetOperation(RushDuel.MaximumLeaveOperation)
c:RegisterEffect(e9)
end
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()
end
function RushDuel.IsMaximumMode(e_or_c)
local c = e_or_c
if aux.GetValueType(c) == "Effect" then
c = c:GetHandler()
end
return c:IsSummonType(SUMMON_TYPE_MAXIMUM)
end
function RushDuel.MaximumOverlay(e, tp, eg, ep, ev, re, r, rp)
local c = e:GetHandler()
local mg = c:GetMaterial()
Duel.Overlay(c, mg)
Duel.MoveSequence(c, 2)
end
function RushDuel.MaximumPositionCondition(e)
return RushDuel.IsMaximumMode(e) and e:GetHandler():IsAttackPos()
end
function RushDuel.MaximumLeaveOperation(e, tp, eg, ep, ev, re, r, rp)
local c = e:GetHandler()
local loc = c:GetDestination()
local g = c:GetOverlayGroup()
if loc == LOCATION_HAND then
Duel.SendtoHand(g, nil, REASON_RULE)
elseif loc == LOCATION_DECK then
Duel.SendtoDeck(g, nil, 2, REASON_RULE)
elseif loc == LOCATION_REMOVED then
Duel.Remove(g, POS_FACEUP, REASON_RULE)
end
end
-- Expand
-- Is Monster has Def (Maximum)
function RushDuel.IsHasDefense(c)
return c:IsDefenseAbove(0) and not (c:IsSummonType(SUMMON_TYPE_MAXIMUM) and c:GetOverlayCount() > 0)
end
-- Send To Deck Top (Maximun)
function RushDuel.SendtoDeckTop(c, rp, reason)
if c:IsSummonType(SUMMON_TYPE_MAXIMUM) and c:GetOverlayCount() > 0 then
local g = c:GetOverlayGroup()
local ct = g:GetCount() + 1
Duel.SendtoDeck(g, nil, 0, reason)
Duel.SendtoDeck(c, nil, 0, reason)
Duel.SortDecktop(rp, c:GetControler(), ct)
Duel.ConfirmDecktop(c:GetControler(), ct)
else
Duel.SendtoDeck(c, nil, 0, reason)
end
end
This diff is collapsed.
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