Commit 849699be authored by Vury Leo's avatar Vury Leo

Add 接触するG

parent 7f4361f2
...@@ -3468,9 +3468,8 @@ function Fusion.AddFusionProcedure(c, opts) ...@@ -3468,9 +3468,8 @@ function Fusion.AddFusionProcedure(c, opts)
e:SetType(EFFECT_TYPE_SINGLE) e:SetType(EFFECT_TYPE_SINGLE)
e:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE) e:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e:SetCode(EFFECT_FUSION_MATERIAL) e:SetCode(EFFECT_FUSION_MATERIAL)
e:SetCondition(Fusion.SeededCondition(c,patterns))
e:SetCondition(Fusion.MultiCondition(c,patterns,true)) e:SetOperation(Fusion.SeededOperation(c,patterns))
e:SetOperation(Fusion.MultiOperation(c,patterns))
e:SetDescription(1379) e:SetDescription(1379)
c:RegisterEffect(e) c:RegisterEffect(e)
end end
...@@ -3727,7 +3726,7 @@ function Fusion.FusionCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,sele ...@@ -3727,7 +3726,7 @@ function Fusion.FusionCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,sele
end end
-- ensure there's at least one free Monster Zone if chkf requests a field-checked summon -- ensure there's at least one free Monster Zone if chkf requests a field-checked summon
if chkf~=PLAYER_NONE then if chkf&0xf~=PLAYER_NONE then
local tp=chkf&0xf local tp=chkf&0xf
if Duel.GetLocationCountFromEx(tp,tp,mg,tc)<=0 then if Duel.GetLocationCountFromEx(tp,tp,mg,tc)<=0 then
return false return false
...@@ -3856,6 +3855,10 @@ end ...@@ -3856,6 +3855,10 @@ end
--- @param tc Card the fusion monster (for substitutes) --- @param tc Card the fusion monster (for substitutes)
--- @return table[] an array of mapping tables (or empty if none) --- @return table[] an array of mapping tables (or empty if none)
function Fusion.FindAllMappings(cards_sel,slots,tc) function Fusion.FindAllMappings(cards_sel,slots,tc)
--- empty selection, just return
if #cards_sel==0 then
return {{}}
end
-- Trackers -- Trackers
local filled={} -- for single slots local filled={} -- for single slots
local group_assigned={} -- how many cards assigned so far to each group slot local group_assigned={} -- how many cards assigned so far to each group slot
...@@ -4140,12 +4143,12 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc, ...@@ -4140,12 +4143,12 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc,
local prev=new_filter local prev=new_filter
new_filter=function(mc,p_tc) new_filter=function(mc,p_tc)
-- original criteria -- original criteria
if prev and not prev(mc,p_tc) then if prev and not prev(mc,tc) then
return false return false
end end
-- for each fn in has_same, check against the precomputed overlap -- for each fn in has_same, check against the precomputed overlap
for fn,overlap in pairs(used_overlap) do for fn,overlap in pairs(used_overlap) do
local v=fn(mc,p_tc) local v=fn(mc,tc)
if type(overlap)=="number" then if type(overlap)=="number" then
-- bitmask path -- bitmask path
if (overlap&v)==0 then if (overlap&v)==0 then
...@@ -4214,7 +4217,7 @@ end ...@@ -4214,7 +4217,7 @@ end
--- Fusion.UniqueByMatching(key_func, min_needed) --- Fusion.UniqueByMatching(key_func, min_needed)
--- Returns a predicate that succeeds iff you can choose `min_needed` --- Returns a predicate that succeeds iff you can choose `min_needed`
--- distinct keys (from `key_func(tc)` lists) for some subset of cards in `g`. --- distinct keys (from `key_func(mc)` lists) for some subset of cards in `g`.
--- Uses bipartite matching to test existence of a distinct‐key assignment. --- Uses bipartite matching to test existence of a distinct‐key assignment.
--- @param key_func fun(Card): any[] returns all keys a card can take --- @param key_func fun(Card): any[] returns all keys a card can take
--- @param min_needed number how many cards must get distinct keys --- @param min_needed number how many cards must get distinct keys
...@@ -4227,9 +4230,9 @@ function Fusion.UniqueByMatching(key_func,min_needed) ...@@ -4227,9 +4230,9 @@ function Fusion.UniqueByMatching(key_func,min_needed)
local key_index={} -- key_index[key] = unique integer ID local key_index={} -- key_index[key] = unique integer ID
local next_key_id=0 local next_key_id=0
for idx,tc in ipairs(cards) do for idx,mc in ipairs(cards) do
card_keys[idx]={} card_keys[idx]={}
for _,key in ipairs(key_func(tc)) do for _,key in ipairs(key_func(mc)) do
local id=key_index[key] local id=key_index[key]
if not id then if not id then
next_key_id=next_key_id+1 next_key_id=next_key_id+1
...@@ -4285,9 +4288,9 @@ end ...@@ -4285,9 +4288,9 @@ end
--- @return table used_keys --- @return table used_keys
function Fusion.ExtractUsedKeys(cards_sel,mapping,slot_idx,key_func) function Fusion.ExtractUsedKeys(cards_sel,mapping,slot_idx,key_func)
local used={} local used={}
for idx,tc in ipairs(cards_sel) do for idx,mc in ipairs(cards_sel) do
if mapping[idx]==slot_idx then if mapping[idx]==slot_idx then
for _,k in ipairs(key_func(tc)) do for _,k in ipairs(key_func(mc)) do
used[k]=true used[k]=true
end end
end end
...@@ -4340,7 +4343,7 @@ end ...@@ -4340,7 +4343,7 @@ end
-- Helper: combine multiple patterns into one condition function (no goto) -- Helper: combine multiple patterns into one condition function (no goto)
function Fusion.MultiCondition(tc,patterns,allow_extras) function Fusion.MultiCondition(tc,patterns,allow_extras)
return function(e,g,gc,chkf) return function(e,g,gc,chkf,selected)
if not g then return false end if not g then return false end
local locked=Fusion.LockedCodes local locked=Fusion.LockedCodes
for _, pat in ipairs(patterns) do for _, pat in ipairs(patterns) do
...@@ -4355,7 +4358,7 @@ function Fusion.MultiCondition(tc,patterns,allow_extras) ...@@ -4355,7 +4358,7 @@ function Fusion.MultiCondition(tc,patterns,allow_extras)
end end
end end
if ok then if ok then
local cond=Fusion.FusionCondition(tc,pat.slots,pat.mat_filter,pat.fgoalcheck,allow_extras) local cond=Fusion.FusionCondition(tc,pat.slots,pat.mat_filter,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
...@@ -4388,7 +4391,7 @@ end ...@@ -4388,7 +4391,7 @@ end
-- Helper: combine patterns into one operation function -- Helper: combine patterns into one operation function
function Fusion.MultiOperation(tc,patterns) function Fusion.MultiOperation(tc,patterns)
return function(e,tp,eg,ep,ev,re,r,rp,gc,chkf) return function(e,tp,eg,ep,ev,re,r,rp,gc,chkf,selected)
-- filter patterns by any locked codes, once per operation -- filter patterns by any locked codes, once per operation
local locked=Fusion.LockedCodes local locked=Fusion.LockedCodes
local active_patterns={} local active_patterns={}
...@@ -4416,7 +4419,7 @@ function Fusion.MultiOperation(tc,patterns) ...@@ -4416,7 +4419,7 @@ function Fusion.MultiOperation(tc,patterns)
local strict_cond=Fusion.MultiCondition(tc,active_patterns,false) local strict_cond=Fusion.MultiCondition(tc,active_patterns,false)
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_FMATERIAL) Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_FMATERIAL)
local sg=Group.CreateGroup() local sg=selected and selected:Clone() or Group.CreateGroup()
--- arraify eg --- arraify eg
local eg_arr={} local eg_arr={}
...@@ -4459,7 +4462,11 @@ function Fusion.MultiOperation(tc,patterns) ...@@ -4459,7 +4462,11 @@ function Fusion.MultiOperation(tc,patterns)
end end
if sg:IsContains(picked) then if sg:IsContains(picked) then
-- If EFFECT_MUST_BE_FMATERIAL is on your field, ensure it's in selected
local must_materials=Duel.GetMustMaterial(tp,EFFECT_MUST_BE_FMATERIAL)
if picked~=gc and not must_materials:IsContains(picked) then
sg:RemoveCard(picked) sg:RemoveCard(picked)
end
else else
sg:AddCard(picked) sg:AddCard(picked)
end end
...@@ -4481,3 +4488,43 @@ function Fusion.PatternIncludesCode(pat,code) ...@@ -4481,3 +4488,43 @@ function Fusion.PatternIncludesCode(pat,code)
end end
return false return false
end end
--- A “seeded” condition that first tries CanCompleteFromMappings on each pattern,
--- then, if none complete, falls back to the strict DFS.
--- @param tc Card
--- @param patterns table[]
function Fusion.SeededCondition(tc,patterns)
return function(e,g,gc,chkf)
if not g then return false end
-- build your seed group
local selected=Group.CreateGroup()
if gc then selected:AddCard(gc) end
-- merge in any EFFECT_MUST_BE_FMATERIAL on your field
local must_materials=Duel.GetMustMaterial(e:GetHandler():GetOwner(),EFFECT_MUST_BE_FMATERIAL)
selected:Merge(must_materials)
-- attempt “search mode” on each pattern
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)
then
return true
end
end
end
end
function Fusion.SeededOperation(c,patterns)
return function(e,tp,eg,ep,ev,re,r,rp,gc,chkf)
-- build selected = {gc}
local selected = Group.CreateGroup()
if gc then selected:AddCard(gc) end
-- If EFFECT_MUST_BE_FMATERIAL is on your field, ensure it's in selected
local must_materials=Duel.GetMustMaterial(tp,EFFECT_MUST_BE_FMATERIAL)
selected:Merge(must_materials)
-- call the original op, swapping in selected for gc
return Fusion.MultiOperation(c,patterns)(e,tp,eg,ep,ev,re,r,rp,gc,chkf,selected)
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