Commit 81a1b411 authored by Vury Leo's avatar Vury Leo

Add has_same

parent 5ca698c3
......@@ -2,7 +2,7 @@
local s,id,o=GetID()
function s.initial_effect(c)
c:EnableReviveLimit()
aux.AddFusionProcFunRep(c,s.ffilter,2,true)
-- aux.AddFusionProcFunRep(c,s.ffilter,2,true)
Fusion.AddFusionProcedure(c,{
slots={
Fusion.Slot.Group({
......@@ -10,7 +10,7 @@ function s.initial_effect(c)
max=2,
unique_by=function(mc) return { mc:GetCode(),mc:GetFusionCode() } end,
has_same={
function(mc) return mc:GetFusionAttribute() end,
function(mc,tc) return mc:GetFusionAttribute(tc:GetOwner()) end,
function(mc) return mc:GetRace() end,
}
})
......
......@@ -3500,11 +3500,11 @@ function Fusion.FusionCondition(slots,allow_extras)
end
-- all has_same on S
for _,fn in ipairs(grp.has_same) do
local v0=fn(S[1])
local v0=fn(S[1],e:GetHandler())
if type(v0)=="number" then
local mask=v0
for j=2,#S do
mask=mask&fn(S[j])
mask=mask&fn(S[j],e:GetHandler())
if mask==0 then return false end
end
else
......@@ -3512,7 +3512,7 @@ function Fusion.FusionCondition(slots,allow_extras)
for _, key in ipairs(v0) do common[key] = true end
for j=2,#S do
local next_common = {}
for _,key in ipairs(fn(S[j])) do
for _,key in ipairs(fn(S[j],e:GetHandler())) do
if common[key] then
next_common[key]=true
end
......@@ -3533,7 +3533,7 @@ function Fusion.FusionCondition(slots,allow_extras)
end
for idx=start,n do
table.insert(comb,idx)
dfs_comb(idx + 1)
dfs_comb(idx+1)
table.remove(comb)
if found then return end
end
......@@ -3543,12 +3543,12 @@ function Fusion.FusionCondition(slots,allow_extras)
if not found then return false end
else
for _,fn in ipairs(grp.has_same) do
local v0=fn(matched[1])
local v0=fn(matched[1],e:GetHandler())
if type(v0)=="number" then
-- bitmask path
local common_mask=v0
for j=2,#matched do
common_mask=common_mask&fn(matched[j])
common_mask=common_mask&fn(matched[j],e:GetHandler())
if common_mask==0 then
return false
end
......@@ -3561,7 +3561,7 @@ function Fusion.FusionCondition(slots,allow_extras)
end
for j=2,#matched do
local next_common={}
for _, k in ipairs(fn(matched[j])) do
for _, k in ipairs(fn(matched[j],e:GetHandler())) do
if common[k] then
next_common[k]=true
end
......@@ -3663,7 +3663,7 @@ function Fusion.FusionOperation(slots)
max_req=max_req+1
end
end
local max_req=math.min(max_req,eg:GetCount())
max_req=math.min(max_req,eg:GetCount())
-- prompt player
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_FMATERIAL)
......@@ -3812,17 +3812,19 @@ function Fusion.FindAllMappings(cards_sel,slots,handler)
-- passes all uniqueness checks → record it
local copy={}
for k,v in pairs(mapping) do
copy[k] = v
copy[k]=v
end
table.insert(all_maps, copy)
table.insert(all_maps,copy)
return
end
local tc=cards_sel[idx]
local any_match=false -- track if we managed to assign tc
-- try single slots
-- try single slots
for i,slot in ipairs(slots) do
if not slot.group and not filled[i] and Fusion.MatchSlot(tc, slot, handler) then
if not slot.group and not filled[i] and Fusion.MatchSlot(tc,slot,handler) then
any_match=true
filled[i]=true
mapping[idx]=i
dfs(idx+1)
......@@ -3835,16 +3837,64 @@ function Fusion.FindAllMappings(cards_sel,slots,handler)
for i,slot in ipairs(slots) do
if slot.group then
local assigned=group_assigned[i]
local max_ok=assigned<slot.group.max
if max_ok and (not slot.group.filter or slot.group.filter(tc)) then
group_assigned[i]=assigned+1
mapping[idx]=i
dfs(idx+1)
group_assigned[i]=assigned
mapping[idx]=nil
if assigned<slot.group.max then
-- base filter
if not slot.group.filter or slot.group.filter(tc) then
-- has_same check: only if there's already ≥1 in this slot
local ok=true
if slot.group.has_same and assigned>0 then
for _,fn in ipairs(slot.group.has_same) do
-- start intersection with this candidate
local v0=fn(tc,handler)
if type(v0)=="number" then
-- bitmask path
local mask=v0
-- AND with each already‐assigned card
for j=1,idx-1 do
if mapping[j]==i then
mask=mask&fn(cards_sel[j],handler)
if mask==0 then break end
end
end
if mask==0 then ok=false end
else
-- list-of-keys path
local common={}
for _,k in ipairs(v0) do common[k]=true end
-- intersect with each already-assigned card
for j=1,idx-1 do
if mapping[j]==i then
local next_c={}
for _,k in ipairs(fn(cards_sel[j],handler)) do
if common[k] then next_c[k]=true end
end
common=next_c
if not next(common) then break end
end
end
if not next(common) then ok=false end
end
if not ok then break end
end
end
if ok then
any_match=true
group_assigned[i]=assigned + 1
mapping[idx]=i
dfs(idx+1)
group_assigned[i]=assigned
mapping[idx]=nil
end
end
end
end
end
-- If we couldn’t assign tc to any slot, prune this branch
if not any_match then
return
end
end
dfs(1)
......@@ -3914,64 +3964,70 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,handler,gc,chkf)
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
local used_overlap={} -- fn → (number mask) or (table of keys)
for _,fn in ipairs(slot.group.has_same) do
local bitmask,keytbl=nil,{}
-- fold each selected card’s fn(...) into either bitmask or keytbl
for idx,mapped_i in pairs(mapping) do
if mapped_i==i then
local v=fn(cards_sel[idx])
if type(v)=="number" then
bitmask=bitmask and (bitmask&v) or v
elseif type(v)=="table" then
for _,k in ipairs(v) do
keytbl[k]=true
-- only if there is at least one already‐selected card for this slot…
local has_sel = false
for _,mapped_i in pairs(mapping) do
if mapped_i==i then
has_sel=true
break
end
end
if has_sel then
-- precompute, for each fn in has_same, the overlap of already-mapped cards
local used_overlap={} -- fn → (number mask) or (table of keys)
for _,fn in ipairs(slot.group.has_same) do
local bitmask,keytbl=nil,{}
-- fold each selected card’s fn(...) into either bitmask or keytbl
for idx,mapped_i in pairs(mapping) do
if mapped_i==i then
local v=fn(cards_sel[idx],handler)
if type(v)=="number" then
bitmask=bitmask and (bitmask&v) or v
elseif type(v)=="table" then
for _,k in ipairs(v) do
keytbl[k]=true
end
end
end
end
-- store whichever collapsed structure is nonempty
if bitmask then
used_overlap[fn]=bitmask
elseif next(keytbl)~=nil then
used_overlap[fn]=keytbl
end
end
-- store whichever collapsed structure is nonempty
if bitmask then
used_overlap[fn]=bitmask
elseif next(keytbl)~=nil then
used_overlap[fn]=keytbl
end
end
-- wrap the existing filter so it also enforces all has_same overlaps
local prev=new_filter
new_filter=function(tc)
-- original criteria
if prev and not prev(tc) then
return false
end
-- for each fn in has_same, check against the precomputed overlap
for fn,overlap in pairs(used_overlap) do
local v=fn(tc)
if type(overlap)=="number" then
-- bitmask path
if (overlap&v)==0 then
return false
end
else
-- list-of-keys path
local ok=false
for _,k in ipairs(v) do
if overlap[k] then
ok=true
break
-- wrap the existing filter so it also enforces all has_same overlaps
local prev=new_filter
new_filter=function(mc)
-- original criteria
if prev and not prev(mc) then
return false
end
-- for each fn in has_same, check against the precomputed overlap
for fn,overlap in pairs(used_overlap) do
local v=fn(mc,handler)
if type(overlap)=="number" then
-- bitmask path
if (overlap&v)==0 then
return false
end
else
-- list-of-keys path
local ok=false
for _,k in ipairs(v) do
if overlap[k] then
ok=true
break
end
end
if not ok then
return false
end
end
if not ok then
return false
end
end
return true
end
return true
end
end
if need>0 then
......
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