Commit 19b8f8bc authored by Vury Leo's avatar Vury Leo

Add 赫聖の妖騎士 and 神海竜ギシルノドン

parent 7c8fda75
......@@ -3439,8 +3439,10 @@ end
function Synchro.AddSynchroProcedure(c,params)
params=params or {}
local tuner_race=params.tuner_race or RACE_ALL
local tuner_level=params.tuner_level or {}
local tuner_filter=params.tuner_filter or aux.TRUE
local non_tuner_race=params.non_tuner_race or RACE_ALL
local non_tuner_level=params.non_tuner_level or {}
local non_tuner_filter=params.non_tuner_filter or aux.TRUE
local tuner_min=params.tuner_min or 1
local tuner_max=params.tuner_max or 1
......@@ -3469,8 +3471,8 @@ function Synchro.AddSynchroProcedure(c,params)
e1:SetCode(EFFECT_SPSUMMON_PROC)
e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e1:SetRange(LOCATION_EXTRA)
e1:SetCondition(Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck))
e1:SetTarget(Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck))
e1:SetCondition(Synchro.SynCondition(tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck))
e1:SetTarget(Synchro.SynTarget(tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck))
e1:SetOperation(Synchro.SynOperation())
e1:SetValue(SUMMON_TYPE_SYNCHRO)
c:RegisterEffect(e1)
......@@ -3483,8 +3485,8 @@ function Synchro.AddSynchroProcedure(c,params)
e2:SetCode(EFFECT_SPSUMMON_PROC)
e2:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e2:SetRange(LOCATION_EXTRA)
e2:SetCondition(Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck))
e2:SetTarget(Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck))
e2:SetCondition(Synchro.SynCondition(tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck))
e2:SetTarget(Synchro.SynTarget(tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck))
e2:SetOperation(Synchro.SynOperation())
e2:SetValue(SUMMON_TYPE_SYNCHRO)
c:RegisterEffect(e2)
......@@ -3493,8 +3495,8 @@ end
-- Entry point: prepares and invokes the DFS
--- @param tc Card
function Synchro.FindValidSelection(candidates,target_level,
tuner_race,tuner_filter,
non_tuner_race,non_tuner_filter,tc,
tuner_race,tuner_level,tuner_filter,
non_tuner_race,non_tuner_level,non_tuner_filter,tc,
tuner_min,tuner_max,
non_tuner_min,non_tuner_max,
level_mapper,hand_count_mapper,
......@@ -3530,8 +3532,8 @@ function Synchro.FindValidSelection(candidates,target_level,
-- 3) Invoke the core DFS, passing last_dyn along
return Synchro.CanCompleteSelection(
candidates,target_level,
tuner_race,tuner_filter,
non_tuner_race,non_tuner_filter,tc,
tuner_race,tuner_level,tuner_filter,
non_tuner_race,non_tuner_level,non_tuner_filter,tc,
tuner_min,tuner_max,
non_tuner_min,non_tuner_max,
level_mapper,hand_count_mapper,
......@@ -3554,9 +3556,11 @@ end
--- @param candidates Card[] -- Candidate material cards.
--- @param target_level integer -- Required total level.
--- @param tuner_race integer -- Bitmask of allowed tuner races.
--- @param tuner_filter fun(mc:Card,tc:Card):boolean -- Tests if mc can be a Tuner.
--- @param tuner_level integer[] -- table of allowed tuner levels.
--- @param tuner_filter fun(mc:Card,tc:Card):boolean -- Tests if mc can be a Tuner.
--- @param non_tuner_race integer -- Bitmask of allowed non-tuner races.
--- @param non_tuner_filter fun(mc:Card,tc:Card):boolean -- Tests if mc can be a non-Tuner.
--- @param non_tuner_level integer[] -- table of allowed non-tuner levels.
--- @param non_tuner_filter fun(mc:Card,tc:Card):boolean -- Tests if mc can be a non-Tuner.
--- @param tc Card -- Synchro monster being summoned.
--- @param tuner_min integer -- Minimum number of Tuners.
--- @param tuner_max integer|table -- Maximum number of Tuners.
......@@ -3583,7 +3587,7 @@ end
--- hand_prune_index integer
--- race_prune_index integer
--- @return boolean True if a valid selection exists, false otherwise.
function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tc,
function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck,selected,index,state,prune_indexes)
if state.tuner_count>tuner_max then return false end
......@@ -3607,6 +3611,36 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f
prune_level=math.huge -- infinity
end
if index>prune_indexes.level_prune_index then
--- assume no level mapper met the requirement actually, so we do not need to enforce the level
if #tuner_level>0 then
local old_tuner_filer=prune_tuner_filter
prune_tuner_filter=aux.AND(function(c)
for _,level in ipairs(tuner_level) do
for _,can_be in ipairs(state.level_mapper(c,tc)) do
if level==can_be then
return true
end
end
end
return false
end,old_tuner_filer)
end
if #non_tuner_level>0 then
local old_non_tuner_filer=prune_non_tuner_filter
prune_non_tuner_filter=aux.AND(function(c)
for _,level in ipairs(non_tuner_level) do
for _,can_be in ipairs(state.level_mapper(c,tc)) do
if level==can_be then
return true
end
end
end
return false
end,prune_non_tuner_filter)
end
end
--- prune on hand count
if index==prune_indexes.hand_prune_index+1 then
if state.hand_count>state.hand_count_limit then
......@@ -3657,17 +3691,17 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f
--- include branch
if can_include then
for _,diff in ipairs(Synchro.GenerateVariantForCard(
state,mc,selected,tc,tuner_race,prune_tuner_filter,non_tuner_race,prune_non_tuner_filter
state,mc,selected,tc,tuner_race,tuner_level,prune_tuner_filter,non_tuner_race,non_tuner_level,prune_non_tuner_filter
)) do
-- apply diff
local branch_state=Synchro.ApplyVariantState(
state,mc,diff,tuner_race,prune_tuner_filter,non_tuner_race,prune_non_tuner_filter,tc,prune_level,append_material_limit_filter
state,mc,diff,tuner_race,tuner_level,prune_tuner_filter,non_tuner_race,non_tuner_level,prune_non_tuner_filter,tc,prune_level,append_material_limit_filter
)
table.insert(selected,mc)
if Synchro.CanCompleteSelection(
candidates,target_level,
tuner_race,tuner_filter,
non_tuner_race,non_tuner_filter,tc,
tuner_race,tuner_level,tuner_filter,
non_tuner_race,non_tuner_level,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,
level_mapper,hand_count_mapper,scheck,sgoalcheck,
selected,index+1,branch_state,prune_indexes
......@@ -3680,7 +3714,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f
end
-- exclude branch
if Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tc,
if Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck,selected,index+1,state,prune_indexes) then
return true
end
......@@ -3704,7 +3738,7 @@ end
--- @param hand_count_mapper fun(mc,tc):integer
--- @param scheck fun(mg:Group):boolean Called during selection to prune branches when it’s impossible to meet the conditions.
--- @param sgoalcheck fun(mg:Group):boolean Called after full selection to verify the final Synchro Summon condition.
function Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck)
function Synchro.SynCondition(tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck)
--- @param mg Group
return function(e,c,smat,mg,min,max,accel_synchro_opts)
if c==nil then return true end
......@@ -3755,17 +3789,17 @@ function Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_f
end
table.insert(pre_selected_arr,smat)
end
local pre_selected_states=Synchro.BuildStatesFromSelection(pre_selected_arr,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,level_mapper,hand_count_mapper,c,math.huge,skip_hand_count_check)
local pre_selected_states=Synchro.BuildStatesFromSelection(pre_selected_arr,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,level_mapper,hand_count_mapper,c,math.huge,skip_hand_count_check)
for _,state in ipairs(pre_selected_states) do
if Synchro.FindValidSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,c,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck,pre_selected_arr,state) then
if Synchro.FindValidSelection(candidates,target_level,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,c,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck,pre_selected_arr,state) then
return true
end
end
end
end
function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck)
function Synchro.SynTarget(tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,scheck,sgoalcheck)
return function(e,tp,eg,ep,ev,re,r,rp,chk,tc,smat,mg,min,max,accel_synchro_opts)
--- accel synchro has already selected their materials, skip material selection step
if mg~=nil and #mg==min then
......@@ -3822,8 +3856,8 @@ function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filt
local selected_level_min=target_level
local selected_states=Synchro.BuildStatesFromSelection(
sg_arr,
tuner_race,tuner_filter,
non_tuner_race,non_tuner_filter,
tuner_race,tuner_level,tuner_filter,
non_tuner_race,non_tuner_level,non_tuner_filter,
level_mapper,hand_count_mapper,
tc,math.huge,skip_hand_count_check
)
......@@ -3860,8 +3894,8 @@ function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filt
local base_states=Synchro.BuildStatesFromSelection(
test_selection,
tuner_race,tuner_filter,
non_tuner_race,non_tuner_filter,
tuner_race,tuner_level,tuner_filter,
non_tuner_race,non_tuner_level,non_tuner_filter,
level_mapper,hand_count_mapper,
tc,math.huge,skip_hand_count_check
)
......@@ -3869,8 +3903,8 @@ function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filt
for _,init_state in ipairs(base_states) do
if Synchro.FindValidSelection(
rest_candidates,target_level,
tuner_race,tuner_filter,
non_tuner_race,non_tuner_filter,tc,
tuner_race,tuner_level,tuner_filter,
non_tuner_race,non_tuner_level,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,
level_mapper,hand_count_mapper,scheck,sgoalcheck,test_selection,init_state)
then
......@@ -3889,7 +3923,7 @@ function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filt
break
end
local finishable=Synchro.IsSelectionValid(sg_arr,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tc,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,sgoalcheck)
local finishable=Synchro.IsSelectionValid(sg_arr,target_level,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tc,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,sgoalcheck)
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_SMATERIAL)
local picked=Group.SelectUnselect(addable,sg,tp,finishable,true,selected_level_min,target_level)
......@@ -3984,14 +4018,14 @@ function Synchro.SynOperation()
end
end
function Synchro.IsSelectionValid(selection,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tc,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,sgoalcheck)
function Synchro.IsSelectionValid(selection,target_level,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tc,tuner_min,tuner_max,non_tuner_min,non_tuner_max,level_mapper,hand_count_mapper,sgoalcheck)
if not sgoalcheck(Group.FromCards(table.unpack(selection))) then
return false
end
local states=Synchro.BuildStatesFromSelection(
selection,
tuner_race,tuner_filter,
non_tuner_race,non_tuner_filter,
tuner_race,tuner_level,tuner_filter,
non_tuner_race,non_tuner_level,non_tuner_filter,
level_mapper,hand_count_mapper,
tc,target_level
)
......@@ -4109,7 +4143,7 @@ function Synchro.UpdatepossibleSums(possible_sums,card_levels,prune_level)
return new_sums
end
function Synchro.BuildStatesFromSelection(selection,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,level_mapper,hand_count_mapper,tc,prune_level,skip_hand_count_check)
function Synchro.BuildStatesFromSelection(selection,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,level_mapper,hand_count_mapper,tc,prune_level,skip_hand_count_check)
local states={
{
possible_sums={[0]=true},
......@@ -4155,11 +4189,11 @@ function Synchro.BuildStatesFromSelection(selection,tuner_race,tuner_filter,non_
for _,st in ipairs(states) do
for _,diff in ipairs(Synchro.GenerateVariantForCard(
st,card,selected,tc,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter
st,card,selected,tc,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter
)) do
-- merge diff into full state
local new_state = Synchro.ApplyVariantState(
st,card,diff,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tc,prune_level,append_material_limit_filter
st,card,diff,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tc,prune_level,append_material_limit_filter
)
table.insert(next_states,new_state)
end
......@@ -4265,7 +4299,7 @@ function Synchro.IsNoHarm(c,tc)
end
-- Helper to generate only the variant-specific diffs for a card
function Synchro.GenerateVariantForCard(st,card,selected,tc,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter)
function Synchro.GenerateVariantForCard(st,card,selected,tc,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter)
local base_variants = {}
-- MonoSynchron first/second
if Synchro.IsMono(card) then
......@@ -4394,7 +4428,7 @@ end
-- Helper to apply a diff to a base state
function Synchro.ApplyVariantState(st,card,diff,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tc,prune_level,append_material_limit_filter)
function Synchro.ApplyVariantState(st,card,diff,tuner_race,tuner_level,tuner_filter,non_tuner_race,non_tuner_level,non_tuner_filter,tc,prune_level,append_material_limit_filter)
-- compute increments using provided filters
local tuner_inc=diff.tuner_delta
local non_tuner_inc=diff.non_tuner_delta
......
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