Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
ygopro-scripts-888
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
3
Merge Requests
3
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
ygopro-scripts-888
Commits
2afce688
Commit
2afce688
authored
Jul 13, 2025
by
Vury Leo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add LockedCodes
parent
9150d818
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
281 additions
and
113 deletions
+281
-113
c11443677.lua
c11443677.lua
+36
-29
c2129638.lua
c2129638.lua
+18
-11
c44362883.lua
c44362883.lua
+11
-10
c70534340.lua
c70534340.lua
+7
-1
c71143015.lua
c71143015.lua
+5
-4
procedure.lua
procedure.lua
+204
-58
No files found.
c11443677.lua
View file @
2afce688
--ブルーアイズ・タイラント・ドラゴン
function
c11443677
.
initial_effect
(
c
)
local
s
,
id
,
o
=
GetID
()
function
s
.
initial_effect
(
c
)
--fusion material
c
:
EnableReviveLimit
()
aux
.
AddFusionProcCodeFun
(
c
,
89631139
,
aux
.
FilterBoolFunction
(
Card
.
IsRace
,
RACE_DRAGON
),
1
,
true
,
true
)
-- aux.AddFusionProcCodeFun(c,89631139,aux.FilterBoolFunction(Card.IsRace,RACE_DRAGON),1,true,true)
Fusion
.
AddFusionProcedure
(
c
,{
slots
=
{
Fusion
.
Slot
.
Code
(
89631139
),
Fusion
.
Slot
.
Filter
(
function
(
mc
,
tc
)
return
mc
:
IsRace
(
RACE_DRAGON
)
end
),
}
})
--special summon condition
local
e1
=
Effect
.
CreateEffect
(
c
)
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
...
...
@@ -17,9 +24,9 @@ function c11443677.initial_effect(c)
e2
:
SetProperty
(
EFFECT_FLAG_CANNOT_DISABLE
+
EFFECT_FLAG_UNCOPYABLE
)
e2
:
SetCode
(
EFFECT_SPSUMMON_PROC
)
e2
:
SetRange
(
LOCATION_EXTRA
)
e2
:
SetCondition
(
c11443677
.
sprcon
)
e2
:
SetTarget
(
c11443677
.
sprtg
)
e2
:
SetOperation
(
c11443677
.
sprop
)
e2
:
SetCondition
(
s
.
sprcon
)
e2
:
SetTarget
(
s
.
sprtg
)
e2
:
SetOperation
(
s
.
sprop
)
c
:
RegisterEffect
(
e2
)
--immune
local
e3
=
Effect
.
CreateEffect
(
c
)
...
...
@@ -27,7 +34,7 @@ function c11443677.initial_effect(c)
e3
:
SetCode
(
EFFECT_IMMUNE_EFFECT
)
e3
:
SetProperty
(
EFFECT_FLAG_SINGLE_RANGE
)
e3
:
SetRange
(
LOCATION_MZONE
)
e3
:
SetValue
(
c11443677
.
efilter
)
e3
:
SetValue
(
s
.
efilter
)
c
:
RegisterEffect
(
e3
)
--attack all
local
e4
=
Effect
.
CreateEffect
(
c
)
...
...
@@ -37,32 +44,32 @@ function c11443677.initial_effect(c)
c
:
RegisterEffect
(
e4
)
--set trap
local
e5
=
Effect
.
CreateEffect
(
c
)
e5
:
SetDescription
(
aux
.
Stringid
(
11443677
,
0
))
e5
:
SetDescription
(
aux
.
Stringid
(
id
,
0
))
e5
:
SetType
(
EFFECT_TYPE_SINGLE
+
EFFECT_TYPE_TRIGGER_O
)
e5
:
SetCode
(
EVENT_DAMAGE_STEP_END
)
e5
:
SetProperty
(
EFFECT_FLAG_CARD_TARGET
)
e5
:
SetCondition
(
c11443677
.
setcon
)
e5
:
SetTarget
(
c11443677
.
settg
)
e5
:
SetOperation
(
c11443677
.
setop
)
e5
:
SetCondition
(
s
.
setcon
)
e5
:
SetTarget
(
s
.
settg
)
e5
:
SetOperation
(
s
.
setop
)
c
:
RegisterEffect
(
e5
)
end
function
c11443677
.
ultimate_fusion_check
(
tp
,
sg
,
fc
)
function
s
.
ultimate_fusion_check
(
tp
,
sg
,
fc
)
return
aux
.
gffcheck
(
sg
,
Card
.
IsFusionCode
,
89631139
,
Card
.
IsRace
,
RACE_DRAGON
)
end
function
c11443677
.
cfilter
(
c
)
function
s
.
cfilter
(
c
)
return
c
:
IsFaceup
()
and
c
:
GetOriginalType
()
&
TYPE_FUSION
~=
0
end
function
c11443677
.
sprfilter
(
c
,
tp
,
sc
)
local
eqc
=
c
:
GetEquipGroup
():
FilterCount
(
c11443677
.
cfilter
,
nil
)
function
s
.
sprfilter
(
c
,
tp
,
sc
)
local
eqc
=
c
:
GetEquipGroup
():
FilterCount
(
s
.
cfilter
,
nil
)
return
c
:
IsFusionCode
(
89631139
)
and
eqc
>
0
and
Duel
.
GetLocationCountFromEx
(
tp
,
tp
,
c
,
sc
)
>
0
and
c
:
IsCanBeFusionMaterial
(
sc
,
SUMMON_TYPE_SPECIAL
)
end
function
c11443677
.
sprcon
(
e
,
c
)
function
s
.
sprcon
(
e
,
c
)
if
c
==
nil
then
return
true
end
local
tp
=
c
:
GetControler
()
return
Duel
.
CheckReleaseGroupEx
(
tp
,
c11443677
.
sprfilter
,
1
,
REASON_SPSUMMON
,
false
,
nil
,
tp
,
c
)
return
Duel
.
CheckReleaseGroupEx
(
tp
,
s
.
sprfilter
,
1
,
REASON_SPSUMMON
,
false
,
nil
,
tp
,
c
)
end
function
c11443677
.
sprtg
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
,
c
)
local
g
=
Duel
.
GetReleaseGroup
(
tp
,
false
,
REASON_SPSUMMON
):
Filter
(
c11443677
.
sprfilter
,
nil
,
tp
,
c
)
function
s
.
sprtg
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
,
c
)
local
g
=
Duel
.
GetReleaseGroup
(
tp
,
false
,
REASON_SPSUMMON
):
Filter
(
s
.
sprfilter
,
nil
,
tp
,
c
)
Duel
.
Hint
(
HINT_SELECTMSG
,
tp
,
HINTMSG_RELEASE
)
local
tc
=
g
:
SelectUnselect
(
nil
,
tp
,
false
,
true
,
1
,
1
)
if
tc
then
...
...
@@ -70,31 +77,31 @@ function c11443677.sprtg(e,tp,eg,ep,ev,re,r,rp,chk,c)
return
true
else
return
false
end
end
function
c11443677
.
sprop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
c
)
function
s
.
sprop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
c
)
local
tc
=
e
:
GetLabelObject
()
c
:
SetMaterial
(
Group
.
FromCards
(
tc
))
Duel
.
Release
(
tc
,
REASON_SPSUMMON
)
end
function
c11443677
.
efilter
(
e
,
te
)
function
s
.
efilter
(
e
,
te
)
return
te
:
IsActiveType
(
TYPE_TRAP
)
end
function
c11443677
.
setcon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
return
e
:
GetHandler
():
GetFlagEffect
(
11443677
)
==
0
and
aux
.
dsercon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
function
s
.
setcon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
return
e
:
GetHandler
():
GetFlagEffect
(
id
)
==
0
and
aux
.
dsercon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
end
function
c11443677
.
setfilter
(
c
)
function
s
.
setfilter
(
c
)
return
c
:
IsType
(
TYPE_TRAP
)
and
c
:
IsSSetable
()
end
function
c11443677
.
settg
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
,
chkc
)
if
chkc
then
return
chkc
:
IsLocation
(
LOCATION_GRAVE
)
and
chkc
:
IsControler
(
tp
)
and
c11443677
.
setfilter
(
chkc
)
end
if
chk
==
0
then
return
Duel
.
IsExistingTarget
(
c11443677
.
setfilter
,
tp
,
LOCATION_GRAVE
,
0
,
1
,
nil
)
end
function
s
.
settg
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
,
chkc
)
if
chkc
then
return
chkc
:
IsLocation
(
LOCATION_GRAVE
)
and
chkc
:
IsControler
(
tp
)
and
s
.
setfilter
(
chkc
)
end
if
chk
==
0
then
return
Duel
.
IsExistingTarget
(
s
.
setfilter
,
tp
,
LOCATION_GRAVE
,
0
,
1
,
nil
)
end
Duel
.
Hint
(
HINT_SELECTMSG
,
tp
,
HINTMSG_SET
)
local
g
=
Duel
.
SelectTarget
(
tp
,
c11443677
.
setfilter
,
tp
,
LOCATION_GRAVE
,
0
,
1
,
1
,
nil
)
local
g
=
Duel
.
SelectTarget
(
tp
,
s
.
setfilter
,
tp
,
LOCATION_GRAVE
,
0
,
1
,
1
,
nil
)
Duel
.
SetOperationInfo
(
0
,
CATEGORY_LEAVE_GRAVE
,
g
,
1
,
0
,
0
)
if
e
:
IsCostChecked
()
then
e
:
GetHandler
():
RegisterFlagEffect
(
11443677
,
RESET_EVENT
|
RESET_TOFIELD
|
RESET_TURN_SET
|
RESET_PHASE
|
PHASE_END
,
0
,
0
,
1
)
e
:
GetHandler
():
RegisterFlagEffect
(
id
,
RESET_EVENT
|
RESET_TOFIELD
|
RESET_TURN_SET
|
RESET_PHASE
|
PHASE_END
,
0
,
0
,
1
)
end
end
function
c11443677
.
setop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
function
s
.
setop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
local
tc
=
Duel
.
GetFirstTarget
()
if
tc
:
IsRelateToEffect
(
e
)
then
Duel
.
SSet
(
tp
,
tc
)
...
...
c2129638.lua
View file @
2afce688
--青眼の双爆裂龍
function
c2129638
.
initial_effect
(
c
)
local
s
,
id
,
o
=
GetID
()
function
s
.
initial_effect
(
c
)
--fusion material
c
:
EnableReviveLimit
()
aux
.
AddFusionProcCodeRep
(
c
,
89631139
,
2
,
true
,
true
)
-- aux.AddFusionProcCodeRep(c,89631139,2,true,true)
Fusion
.
AddFusionProcedure
(
c
,{
slots
=
{
Fusion
.
Slot
.
Code
(
89631139
),
Fusion
.
Slot
.
Code
(
89631139
),
}
})
aux
.
AddContactFusionProcedure
(
c
,
Card
.
IsAbleToGraveAsCost
,
LOCATION_MZONE
,
0
,
Duel
.
SendtoGrave
,
REASON_COST
)
--spsummon condition
local
e1
=
Effect
.
CreateEffect
(
c
)
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetProperty
(
EFFECT_FLAG_CANNOT_DISABLE
+
EFFECT_FLAG_UNCOPYABLE
)
e1
:
SetCode
(
EFFECT_SPSUMMON_CONDITION
)
e1
:
SetValue
(
c2129638
.
splimit
)
e1
:
SetValue
(
s
.
splimit
)
c
:
RegisterEffect
(
e1
)
--indes
local
e3
=
Effect
.
CreateEffect
(
c
)
...
...
@@ -29,30 +36,30 @@ function c2129638.initial_effect(c)
c
:
RegisterEffect
(
e4
)
--remove
local
e7
=
Effect
.
CreateEffect
(
c
)
e7
:
SetDescription
(
aux
.
Stringid
(
2129638
,
0
))
e7
:
SetDescription
(
aux
.
Stringid
(
id
,
0
))
e7
:
SetCategory
(
CATEGORY_REMOVE
)
e7
:
SetType
(
EFFECT_TYPE_SINGLE
+
EFFECT_TYPE_TRIGGER_O
)
e7
:
SetCode
(
EVENT_DAMAGE_STEP_END
)
e7
:
SetCondition
(
c2129638
.
rmcon
)
e7
:
SetTarget
(
c2129638
.
rmtg
)
e7
:
SetOperation
(
c2129638
.
rmop
)
e7
:
SetCondition
(
s
.
rmcon
)
e7
:
SetTarget
(
s
.
rmtg
)
e7
:
SetOperation
(
s
.
rmop
)
c
:
RegisterEffect
(
e7
)
end
function
c2129638
.
splimit
(
e
,
se
,
sp
,
st
)
function
s
.
splimit
(
e
,
se
,
sp
,
st
)
return
bit
.
band
(
st
,
SUMMON_TYPE_FUSION
)
==
SUMMON_TYPE_FUSION
end
function
c2129638
.
rmcon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
function
s
.
rmcon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
local
c
=
e
:
GetHandler
()
local
bc
=
c
:
GetBattleTarget
()
e
:
SetLabelObject
(
bc
)
return
c
==
Duel
.
GetAttacker
()
and
aux
.
dsercon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
and
bc
and
c
:
IsStatus
(
STATUS_OPPO_BATTLE
)
and
bc
:
IsOnField
()
and
bc
:
IsRelateToBattle
()
end
function
c2129638
.
rmtg
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
)
function
s
.
rmtg
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
)
if
chk
==
0
then
return
e
:
GetLabelObject
():
IsAbleToRemove
()
end
Duel
.
SetOperationInfo
(
0
,
CATEGORY_REMOVE
,
e
:
GetLabelObject
(),
1
,
0
,
0
)
end
function
c2129638
.
rmop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
function
s
.
rmop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
local
bc
=
e
:
GetLabelObject
()
if
bc
:
IsRelateToBattle
()
then
Duel
.
Remove
(
bc
,
POS_FACEUP
,
REASON_EFFECT
)
...
...
c44362883.lua
View file @
2afce688
...
...
@@ -6,7 +6,8 @@ function s.initial_effect(c)
local
e1
=
FusionSpell
.
CreateSummonEffect
(
c
,{
fusfilter
=
s
.
fusfilter
,
pre_select_mat_location
=
LOCATION_HAND
|
LOCATION_DECK
|
LOCATION_MZONE
,
additional_fcheck
=
s
.
fcheck
additional_fcheck
=
s
.
fcheck
,
locked_codes
=
{
68468459
},
})
e1
:
SetCategory
(
CATEGORY_SPECIAL_SUMMON
+
CATEGORY_FUSION_SUMMON
+
CATEGORY_DECKDES
)
e1
:
SetCountLimit
(
1
,
id
+
EFFECT_COUNT_CODE_OATH
)
...
...
@@ -44,14 +45,14 @@ function s.fcheck(tp,mg,fc,mg_all)
if
#
mg_all
>
2
then
return
false
end
if
fc
.
branded_fusion_check
~=
nil
then
if
fc
.
branded_fusion_check
(
tp
,
mg_all
,
fc
)
==
false
then
return
false
end
else
if
not
mg_all
:
IsExists
(
function
(
c
)
return
c
:
IsFusionCode
(
68468459
)
end
,
1
,
nil
)
then
return
false
end
end
--
if fc.branded_fusion_check~=nil then
--
if fc.branded_fusion_check(tp,mg_all,fc)==false then
--
return false
--
end
--
else
--
if not mg_all:IsExists(function(c) return c:IsFusionCode(68468459) end,1,nil) then
--
return false
--
end
--
end
return
true
end
c70534340.lua
View file @
2afce688
...
...
@@ -3,7 +3,13 @@ local s,id,o=GetID()
function
s
.
initial_effect
(
c
)
--fusion material
c
:
EnableReviveLimit
()
aux
.
AddFusionProcCodeFun
(
c
,
68468459
,
aux
.
FilterBoolFunction
(
Card
.
IsFusionAttribute
,
ATTRIBUTE_DARK
),
1
,
true
,
true
)
-- aux.AddFusionProcCodeFun(c,68468459,aux.FilterBoolFunction(Card.IsFusionAttribute,ATTRIBUTE_DARK),1,true,true)
Fusion
.
AddFusionProcedure
(
c
,{
slots
=
{
Fusion
.
Slot
.
Code
(
68468459
),
Fusion
.
Slot
.
Filter
(
function
(
mc
,
tc
)
return
mc
:
IsFusionAttribute
(
ATTRIBUTE_DARK
,
tc
:
GetOwner
())
end
),
}
})
--spsummon
local
e1
=
FusionSpell
.
CreateSummonEffect
(
c
,{
fusfilter
=
s
.
fusfilter
,
...
...
c71143015.lua
View file @
2afce688
...
...
@@ -10,7 +10,8 @@ function s.initial_effect(c)
{
[
LOCATION_DECK
]
=
FusionSpell
.
FUSION_OPERATION_GRAVE
},
{
[
0xff
]
=
FusionSpell
.
FUSION_OPERATION_SHUFFLE
}
},
stage_x_operation
=
s
.
stage_x_operation
stage_x_operation
=
s
.
stage_x_operation
,
locked_codes
=
{
89631139
,
23995346
}
})
e1
:
SetCategory
(
CATEGORY_SPECIAL_SUMMON
+
CATEGORY_FUSION_SUMMON
+
CATEGORY_GRAVE_ACTION
)
e1
:
SetHintTiming
(
0
,
TIMINGS_CHECK_MONSTER
+
TIMING_MAIN_END
)
...
...
@@ -34,9 +35,9 @@ function s.fcheck(tp,mg,fc,mg_all)
if
fc
.
ultimate_fusion_check
(
tp
,
mg_all
,
fc
)
==
false
then
return
false
end
elseif
not
(
mg_all
:
IsExists
(
function
(
c
)
return
c
:
IsFusionCode
(
89631139
)
end
,
1
,
nil
)
and
aux
.
IsMaterialListCode
(
fc
,
89631139
)
==
true
or
mg_all
:
IsExists
(
function
(
c
)
return
c
:
IsFusionCode
(
23995346
)
end
,
1
,
nil
)
and
aux
.
IsMaterialListCode
(
fc
,
23995346
)
==
true
)
then
return
false
--
elseif not (mg_all:IsExists(function(c) return c:IsFusionCode(89631139) end,1,nil) and aux.IsMaterialListCode(fc,89631139)==true
--
or mg_all:IsExists(function(c) return c:IsFusionCode(23995346) end,1,nil) and aux.IsMaterialListCode(fc,23995346)==true) then
--
return false
end
return
true
end
...
...
procedure.lua
View file @
2afce688
...
...
@@ -2254,6 +2254,8 @@ FusionSpell = {}
--- @field skip_summon_check? boolean
--- Whether skip the location count check, default false, used for 叛逆の堕天使, only works for target function
--- @field skip_location_count_check? boolean
--- Locked code, material code that can not use substitutes
--- @field locked_codes? integer[]
--- Add LOCATION_EXTRA and opponent mzone to EFFECT_EXTRA_FUSION_MATERIAL list, remove once core updated
...
...
@@ -2334,6 +2336,7 @@ function FusionSpell.CreateSummonEffect(c,opts)
local
fusion_spell_matfilter
=
opts
.
fusion_spell_matfilter
or
aux
.
TRUE
local
skip_summon_check
=
opts
.
skip_summon_check
or
false
local
skip_location_count_check
=
opts
.
skip_location_count_check
or
false
local
locked_codes
=
opts
.
locked_codes
or
{}
-- Ensure material operation fallbacks are present
table.insert
(
mat_operation_code_map
,{
[
LOCATION_GRAVE
]
=
FusionSpell
.
FUSION_OPERATION_BANISH
})
...
...
@@ -2361,7 +2364,8 @@ function FusionSpell.CreateSummonEffect(c,opts)
gc
,
fusion_spell_matfilter
,
skip_summon_check
,
skip_location_count_check
skip_location_count_check
,
locked_codes
))
e1
:
SetOperation
(
FusionSpell
.
GetSummonOperation
(
fusfilter
,
...
...
@@ -2379,7 +2383,8 @@ function FusionSpell.CreateSummonEffect(c,opts)
post_select_mat_opponent_location
,
gc
,
fusion_spell_matfilter
,
skip_summon_check
skip_summon_check
,
locked_codes
))
e1
:
SetDescription
(
1169
)
--- 融合召喚
return
e1
...
...
@@ -2402,6 +2407,7 @@ end
---@param fusion_spell_matfilter FUSION_SPELL_MATFILTER_FUNCTION a material must pass this to be legal as material come from fusion spell
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@param locked_codes integer[] Locked code, material code that can not use substitutes, used for 烙印融合
function
FusionSpell
.
GetSummonTarget
(
fusfilter
,
matfilter
,
...
...
@@ -2419,7 +2425,8 @@ function FusionSpell.GetSummonTarget(
gc
,
fusion_spell_matfilter
,
skip_summon_check
,
skip_location_count_check
skip_location_count_check
,
locked_codes
)
return
function
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
)
if
chk
==
0
then
...
...
@@ -2444,7 +2451,8 @@ function FusionSpell.GetSummonTarget(
gc
,
fusion_spell_matfilter
,
skip_summon_check
,
skip_location_count_check
)
skip_location_count_check
,
locked_codes
)
end
,
tp
,
fuslocation
,
0
,
1
,
nil
)
if
sg
==
true
then
...
...
@@ -2480,6 +2488,7 @@ end
---@param gc fun(e:Effect):Card|nil Function that returns a card that must be included in the fusion materials
---@param fusion_spell_matfilter FUSION_SPELL_MATFILTER_FUNCTION a material must pass this to be legal as material come from fusion spell
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param locked_codes integer[] Locked code, material code that can not use substitutes, used for 烙印融合
function
FusionSpell
.
GetSummonOperation
(
fusfilter
,
matfilter
,
...
...
@@ -2496,7 +2505,8 @@ function FusionSpell.GetSummonOperation(
post_select_mat_opponent_location
,
gc
,
fusion_spell_matfilter
,
skip_summon_check
skip_summon_check
,
locked_codes
)
return
function
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
local
tc
=
nil
...
...
@@ -2521,14 +2531,15 @@ function FusionSpell.GetSummonOperation(
gc
,
fusion_spell_matfilter
,
skip_summon_check
,
false
--[[skip_location_count_check]]
)
false
--[[skip_location_count_check]]
,
locked_codes
)
end
,
tp
,
fuslocation
,
0
,
nil
)
fusion_targets
:
Merge
(
sg
)
--- check for chain material targets
local
ce_sgs
=
{}
if
sumtype
&
SUMMON_TYPE_FUSION
~=
0
then
ce_sgs
=
FusionSpell
.
ListChainMaterialSummonTargets
(
e
,
tp
,
fusfilter
,
aux
.
NecroValleyFilter
(
matfilter
),
additional_fcheck
,
additional_fgoalcheck
,
fuslocation
,
sumtype
,
sumpos
,
gc
,
skip_summon_check
,
false
--[[skip_location_count_check]]
)
ce_sgs
=
FusionSpell
.
ListChainMaterialSummonTargets
(
e
,
tp
,
fusfilter
,
aux
.
NecroValleyFilter
(
matfilter
),
additional_fcheck
,
additional_fgoalcheck
,
fuslocation
,
sumtype
,
sumpos
,
gc
,
skip_summon_check
,
false
--[[skip_location_count_check]]
,
locked_codes
)
--- add chain material targets
for
_
,
ce_sg
in
pairs
(
ce_sgs
)
do
fusion_targets
:
Merge
(
ce_sg
)
...
...
@@ -2586,9 +2597,11 @@ function FusionSpell.GetSummonOperation(
e
,
mat_operation_code_map
)
aux
.
FGoalCheckAdditional
=
FusionSpell
.
GetFusionSpellFGoalCheckAdditionalFunction
(
additional_fgoalcheck
,
tp
,
tc
,
pre_select_mat_location
,
e
)
Fusion
.
LockedCodes
=
locked_codes
materials
=
Duel
.
SelectFusionMaterial
(
tp
,
tc
,
mg
,
gc
(
e
),
tp
)
aux
.
FCheckAdditional
=
nil
aux
.
FGoalCheckAdditional
=
nil
Fusion
.
LockedCodes
=
nil
else
--- use chain material effect
---@type function
...
...
@@ -2597,9 +2610,11 @@ function FusionSpell.GetSummonOperation(
assert
(
#
chain_mg
>
0
,
"we are trying to apply a chain material, but it has no possible material"
)
aux
.
FCheckAdditional
=
FusionSpell
.
GetFusionSpellFCheckAdditionalFunctionForChainMaterial
(
additional_fcheck
,
e
)
aux
.
FGoalCheckAdditional
=
FusionSpell
.
GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial
(
additional_fgoalcheck
,
e
)
Fusion
.
LockedCodes
=
locked_codes
materials
=
Duel
.
SelectFusionMaterial
(
tp
,
tc
,
chain_mg
,
gc
(
e
),
tp
)
aux
.
FCheckAdditional
=
nil
aux
.
FGoalCheckAdditional
=
nil
Fusion
.
LockedCodes
=
nil
end
end
...
...
@@ -2864,6 +2879,7 @@ end
---@param fusion_spell_matfilter fun(c:Card):boolean a material must pass this to be legal as material come from fusion spell
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@param locked_codes integer[] Locked code, material code that can not use substitutes, used for 烙印融合
function
FusionSpell
.
SummonTargetFilter
(
c
,
fusfilter
,
...
...
@@ -2882,7 +2898,8 @@ function FusionSpell.SummonTargetFilter(
gc
,
fusion_spell_matfilter
,
skip_summon_check
,
skip_location_count_check
)
skip_location_count_check
,
locked_codes
)
if
not
c
:
IsType
(
TYPE_FUSION
)
or
fusfilter
(
c
,
e
,
tp
)
==
false
then
return
false
end
...
...
@@ -2915,10 +2932,12 @@ function FusionSpell.SummonTargetFilter(
e
,
mat_operation_code_map
)
aux
.
FGoalCheckAdditional
=
FusionSpell
.
GetFusionSpellFGoalCheckAdditionalFunction
(
additional_fgoalcheck
,
tp
,
c
,
pre_select_mat_location
,
e
)
Fusion
.
LockedCodes
=
locked_codes
local
chkf
=
FusionSpell
.
GetCheckFieldPlayer
(
tp
,
skip_location_count_check
)
local
res
=
c
:
CheckFusionMaterial
(
mg
,
gc
(
e
),
chkf
)
aux
.
FCheckAdditional
=
nil
aux
.
FGoalCheckAdditional
=
nil
Fusion
.
LockedCodes
=
nil
return
res
end
...
...
@@ -2927,7 +2946,7 @@ end
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@return {[Effect]:Group} effect_targets_map Return a map of different chain material to potiential fusion targets
function
FusionSpell
.
ListChainMaterialSummonTargets
(
e
,
tp
,
fusfilter
,
matfilter
,
additional_fcheck
,
additional_fgoalcheck
,
fuslocation
,
sumtype
,
sumpos
,
gc
,
skip_summon_check
,
skip_location_count_check
)
function
FusionSpell
.
ListChainMaterialSummonTargets
(
e
,
tp
,
fusfilter
,
matfilter
,
additional_fcheck
,
additional_fgoalcheck
,
fuslocation
,
sumtype
,
sumpos
,
gc
,
skip_summon_check
,
skip_location_count_check
,
locked_codes
)
local
chain_material_effects
=
{
Duel
.
IsPlayerAffectedByEffect
(
tp
,
EFFECT_CHAIN_MATERIAL
)}
---@type {[Effect]:Group}
local
chain_material_targets
=
{}
...
...
@@ -2939,7 +2958,7 @@ function FusionSpell.ListChainMaterialSummonTargets(e,tp,fusfilter,matfilter,add
if
#
chain_mg
>
0
then
local
ce_fusfilter
=
ce
:
GetValue
()
local
ce_sg
=
Duel
.
GetMatchingGroup
(
function
(
c
)
return
FusionSpell
.
ChainMaterialSummonTargetFilter
(
c
,
aux
.
AND
(
ce_fusfilter
,
fusfilter
),
e
,
tp
,
chain_mg
,
additional_fcheck
,
additional_fgoalcheck
,
sumtype
,
sumpos
,
gc
,
skip_summon_check
,
skip_location_count_check
)
return
FusionSpell
.
ChainMaterialSummonTargetFilter
(
c
,
aux
.
AND
(
ce_fusfilter
,
fusfilter
),
e
,
tp
,
chain_mg
,
additional_fcheck
,
additional_fgoalcheck
,
sumtype
,
sumpos
,
gc
,
skip_summon_check
,
skip_location_count_check
,
locked_codes
)
end
,
tp
,
fuslocation
,
0
,
nil
)
if
#
ce_sg
>
0
then
chain_material_targets
[
ce
]
=
ce_sg
...
...
@@ -2982,7 +3001,7 @@ end
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@return boolean result Whether c could be fusion summoned by this chain material effect
function
FusionSpell
.
ChainMaterialSummonTargetFilter
(
c
,
fusfilter
,
e
,
tp
,
mg
,
additional_fcheck
,
additional_fgoalcheck
,
sumtype
,
sumpos
,
gc
,
skip_summon_check
,
skip_location_count_check
)
function
FusionSpell
.
ChainMaterialSummonTargetFilter
(
c
,
fusfilter
,
e
,
tp
,
mg
,
additional_fcheck
,
additional_fgoalcheck
,
sumtype
,
sumpos
,
gc
,
skip_summon_check
,
skip_location_count_check
,
locked_codes
)
if
not
c
:
IsType
(
TYPE_FUSION
)
or
fusfilter
(
c
,
e
,
tp
)
==
false
then
return
false
end
...
...
@@ -2993,10 +3012,12 @@ function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additio
end
aux
.
FCheckAdditional
=
FusionSpell
.
GetFusionSpellFCheckAdditionalFunctionForChainMaterial
(
additional_fcheck
,
e
)
aux
.
FGoalCheckAdditional
=
FusionSpell
.
GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial
(
additional_fgoalcheck
,
e
)
Fusion
.
LockedCodes
=
locked_codes
local
chkf
=
FusionSpell
.
GetCheckFieldPlayer
(
tp
,
skip_location_count_check
)
local
res
=
c
:
CheckFusionMaterial
(
mg
,
gc
(
e
),
chkf
)
aux
.
FCheckAdditional
=
nil
aux
.
FGoalCheckAdditional
=
nil
Fusion
.
LockedCodes
=
nil
return
res
end
...
...
@@ -3375,19 +3396,61 @@ end
Fusion
=
{}
function
Fusion
.
AddFusionProcedure
(
tc
,
opts
)
--- locked codes
Fusion
.
LockedCodes
=
nil
function
Fusion
.
AddFusionProcedure
(
c
,
opts
)
local
slots
=
opts
.
slots
local
mat_filter
=
opts
.
mat_filter
or
nil
local
fgoalcheck
=
opts
.
fgoalcheck
or
aux
.
TRUE
-- Register metadata
if
c
:
IsStatus
(
STATUS_COPYING_EFFECT
)
then
return
end
local
mat
=
{}
local
min_req
=
0
local
max_req
=
0
for
_
,
slot
in
ipairs
(
slots
)
do
if
slot
.
match_code
then
mat
[
slot
.
match_code
]
=
true
min_req
=
min_req
+
1
max_req
=
max_req
+
1
elseif
slot
.
match_codes
then
for
_
,
code
in
ipairs
(
slot
.
match_codes
)
do
mat
[
code
]
=
true
end
min_req
=
min_req
+
1
max_req
=
max_req
+
1
elseif
slot
.
filter
then
local
prev
=
slot
.
filter
slot
.
filter
=
function
(
mc
,
p_tc
)
return
prev
(
mc
,
p_tc
)
and
not
mc
:
IsHasEffect
(
6205579
)
end
min_req
=
min_req
+
1
max_req
=
max_req
+
1
elseif
slot
.
group
then
local
prev
=
slot
.
group
.
filter
slot
.
group
.
filter
=
function
(
mc
,
p_tc
)
return
prev
(
mc
,
p_tc
)
and
not
mc
:
IsHasEffect
(
6205579
)
end
min_req
=
min_req
+
slot
.
group
.
min
max_req
=
max_req
+
slot
.
group
.
max
end
end
local
mt
=
getmetatable
(
c
)
if
mt
.
material
==
nil
then
mt
.
material
=
mat
end
if
mt
.
material_count
==
nil
then
mt
.
material_count
=
{
min_req
,
max_req
}
end
for
index
,
_
in
pairs
(
mat
)
do
Auxiliary
.
AddCodeList
(
c
,
index
)
end
-- Register effect
local
e
=
Effect
.
CreateEffect
(
t
c
)
local
e
=
Effect
.
CreateEffect
(
c
)
e
:
SetType
(
EFFECT_TYPE_SINGLE
)
e
:
SetProperty
(
EFFECT_FLAG_CANNOT_DISABLE
+
EFFECT_FLAG_UNCOPYABLE
)
e
:
SetCode
(
EFFECT_FUSION_MATERIAL
)
e
:
SetCondition
(
Fusion
.
FusionCondition
(
t
c
,
slots
,
mat_filter
,
fgoalcheck
,
true
))
e
:
SetOperation
(
Fusion
.
FusionOperation
(
t
c
,
slots
,
mat_filter
,
fgoalcheck
))
e
:
SetCondition
(
Fusion
.
FusionCondition
(
c
,
slots
,
mat_filter
,
fgoalcheck
,
true
))
e
:
SetOperation
(
Fusion
.
FusionOperation
(
c
,
slots
,
mat_filter
,
fgoalcheck
))
e
:
SetDescription
(
1379
)
--- 启用扩展卡包调试模式
t
c
:
RegisterEffect
(
e
)
c
:
RegisterEffect
(
e
)
end
---@param allow_extras boolean whether to allow extra materials for checking propose
...
...
@@ -3433,6 +3496,31 @@ function Fusion.FusionCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,sele
return
false
end
-- prepare per-slot lock flags (lock only first matching slot per code or code list)
local
locked_slots
=
{}
if
Fusion
.
LockedCodes
then
for
_
,
code
in
ipairs
(
Fusion
.
LockedCodes
)
do
for
idx
,
slot
in
ipairs
(
single_slots
)
do
-- lock slot if its match_code equals code
if
slot
.
match_code
==
code
then
Debug
.
Message
(
string.format
(
"locked %d, slot %d"
,
code
,
idx
))
locked_slots
[
idx
]
=
true
break
end
-- lock slot if it's a multi-code slot containing code
if
slot
.
match_codes
then
for
_
,
c
in
ipairs
(
slot
.
match_codes
)
do
if
c
==
code
then
locked_slots
[
idx
]
=
true
break
end
end
if
locked_slots
[
idx
]
then
break
end
end
end
end
end
local
used
=
{}
local
sub_count
=
0
-- DFS assign slots
...
...
@@ -3635,16 +3723,19 @@ function Fusion.FusionCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,sele
if
not
used
[
idx
]
then
local
match
,
is_sub
=
Fusion
.
MatchSlot
(
mc
,
slot
,
tc
)
if
match
==
true
then
used
[
idx
]
=
true
local
prev_sub
=
sub_count
if
is_sub
then
sub_count
=
sub_count
+
1
end
if
sub_count
<=
1
and
dfs
(
i
+
1
)
then
return
true
end
used
[
idx
]
=
false
sub_count
=
prev_sub
-- skip sub material if slot is locked
if
not
(
is_sub
and
locked_slots
[
i
])
then
-- commit material
used
[
idx
]
=
true
local
prev_sub
=
sub_count
if
is_sub
then
sub_count
=
sub_count
+
1
end
if
sub_count
<=
1
and
dfs
(
i
+
1
)
then
return
true
end
-- backtrack
used
[
idx
]
=
false
sub_count
=
prev_sub
end
end
end
end
...
...
@@ -3655,28 +3746,28 @@ function Fusion.FusionCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,sele
end
--- Helper: check one card against a named slot
---@param
t
c Card
---@param
m
c Card
---@param slot table match_code|match_codes|allow_sub
---@param
handler
Card
---@param
tc
Card
---@return boolean match
---@return boolean is_sub
function
Fusion
.
MatchSlot
(
tc
,
slot
,
handler
)
function
Fusion
.
MatchSlot
(
mc
,
slot
,
tc
)
-- exact code match
if
slot
.
match_code
and
t
c
:
IsFusionCode
(
slot
.
match_code
)
then
if
slot
.
match_code
and
m
c
:
IsFusionCode
(
slot
.
match_code
)
then
return
true
,
false
end
-- any-of-codes
if
slot
.
match_codes
then
for
_
,
code
in
ipairs
(
slot
.
match_codes
)
do
if
t
c
:
IsFusionCode
(
code
)
then
if
m
c
:
IsFusionCode
(
code
)
then
return
true
,
false
end
end
end
-- filter
if
slot
.
filter
and
slot
.
filter
(
tc
)
then
return
true
,
false
end
if
slot
.
filter
and
slot
.
filter
(
mc
,
tc
)
then
return
true
,
false
end
-- generic substitute
if
slot
.
allow_sub
and
tc
:
CheckFusionSubstitute
(
handler
)
then
if
slot
.
allow_sub
and
mc
:
CheckFusionSubstitute
(
tc
)
then
return
true
,
true
end
return
false
,
false
...
...
@@ -3795,7 +3886,7 @@ function Fusion.Slot.Codes(codes,opts)
end
--- Create a slot for generic filter (no substitutes)
---@param filter fun(mc:Card):boolean
---@param filter fun(mc:Card
,tc:Card
):boolean
---@return table
function
Fusion
.
Slot
.
Filter
(
filter
)
return
{
...
...
@@ -3805,11 +3896,12 @@ function Fusion.Slot.Filter(filter)
end
--- Group slot (multi-card)
---@param opts {min?:number,max?:number,filter?:fun(mc:Card):boolean}
---@param opts {min?:number,max?:number,filter?:fun(mc:Card
,tc:Card
):boolean}
---@return table
function
Fusion
.
Slot
.
Group
(
opts
)
opts
.
min
=
opts
.
min
or
1
opts
.
max
=
opts
.
max
or
math.huge
opts
.
filter
=
opts
.
filter
or
aux
.
TRUE
return
{
group
=
opts
}
...
...
@@ -3818,9 +3910,9 @@ end
--- FindAllMapping
--- @param cards_sel Card[] currently picked materials
--- @param slots table[] your original slots spec
--- @param
handler
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)
function
Fusion
.
FindAllMappings
(
cards_sel
,
slots
,
handler
)
function
Fusion
.
FindAllMappings
(
cards_sel
,
slots
,
tc
)
-- Trackers
local
filled
=
{}
-- for single slots
local
group_assigned
=
{}
-- how many cards assigned so far to each group slot
...
...
@@ -3832,6 +3924,29 @@ function Fusion.FindAllMappings(cards_sel,slots,handler)
end
end
-- prepare locked_slots for this mapping
local
locked_slots
=
{}
if
Fusion
.
LockedCodes
then
for
_
,
code
in
ipairs
(
Fusion
.
LockedCodes
)
do
for
idx
,
slot
in
ipairs
(
slots
)
do
local
matched
=
false
if
slot
.
match_code
==
code
then
matched
=
true
elseif
slot
.
match_codes
then
for
_
,
c
in
ipairs
(
slot
.
match_codes
)
do
if
c
==
code
then
matched
=
true
break
end
end
end
if
matched
then
locked_slots
[
idx
]
=
true
break
end
end
end
end
local
all_maps
=
{}
local
mapping
=
{}
-- mapping[idx_in_cards_sel] = slot_index
...
...
@@ -3865,18 +3980,24 @@ function Fusion.FindAllMappings(cards_sel,slots,handler)
return
end
local
t
c
=
cards_sel
[
idx
]
local
m
c
=
cards_sel
[
idx
]
local
any_match
=
false
-- track if we managed to assign tc
-- 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
any_match
=
true
filled
[
i
]
=
true
mapping
[
idx
]
=
i
dfs
(
idx
+
1
)
filled
[
i
]
=
false
mapping
[
idx
]
=
nil
if
not
slot
.
group
and
not
filled
[
i
]
then
local
match
,
is_sub
=
Fusion
.
MatchSlot
(
mc
,
slot
,
tc
)
if
match
then
-- skip substitute if slot is locked
if
not
(
is_sub
and
locked_slots
[
i
])
then
any_match
=
true
filled
[
i
]
=
true
mapping
[
idx
]
=
i
dfs
(
idx
+
1
)
filled
[
i
]
=
false
mapping
[
idx
]
=
nil
end
end
end
end
...
...
@@ -3886,20 +4007,20 @@ function Fusion.FindAllMappings(cards_sel,slots,handler)
local
assigned
=
group_assigned
[
i
]
if
assigned
<
slot
.
group
.
max
then
-- base filter
if
not
slot
.
group
.
filter
or
slot
.
group
.
filter
(
tc
)
then
if
not
slot
.
group
.
filter
or
slot
.
group
.
filter
(
mc
,
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
)
local
v0
=
fn
(
mc
,
tc
)
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
)
mask
=
mask
&
fn
(
cards_sel
[
j
],
tc
)
if
mask
==
0
then
break
end
end
end
...
...
@@ -3912,7 +4033,7 @@ function Fusion.FindAllMappings(cards_sel,slots,handler)
for
j
=
1
,
idx
-
1
do
if
mapping
[
j
]
==
i
then
local
next_c
=
{}
for
_
,
k
in
ipairs
(
fn
(
cards_sel
[
j
],
handler
))
do
for
_
,
k
in
ipairs
(
fn
(
cards_sel
[
j
],
tc
))
do
if
common
[
k
]
then
next_c
[
k
]
=
true
end
end
common
=
next_c
...
...
@@ -4000,6 +4121,27 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc,
-- build the “leftover” slots list
local
rem_slots
=
{}
-- rebuild dynamic locks per mapping
local
old_locked
=
Fusion
.
LockedCodes
local
new_locked
=
{}
if
old_locked
then
for
_
,
code
in
ipairs
(
old_locked
)
do
-- find slot index for this code
for
j
,
slot
in
ipairs
(
slots
)
do
local
matches
=
(
slot
.
match_code
==
code
or
(
slot
.
match_codes
and
(
function
()
for
_
,
c
in
ipairs
(
slot
.
match_codes
)
do
if
c
==
code
then
return
true
end
end
;
return
false
end
)()))
if
matches
then
-- if that slot was not filled, keep lock
if
not
filled_single
[
j
]
then
table.insert
(
new_locked
,
code
)
end
break
end
end
end
end
Fusion
.
LockedCodes
=
new_locked
for
i
,
slot
in
ipairs
(
slots
)
do
if
slot
.
group
then
local
need
=
group_need
[
i
]
or
0
...
...
@@ -4046,14 +4188,14 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc,
end
-- wrap the existing filter so it also enforces all has_same overlaps
local
prev
=
new_filter
new_filter
=
function
(
mc
)
new_filter
=
function
(
mc
,
p_tc
)
-- original criteria
if
prev
and
not
prev
(
mc
)
then
if
prev
and
not
prev
(
mc
,
p_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
(
mc
,
tc
)
local
v
=
fn
(
mc
,
p_
tc
)
if
type
(
overlap
)
==
"number"
then
-- bitmask path
if
(
overlap
&
v
)
==
0
then
...
...
@@ -4097,11 +4239,13 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc,
end
end
-- if nothing remains, we
already succeed
, check fgoal
-- if nothing remains, we
exhausted slots
, check fgoal
if
#
rem_slots
==
0
then
if
(
fgoalcheck
==
nil
or
fgoalcheck
(
sel
)
==
true
)
and
(
aux
.
FGoalCheckAdditional
==
nil
or
aux
.
FGoalCheckAdditional
(
tc
:
GetOwner
(),
sel
,
tc
))
then
Fusion
.
LockedCodes
=
old_locked
return
true
else
Fusion
.
LockedCodes
=
old_locked
return
false
end
end
...
...
@@ -4109,8 +4253,10 @@ function Fusion.CanCompleteFromMappings(e,sel,eg,slots,mat_filter,fgoalcheck,tc,
-- delegate to FusionCondition (allow_extras = true)
local
search_cond
=
Fusion
.
FusionCondition
(
tc
,
rem_slots
,
mat_filter
,
fgoalcheck
,
true
,
sel
)
if
search_cond
(
e
,
rem_pool
,
gc
,
chkf
)
then
Fusion
.
LockedCodes
=
old_locked
return
true
end
Fusion
.
LockedCodes
=
old_locked
end
return
false
...
...
@@ -4201,18 +4347,18 @@ end
--- Builds a new filter that enforces both the original filter *and*
--- “none of this card’s keys are in used_keys.”
--- @param orig_filter fun(Card):boolean? (may be nil)
--- @param orig_filter fun(
mc:Card,tc:
Card):boolean? (may be nil)
--- @param key_func fun(Card):any[]
--- @param used_keys table as returned above
--- @return fun(Card):boolean
--- @return fun(
mc:Card,tc:
Card):boolean
function
Fusion
.
MakeExcludeFilter
(
orig_filter
,
key_func
,
used_keys
)
return
function
(
tc
)
return
function
(
mc
,
tc
)
-- first, pass the original criteria
if
orig_filter
and
not
orig_filter
(
tc
)
then
if
orig_filter
and
not
orig_filter
(
mc
,
tc
)
then
return
false
end
-- then ensure no key overlaps
for
_
,
k
in
ipairs
(
key_func
(
t
c
))
do
for
_
,
k
in
ipairs
(
key_func
(
m
c
))
do
if
used_keys
[
k
]
then
return
false
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment