Commit 2ecb3ab8 authored by Vury Leo's avatar Vury Leo

tuning 白の枢機竜

parent 70ab2010
...@@ -30,7 +30,7 @@ function s.initial_effect(c) ...@@ -30,7 +30,7 @@ function s.initial_effect(c)
end, end,
}) })
}, },
mat_filter=s.mat_filter, matfilter=s.matfilter,
fgoalcheck=s.fgoalcheck, fgoalcheck=s.fgoalcheck,
}) })
--material limit --material limit
...@@ -96,7 +96,7 @@ function s.fgoalcheck(mg) ...@@ -96,7 +96,7 @@ function s.fgoalcheck(mg)
return hand>=1 and field>=1 return hand>=1 and field>=1
end end
function s.mat_filter(mc,tc) function s.matfilter(mc,tc)
return mc:IsLocation(LOCATION_HAND) or mc:IsControler(tc:GetControler()) and mc:IsOnField() return mc:IsLocation(LOCATION_HAND) or mc:IsControler(tc:GetControler()) and mc:IsOnField()
end end
......
...@@ -2,13 +2,31 @@ ...@@ -2,13 +2,31 @@
local s,id,o=GetID() local s,id,o=GetID()
function s.initial_effect(c) function s.initial_effect(c)
c:EnableReviveLimit() c:EnableReviveLimit()
-- aux.AddFusionProcFunRep(c,s.ffilter,2,true)
Fusion.AddFusionProcedure(c,{ Fusion.AddFusionProcedure(c,{
slots={ slots={
Fusion.Slot.Group({ Fusion.Slot.Group({
min=2, min=2,
max=2, max=2,
unique_by=function(mc) return { mc:GetCode(),mc:GetFusionCode() } end, --- @param mc Card
unique_by=function(mc)
local function dedup_represent(code)
if code==78734254 then
return 17955766
elseif code==13857930 then
return 17732278
end
return code
end
local code=dedup_represent(mc:GetCode())
local res={code}
--- Add Fusion Tag names
for _,eff in ipairs({mc:IsHasEffect(EFFECT_ADD_FUSION_CODE)}) do
local fusion_tag_code=eff:GetValue()
assert(type(fusion_tag_code)=='number')
table.insert(res,dedup_represent(fusion_tag_code))
end
return res
end,
has_same={ has_same={
function(mc,tc) return mc:GetFusionAttribute(tc:GetOwner()) end, function(mc,tc) return mc:GetFusionAttribute(tc:GetOwner()) end,
function(mc) return mc:GetRace() end, function(mc) return mc:GetRace() end,
...@@ -34,14 +52,6 @@ function s.initial_effect(c) ...@@ -34,14 +52,6 @@ function s.initial_effect(c)
e2:SetOperation(s.operation) e2:SetOperation(s.operation)
c:RegisterEffect(e2) c:RegisterEffect(e2)
end end
function s.matchfilter(c,attr,race)
return c:IsFusionAttribute(attr) and c:IsRace(race)
end
function s.ffilter(c,fc,sub,mg,sg)
return not sg or sg:FilterCount(aux.TRUE,c)==0
or (sg:IsExists(s.matchfilter,#sg-1,c,c:GetFusionAttribute(),c:GetRace())
and not sg:IsExists(Card.IsFusionCode,1,c,c:GetFusionCode()))
end
function s.target(e,tp,eg,ep,ev,re,r,rp,chk) function s.target(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return Duel.IsPlayerCanDraw(tp,1) end if chk==0 then return Duel.IsPlayerCanDraw(tp,1) end
Duel.SetTargetPlayer(tp) Duel.SetTargetPlayer(tp)
......
...@@ -3475,14 +3475,14 @@ function Fusion.AddFusionProcedure(c, opts) ...@@ -3475,14 +3475,14 @@ function Fusion.AddFusionProcedure(c, opts)
end end
---@param allow_extras boolean whether to allow extra materials for checking propose ---@param allow_extras boolean whether to allow extra materials for checking propose
function Fusion.BasicCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,selected) function Fusion.BasicCondition(tc,slots,matfilter,fgoalcheck,allow_extras,selected)
return function(e,g,gc,chkf) return function(e,g,gc,chkf)
if not g then return false end if not g then return false end
-- Collect cards and apply global mat_filter -- Collect cards and apply global matfilter
local cards={} local cards={}
for c in aux.Next(g) do for c in aux.Next(g) do
if not mat_filter or mat_filter(c,tc) then if not matfilter or matfilter(c,tc) then
table.insert(cards,c) table.insert(cards,c)
end end
end end
...@@ -3506,7 +3506,7 @@ function Fusion.BasicCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,selec ...@@ -3506,7 +3506,7 @@ function Fusion.BasicCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,selec
end end
-- Prepare locked flags for substitute materials -- Prepare locked flags for substitute materials
local locked = {} local locked={}
if Fusion.LockedCodes then if Fusion.LockedCodes then
for _, code in ipairs(Fusion.LockedCodes) do for _, code in ipairs(Fusion.LockedCodes) do
for i,slot in ipairs(single_slots) do for i,slot in ipairs(single_slots) do
...@@ -3531,7 +3531,7 @@ function Fusion.BasicCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,selec ...@@ -3531,7 +3531,7 @@ function Fusion.BasicCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,selec
end end
end end
-- 5) DFS assign single‐slots -- DFS assign single‐slots
local used={} local used={}
local sub_count=0 local sub_count=0
local function dfs_singles(i) local function dfs_singles(i)
...@@ -3630,13 +3630,15 @@ function Fusion.StrictGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf) ...@@ -3630,13 +3630,15 @@ function Fusion.StrictGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf)
return false return false
end end
-- has_same on full matched -- has_same on full matched
if grp.has_same and not Fusion.CheckHasSame(grp,Group.FromCards(table.unpack(matched)),e) then if grp.has_same and not Fusion.CheckHasSame(grp,matched,e) then
Debug.Message("rejected by has_same")
return false return false
end end
-- unique_by on full matched -- unique_by on full matched
if grp.unique_by then if grp.unique_by then
local matcher=Fusion.UniqueByMatching(grp.unique_by,#matched) local matcher=Fusion.UniqueByMatching(grp.unique_by,#matched)
if not matcher(matched) then if not matcher(matched) then
Debug.Message("rejected by unique_by")
return false return false
end end
end end
...@@ -3655,6 +3657,7 @@ function Fusion.SearchGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf) ...@@ -3655,6 +3657,7 @@ function Fusion.SearchGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf)
table.insert(matched,c) table.insert(matched,c)
end end
end end
if #matched<grp.min then if #matched<grp.min then
return false return false
end end
...@@ -3666,24 +3669,25 @@ function Fusion.SearchGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf) ...@@ -3666,24 +3669,25 @@ function Fusion.SearchGroup(e,leftovers,mg_base,grp,tc,fgoalcheck,chkf)
return false return false
end end
end end
local comb={} local comb={}
local function dfs(start,depth) local function dfs(start,depth)
-- If we have at least grp.min cards, test this subset immediately -- If we have at least grp.min cards, test this subset immediately
if depth>=grp.min then if depth>=grp.min then
-- build subset group and merged material group -- build subset group and merged material group
local subG=Group.FromCards(table.unpack(comb,1,depth)) local sub_g_arr={table.unpack(comb,1,depth)}
local subG=Group.FromCards(table.unpack(sub_g_arr))
local mg_tmp=mg_base:Clone() local mg_tmp=mg_base:Clone()
mg_tmp:Merge(subG) mg_tmp:Merge(subG)
-- has_same check -- has_same check
local ok_same=not grp.has_same or Fusion.CheckHasSame(grp,subG,e) local ok_same=not grp.has_same or Fusion.CheckHasSame(grp,sub_g_arr,e)
-- unique_by check -- unique_by check
local ok_unique=true local ok_unique=true
if grp.unique_by then if grp.unique_by then
local matcher=Fusion.UniqueByMatching(grp.unique_by,depth) local matcher=Fusion.UniqueByMatching(grp.unique_by,#sub_g_arr)
ok_unique=matcher(comb) ok_unique=matcher(sub_g_arr)
end end
-- final fusion checks -- final fusion checks
if ok_same and ok_unique and Fusion.FinalCheck(e,mg_tmp,tc,fgoalcheck,chkf) then if ok_same and ok_unique and Fusion.FinalCheck(e,mg_tmp,tc,fgoalcheck,chkf) then
...@@ -3718,9 +3722,7 @@ end ...@@ -3718,9 +3722,7 @@ end
-- Shared has_same checker (bitmask or key‐list) -- Shared has_same checker (bitmask or key‐list)
function Fusion.CheckHasSame(grp,group_obj,e) function Fusion.CheckHasSame(grp,cards,e)
local cards={}
for c in aux.Next(group_obj) do table.insert(cards,c) end
for _,fn in ipairs(grp.has_same) do for _,fn in ipairs(grp.has_same) do
local v0=fn(cards[1],e:GetHandler()) local v0=fn(cards[1],e:GetHandler())
if type(v0)=="number" then if type(v0)=="number" then
...@@ -4001,7 +4003,7 @@ end ...@@ -4001,7 +4003,7 @@ end
--- @param slots table[] your slot definitions --- @param slots table[] your slot definitions
--- @param tc Card the Fusion monster (for substitutes) --- @param tc Card the Fusion monster (for substitutes)
--- @return boolean true if ∃ a mapping + completion path --- @return boolean true if ∃ a mapping + completion path
function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc,gc,chkf) function Fusion.CanCompleteFromMappings(e,sel,eg,slots,matfilter,fgoalcheck,tc,gc,chkf)
-- arrayify sel so we can refer by index -- arrayify sel so we can refer by index
local cards_sel={} local cards_sel={}
for c in aux.Next(sel) do for c in aux.Next(sel) do
...@@ -4071,14 +4073,7 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc, ...@@ -4071,14 +4073,7 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc,
for i,slot in ipairs(slots) do for i,slot in ipairs(slots) do
if slot.group then if slot.group then
local need=group_need[i] or 0 local need=group_need[i] or 0
-- if this slot has a unique_by, wrap its filter to exclude collided keys
local new_filter=slot.group.filter local new_filter=slot.group.filter
if slot.group.unique_by then
local used_keys=Fusion.ExtractUsedKeys(cards_sel,mapping,i,slot.group.unique_by)
new_filter=Fusion.MakeExcludeFilter(new_filter,slot.group.unique_by,used_keys)
end
-- if this slot has a has_same, wrap its filter to include only sames
if slot.group.has_same then
-- only if there is at least one already‐selected card for this slot… -- only if there is at least one already‐selected card for this slot…
local has_sel=false local has_sel=false
for _,mapped_i in pairs(mapping) do for _,mapped_i in pairs(mapping) do
...@@ -4088,6 +4083,13 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc, ...@@ -4088,6 +4083,13 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc,
end end
end end
if has_sel then if has_sel then
-- if this slot has a unique_by, wrap its filter to exclude collided keys
if slot.group.unique_by then
local used_keys=Fusion.ExtractUsedKeys(cards_sel,mapping,i,slot.group.unique_by)
new_filter=Fusion.MakeExcludeFilter(new_filter,slot.group.unique_by,used_keys)
end
-- if this slot has a has_same, wrap its filter to include only sames
if slot.group.has_same then
-- precompute, for each fn in has_same, the overlap of already-mapped cards -- precompute, for each fn in has_same, the overlap of already-mapped cards
local used_overlap={} -- fn → (number mask) or (table of keys) local used_overlap={} -- fn → (number mask) or (table of keys)
for _,fn in ipairs(slot.group.has_same) do for _,fn in ipairs(slot.group.has_same) do
...@@ -4152,8 +4154,8 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc, ...@@ -4152,8 +4154,8 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc,
min=need, min=need,
max=slot.group.max-slot.group.min+need, max=slot.group.max-slot.group.min+need,
filter=new_filter, filter=new_filter,
unique_by=slot.unique_by, unique_by=slot.group.unique_by,
has_same=slot.has_same, has_same=slot.group.has_same,
} }
}) })
end end
...@@ -4177,7 +4179,7 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc, ...@@ -4177,7 +4179,7 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc,
end end
-- delegate to FusionCondition (allow_extras=true) -- delegate to FusionCondition (allow_extras=true)
local search_cond=Fusion.BasicCondition(tc,rem_slots,mat_filter,fgoalcheck,true,sel) local search_cond=Fusion.BasicCondition(tc,rem_slots,matfilter,fgoalcheck,true,sel)
if search_cond(e,rem_pool,gc,chkf) then if search_cond(e,rem_pool,gc,chkf) then
Fusion.LockedCodes=old_locked Fusion.LockedCodes=old_locked
return true return true
...@@ -4215,7 +4217,6 @@ function Fusion.UniqueByMatching(key_func,min_needed) ...@@ -4215,7 +4217,6 @@ function Fusion.UniqueByMatching(key_func,min_needed)
table.insert(card_keys[idx],id) table.insert(card_keys[idx],id)
end end
end end
-- quick reject if fewer distinct keys exist than needed -- quick reject if fewer distinct keys exist than needed
if next_key_id<min_needed then if next_key_id<min_needed then
return false return false
...@@ -4300,14 +4301,14 @@ function Fusion.BuildPatterns(opts) ...@@ -4300,14 +4301,14 @@ function Fusion.BuildPatterns(opts)
for _, v in ipairs(opts.variants) do for _, v in ipairs(opts.variants) do
table.insert(patterns,{ table.insert(patterns,{
slots=v.slots, slots=v.slots,
mat_filter=v.mat_filter, matfilter=v.matfilter,
fgoalcheck=v.fgoalcheck or aux.TRUE, fgoalcheck=v.fgoalcheck or aux.TRUE,
}) })
end end
else else
table.insert(patterns,{ table.insert(patterns,{
slots=opts.slots, slots=opts.slots,
mat_filter=opts.mat_filter, matfilter=opts.matfilter,
fgoalcheck=opts.fgoalcheck or aux.TRUE, fgoalcheck=opts.fgoalcheck or aux.TRUE,
}) })
end end
...@@ -4331,7 +4332,7 @@ function Fusion.MultiCondition(tc,patterns,allow_extras) ...@@ -4331,7 +4332,7 @@ function Fusion.MultiCondition(tc,patterns,allow_extras)
end end
end end
if ok then if ok then
local cond=Fusion.BasicCondition(tc,pat.slots,pat.mat_filter,pat.fgoalcheck,allow_extras,selected) local cond=Fusion.BasicCondition(tc,pat.slots,pat.matfilter,pat.fgoalcheck,allow_extras,selected)
if cond(e,g,gc,chkf) then if cond(e,g,gc,chkf) then
return true return true
end end
...@@ -4409,7 +4410,7 @@ function Fusion.MultiOperation(tc,patterns) ...@@ -4409,7 +4410,7 @@ function Fusion.MultiOperation(tc,patterns)
sg:AddCard(mc) sg:AddCard(mc)
-- completion test against active patterns -- completion test against active patterns
for _,pat in ipairs(active_patterns) do for _,pat in ipairs(active_patterns) do
if Fusion.CanCompleteFromMappings(e,sg,eg,pat.slots,pat.mat_filter,pat.fgoalcheck,tc,gc,chkf) then if Fusion.CanCompleteFromMappings(e,sg,eg,pat.slots,pat.matfilter,pat.fgoalcheck,tc,gc,chkf) then
addable:AddCard(mc) addable:AddCard(mc)
break break
end end
...@@ -4480,11 +4481,11 @@ function Fusion.FusionCondition(tc,patterns) ...@@ -4480,11 +4481,11 @@ function Fusion.FusionCondition(tc,patterns)
-- attempt “search mode” on each pattern -- attempt “search mode” on each pattern
for _,pat in ipairs(patterns) do for _,pat in ipairs(patterns) do
if Fusion.CanCompleteFromMappings(e,selected,g,pat.slots,pat.mat_filter,pat.fgoalcheck or aux.TRUE,tc,gc,chkf) if Fusion.CanCompleteFromMappings(e,selected,g,pat.slots,pat.matfilter,pat.fgoalcheck or aux.TRUE,tc,gc,chkf) then
then
return true return true
end end
end end
return false
end end
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