Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
ygopro-222DIY-cards
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
0
Merge Requests
0
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
alstroemeria-silentlove
ygopro-222DIY-cards
Commits
14515cb1
Commit
14515cb1
authored
Jul 17, 2025
by
Satty
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix
parent
d3283871
Pipeline
#39131
failed with stages
in 8 minutes and 12 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
2200 additions
and
862 deletions
+2200
-862
expansions/script/c15000358.lua
expansions/script/c15000358.lua
+2
-3
expansions/script/c16110038.lua
expansions/script/c16110038.lua
+1
-1
expansions/script/c20000000.lua
expansions/script/c20000000.lua
+819
-405
expansions/script/c20099997.lua
expansions/script/c20099997.lua
+385
-92
expansions/script/c20099998.lua
expansions/script/c20099998.lua
+957
-344
expansions/script/c20099999.lua
expansions/script/c20099999.lua
+36
-17
No files found.
expansions/script/c15000358.lua
View file @
14515cb1
...
...
@@ -24,7 +24,7 @@ function cm.initial_effect(c)
c
:
RegisterEffect
(
e1
)
end
function
cm
.
spcfilter
(
c
)
return
c
:
IsRace
(
RACE_INSECT
)
and
c
:
IsAbleToDeckOrExtraAsCost
()
return
c
:
IsRace
(
RACE_INSECT
)
and
c
:
IsAbleToDeckOrExtraAsCost
()
and
c
:
IsFaceup
()
end
function
cm
.
spcon
(
e
,
c
)
if
c
==
nil
then
return
true
end
...
...
@@ -35,7 +35,6 @@ end
function
cm
.
spop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
c
)
Duel
.
Hint
(
HINT_SELECTMSG
,
tp
,
HINTMSG_TODECK
)
local
g
=
Duel
.
SelectMatchingCard
(
tp
,
cm
.
spcfilter
,
tp
,
LOCATION_GRAVE
+
LOCATION_REMOVED
,
0
,
1
,
2
,
c
)
Duel
.
ConfirmCards
(
1
-
tp
,
g
)
Duel
.
ConfirmCards
(
tp
,
g
)
Duel
.
HintSelection
(
g
)
Duel
.
SendtoDeck
(
g
,
nil
,
2
,
REASON_COST
)
end
\ No newline at end of file
expansions/script/c16110038.lua
View file @
14515cb1
...
...
@@ -59,7 +59,7 @@ function cm.sfilter(c)
return
c
:
IsSummonable
(
true
,
nil
,
1
)
and
c
:
IsSetCard
(
0xcc5
)
end
function
cm
.
con
(
e
,
tp
)
return
(
Duel
.
GetCurrentPhase
()
==
PHASE_MAIN1
and
Duel
.
GetCurrentPhase
()
==
PHASE_MAIN2
)
and
Duel
.
IsExistingMatchingCard
(
cm
.
sfilter
,
tp
,
LOCATION_HAND
,
0
,
1
,
nil
)
return
(
Duel
.
GetCurrentPhase
()
==
PHASE_MAIN1
or
Duel
.
GetCurrentPhase
()
==
PHASE_MAIN2
)
and
Duel
.
IsExistingMatchingCard
(
cm
.
sfilter
,
tp
,
LOCATION_HAND
,
0
,
1
,
nil
)
end
function
cm
.
op1
(
e
,
tp
)
Duel
.
Hint
(
HINT_SELECTMSG
,
tp
,
HINTMSG_SUMMON
)
...
...
expansions/script/c20000000.lua
View file @
14515cb1
dofile
(
"expansions/script/c20099997.lua"
)
if
fuef
then
return
end
--2025/4/25
fuef
=
{
DebugMode
=
false
,
-- 调试模式
StepReg
=
false
-- 每次 Reload 皆印出 Reg
}
if
fuef
then
return
end
--2025/7/16
fuef
=
{
}
fuef
.
__index
=
fuef
---------------------------------------------------------------- Standard Register
-- no cod
function
fuef
.
I
(
_owner
,
_handler
,
_ignore
)
if
_owner
==
false
then
_handler
,
_owner
=
false
end
-- _owner is _handler (use in FG
return
fuef
:
Creat
(
"I"
,
nil
,
_owner
,
_handler
,
_ignore
)
end
function
fuef
.
FG
(
_owner
,
_obj
,
_handler
,
_ignore
)
-- ex: cm.e3 = fuef.FG("e1+e2")
if
type
(
_owner
)
~=
"userdata"
then
_obj
,
_owner
=
_owner
end
return
fuef
:
Creat
(
"F+G"
,
nil
,
_owner
,
_handler
,
_ignore
):
OBJ
(
_obj
)
end
-- need cod
for
i
,
typs
in
ipairs
({
"S,F,E,S+C,F+C,E+C,F+TO,F+TF,S+TO,S+TF,X"
,
"A,QO,QF"
})
do
for
_
,
typ
in
typs
:
ForCut
(
"typ_reg_1"
)
do
fuef
.
DebugMode
=
false
-- 调试模式
dofile
(
"expansions/script/c20099997.lua"
)
----------------------------------------------------------------
--- 建立一个 IGNITION 的 fuef
-- @param owner Card|Effect|nil 效果的持有者(若为 nil,仅建立效果表;需后续补设)
-- @param target boolean|Card|Group|player 注册目标
-- @param force boolean 是否强制注册
-- @return fuef 新创建的效果表实例
function
fuef
.
I
(
owner
,
target
,
force
)
local
log
=
fudf
.
StartLog
(
0
,
"fuef.I"
,
owner
,
target
,
force
)
return
fuef
.
New
(
log
,
"I"
,
nil
,
owner
,
target
,
force
)
end
--- 建立一个 FIELD + GRANT 的 fuef
-- @param owner Card|Effect|nil 效果的持有者(若为 obj,仅建立效果表;需后续补设)
-- @param obj Effect|fuef|string 要赋予的效果(effect object)
-- @param target boolean|Card|Group|player 注册目标
-- @param force boolean 是否强制注册
-- @return fuef 新创建的效果表实例
function
fuef
.
FG
(
owner
,
obj
,
target
,
force
)
local
log
=
fudf
.
StartLog
(
0
,
"fuef.FG"
,
owner
,
obj
,
target
,
force
)
local
is_obj
=
pcall
(
fusf
.
CheckTypes
,
owner
,
"string/fuef/Effect"
)
if
is_obj
then
owner
,
obj
,
target
,
force
=
nil
,
owner
,
obj
,
target
end
return
fuef
.
New
(
log
,
"F+G"
,
nil
,
owner
,
target
,
force
):
OBJ
(
obj
)
end
--- 建立剩余需要 cod 的 fuef
for
i
,
typs
in
ipairs
{
"S,F,E,S+C,F+C,E+C,F+TO,F+TF,S+TO,S+TF,X"
,
"A,QO,QF"
}
do
for
_
,
typ
in
typs
:
ForCut
()
do
local
name
=
typ
:
gsub
(
"+"
,
""
)
fuef
[
name
]
=
function
(
_owner
,
_cod
,
_handler
,
_ignore
)
if
type
(
_owner
)
~=
"userdata"
then
_cod
,
_handler
,
_owner
=
_owner
,
_cod
end
-- _owner is cod (Noc
if
i
==
2
then
_cod
=
_cod
or
"FC"
end
-- A,QO,QF
return
fuef
:
Creat
(
typ
,
_cod
,
_owner
,
_handler
,
_ignore
)
fuef
[
name
]
=
function
(
owner
,
cod
,
target
,
force
)
local
log
=
fudf
.
StartLog
(
0
,
"fuef."
..
name
,
owner
,
cod
,
target
,
force
)
local
is_cod
=
pcall
(
fusf
.
CheckTypes
,
owner
,
"string/number"
)
if
is_cod
then
owner
,
cod
,
target
,
force
=
nil
,
owner
,
cod
,
target
end
if
i
==
2
then
cod
=
cod
or
"FC"
end
-- A,QO,QF
return
fuef
.
New
(
log
,
typ
,
cod
,
owner
,
target
,
force
)
end
end
end
---------------------------------------------------------------- procedure Register (just Noc
function
fuef
.
Proc_XYZ
(
cf
,
gf
,
min
,
max
,
ex_loc
)
min
,
max
=
min
or
1
,
max
or
99
return
fuef
.
F
(
EFFECT_SPSUMMON_PROC
):
DES
(
"XYZ"
):
PRO
(
"OE"
):
RAN
(
"E"
):
Func
(
"XYZ,PX_con(%1,%2,%3,%4,%5),PX_tg(%1,%2,%3,%4,%5),XyzLevelFreeOperation()"
,
cf
,
gf
,
min
,
max
,
ex_loc
)
end
function
fuef
.
PX_g_goal
(
g
,
tp
,
xyzc
,
gf
)
---------------------------------------------------------------- XYZ Proc
function
fuef
.
ProcXyzLv
(
lv
,
cf
,
min
,
max
)
fusf
.
CheckArgType
(
"fuef.ProcXyzLv"
,
1
,
lv
,
"number"
)
fusf
.
CheckArgType
(
"fuef.ProcXyzLv"
,
2
,
cf
,
"nil/function"
)
local
lvf
=
fucf
.
MakeCardFilter
(
"IsLv"
,
lv
)
local
_cf
=
function
(
c
,
xyzc
)
return
lvf
(
c
)
and
(
not
cf
or
cf
(
c
,
xyzc
))
end
return
fuef
.
ProcXyz
(
_cf
,
nil
,
min
,
max
)
end
function
fuef
.
ProcXyzAlter
(
cf
,
gf
,
min
,
max
,
ex_op
,
ex_cf
)
return
fuef
.
ProcXyz
(
cf
,
gf
,
min
,
max
,
ex_op
,
ex_cf
):
Lab
(
1
)
end
function
fuef
.
ProcXyz
(
cf
,
gf
,
min
,
max
,
ex_op
,
ex_cf
)
fusf
.
CheckArgType
(
"fuef.ProcXyz"
,
1
,
cf
,
"nil/string/function"
)
fusf
.
CheckArgType
(
"fuef.ProcXyz"
,
2
,
gf
,
"nil/string/function"
)
local
_
,
min
=
fusf
.
CheckArgType
(
"fuef.ProcXyz"
,
3
,
min
or
2
,
"number"
)
local
_
,
max
=
fusf
.
CheckArgType
(
"fuef.ProcXyz"
,
4
,
max
or
min
,
"number"
)
fusf
.
CheckArgType
(
"fuef.ProcXyz"
,
5
,
ex_op
,
"nil/string/function"
)
fusf
.
CheckArgType
(
"fuef.ProcXyz"
,
6
,
ex_cf
,
"nil/string/function"
)
local
e
=
fuef
.
F
(
EFFECT_SPSUMMON_PROC
):
Des
(
1165
):
Pro
(
"OE"
):
Ran
(
"E"
):
Val
(
"XYZ"
)
e
:
Con
(
"PX_con"
,
cf
,
gf
,
min
,
max
,
ex_op
,
ex_cf
)
e
:
Tg
(
"PX_tg"
,
cf
,
gf
,
min
,
max
,
ex_op
,
ex_cf
)
return
e
:
Op
(
aux
.
XyzLevelFreeOperation
())
end
function
fuef
.
PX_goal
(
g
,
tp
,
xyzc
,
gf
)
return
(
not
gf
or
gf
(
g
,
tp
,
xyzc
))
and
Duel
.
GetLocationCountFromEx
(
tp
,
tp
,
g
,
xyzc
)
>
0
end
function
fuef
.
PX_con
(
cf
,
gf
,
minc
,
maxc
,
ex_
loc
)
function
fuef
.
PX_con
(
cf
,
gf
,
minc
,
maxc
,
ex_
op
,
ex_cf
)
return
function
(
e
,
c
,
og
,
min
,
max
)
if
c
==
nil
then
return
true
end
if
c
:
IsType
(
TYPE_PENDULUM
)
and
c
:
IsFaceup
()
then
return
false
end
local
tp
,
minc
,
maxc
=
c
:
GetControler
(),
math.max
(
minc
,
min
or
minc
),
math.min
(
maxc
,
max
or
maxc
)
local
minc
,
maxc
=
math.max
(
minc
,
min
or
minc
),
math.min
(
maxc
,
max
or
maxc
)
if
maxc
<
minc
then
return
false
end
local
catch
=
fusf
.
MakeFuncCatch
(
e
)
local
tp
=
c
:
GetControler
()
if
ex_op
then
if
type
(
ex_op
)
==
"string"
then
ex_op
=
fusf
.
FindFuncCatch
(
catch
,
"ex_op"
,
ex_op
)
end
if
not
ex_op
(
e
,
c
,
tp
,
0
)
then
return
false
end
end
if
cf
and
type
(
cf
)
==
"string"
then
cf
=
fusf
.
FindFuncCatch
(
catch
,
"cf"
,
cf
)
end
local
mg
=
fugf
.
Filter
(
og
or
fugf
.
Get
(
tp
,
"M"
),
"XyzLevelFreeFilter"
,
{
c
,
cf
})
if
ex_loc
then
mg
=
mg
+
fugf
.
GetFilter
(
tp
,
ex_loc
,
"XyzLevelFreeFilter"
,
{
c
,
cf
})
end
local
sg
=
Duel
.
GetMustMaterial
(
tp
,
EFFECT_MUST_BE_XMATERIAL
)
if
ex_cf
then
local
mg2
=
fugf
.
GetFilter
(
tp
,
"A"
,
"IsTyp/IsCanBeXyzMaterial"
,
"S/T,%1"
,
nil
,
c
)
-
mg
if
type
(
ex_cf
)
==
"string"
then
ex_cf
=
fusf
.
FindFuncCatch
(
catch
,
"ex_cf"
,
ex_cf
)
end
mg
=
mg
+
fugf
.
Filter
(
mg2
,
ex_cf
,
c
)
end
local
sg
=
Duel
.
GetMustMaterial
(
tp
,
EFFECT_MUST_BE_XMATERIAL
)
if
#
mg
>
#
(
mg
+
sg
)
then
return
false
end
Duel
.
SetSelectedCard
(
sg
)
Auxiliary
.
GCheckAdditional
=
Auxiliary
.
TuneMagicianCheckAdditionalX
(
EFFECT_TUNE_MAGICIAN_X
)
local
res
=
mg
:
CheckSubGroup
(
fuef
.
PX_g_goal
,
minc
,
maxc
,
tp
,
c
,
gf
)
if
gf
and
type
(
gf
)
==
"string"
then
gf
=
fusf
.
FindFuncCatch
(
catch
,
"gf"
,
gf
)
end
local
res
=
mg
:
CheckSubGroup
(
fuef
.
PX_goal
,
minc
,
maxc
,
tp
,
c
,
gf
)
Auxiliary
.
GCheckAdditional
=
nil
return
res
end
end
function
fuef
.
PX_tg
(
cf
,
gf
,
minc
,
maxc
,
ex_
loc
)
function
fuef
.
PX_tg
(
cf
,
gf
,
minc
,
maxc
,
ex_
op
,
ex_cf
)
return
function
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
,
c
,
og
,
min
,
max
)
if
og
and
not
min
then
return
true
end
minc
,
maxc
=
math.max
(
minc
,
min
or
minc
),
math.min
(
maxc
,
max
or
maxc
)
local
catch
=
fusf
.
MakeFuncCatch
(
e
)
if
cf
and
type
(
cf
)
==
"string"
then
cf
=
fusf
.
FindFuncCatch
(
catch
,
"cf"
,
cf
)
end
local
mg
=
fugf
.
Filter
(
og
or
fugf
.
Get
(
tp
,
"M"
),
"XyzLevelFreeFilter"
,
{
c
,
cf
})
if
ex_loc
then
mg
=
mg
+
fugf
.
GetFilter
(
tp
,
ex_loc
,
"XyzLevelFreeFilter"
,
{
c
,
cf
})
end
if
ex_cf
then
local
mg2
=
fugf
.
GetFilter
(
tp
,
"A"
,
"IsTyp/IsCanBeXyzMaterial"
,
"S/T,%1"
,
nil
,
c
)
-
mg
if
type
(
ex_cf
)
==
"string"
then
ex_cf
=
fusf
.
FindFuncCatch
(
catch
,
"ex_cf"
,
ex_cf
)
end
mg
=
mg
+
fugf
.
Filter
(
mg2
,
ex_cf
,
c
)
end
Duel
.
SetSelectedCard
(
Duel
.
GetMustMaterial
(
tp
,
EFFECT_MUST_BE_XMATERIAL
))
Duel
.
Hint
(
HINT_SELECTMSG
,
tp
,
HINTMSG_XMATERIAL
)
Auxiliary
.
GCheckAdditional
=
Auxiliary
.
TuneMagicianCheckAdditionalX
(
EFFECT_TUNE_MAGICIAN_X
)
mg
=
mg
:
SelectSubGroup
(
tp
,
fuef
.
PX_g_goal
,
Duel
.
IsSummonCancelable
(),
minc
,
maxc
,
tp
,
c
,
gf
)
if
gf
and
type
(
gf
)
==
"string"
then
gf
=
fusf
.
FindFuncCatch
(
catch
,
"gf"
,
gf
)
end
mg
=
mg
:
SelectSubGroup
(
tp
,
fuef
.
PX_goal
,
Duel
.
IsSummonCancelable
(),
minc
,
maxc
,
tp
,
c
,
gf
)
Auxiliary
.
GCheckAdditional
=
nil
if
ex_op
then
if
type
(
ex_op
)
==
"string"
then
ex_op
=
fusf
.
FindFuncCatch
(
catch
,
"ex_op"
,
ex_op
)
end
ex_op
(
e
,
c
,
tp
,
1
)
end
if
not
mg
or
#
mg
==
0
then
return
false
end
mg
:
KeepAlive
()
e
:
SetLabelObject
(
mg
)
return
true
end
end
---------------------------------------------------------------- fuef()
function
fuef
:
__call
(
_cod
,
_handler
,
_ignore
)
fusf
.
Debug
(
""
)
fusf
.
Debug
(
"__call("
..
fusf
.
ValToDebug
(
_cod
,
_handler
,
_ignore
)
..
")"
)
-- _cod is owner (Creat and Register Noc
if
type
(
_cod
)
==
"userdata"
then
return
self
:
CreatNoc
(
_cod
,
_handler
,
_ignore
)
end
-- Creat and Clone all key
local
CE
=
setmetatable
({
},
fuef
)
local
keys
=
"typ,cod,des,cat,pro,ran,tran,ctl,val,con,cos,tg,op,res,lab,obj,handler"
for
_
,
_key
in
keys
:
ForCut
(
"fuef:__call"
)
do
CE
[
_key
]
=
self
[
_key
]
or
nil
---------------------------------------------------------------- local
--- 修正效果建立时的三个参数:赋予者(owner)、被赋予者(target)、是否强制注册(force)
-- 根据参数类型推断调用者的意图,并统一为标准形式返回,用于 fuef.New
-- @param owner Card/Effect/player/boolean/nil - 效果赋予者;若为 player/boolean/nil,将视为 target
-- @param target Card/Group/player/boolean/nil - 效果被赋予对象;若为 true 表示强制注册
-- @param force boolean/nil - 是否强制注册;预设为 false
-- @return owner(Card/Effect/nil), target(Card/Group/player/nil), force(boolean)
local
function
FixEffectAssignArgs
(
owner
,
target
,
force
)
if
owner
==
false
or
owner
==
0
or
owner
==
1
then
owner
,
target
=
nil
,
owner
else
fusf
.
CheckTypes
(
owner
,
"nil/Card/Effect"
)
end
if
target
==
true
then
target
,
force
=
nil
,
true
elseif
target
~=
false
then
local
typ
=
fusf
.
CheckTypes
(
target
,
"nil/Card/Group/table/player"
)
if
typ
==
"Card"
or
typ
==
"Group"
then
target
=
fusf
.
ToGroupTable
(
target
)
end
end
force
=
fusf
.
CheckType
(
force
or
false
,
"boolean"
)
return
owner
,
target
,
force
end
--- 检查 val 是否为有效的 value 格式,用于 fuef:Func
-- @param val any 欲检查的值
-- @param val_typ string 值的型别
-- @return boolean 是否符合格式
local
function
MatchValFormat
(
val
,
val_typ
)
if
val_typ
~=
"string"
then
return
true
end
if
val
:
match
(
"%,"
)
then
return
false
end
return
tonumber
(
val
)
or
fucs
.
val
[
val
]
or
(
val
:
sub
(
-
4
,
-
2
):
lower
()
==
"val"
)
end
----------------------------------------------------------------
--- 建立一个新的效果表(fuef 物件),初始化基本栏位
--
-- - 若 `owner` 为 nil,仅建立效果表而不创建 Effect 实体,需后续呼叫 `:InitSetOwner(owner)` 补足。
-- - 若 `owner` 为 Effect 或 Card,则立即创建 Effect 并进行注册。
----- 建立一个新的效果表(fuef 物件),初始化基本栏位
--
-- - 若 `owner` 为 nil,仅建立效果表而不创建 Effect 实体,需后续呼叫 `:InitSetOwner(owner)` 补足。
-- - 若 `owner` 为 Effect 或 Card,则立即创建 Effect 并进行注册。
--
-- @param log 日志对象或层级(用于调试记录)
-- @param typ string|number 效果类型(支援常数名或数值,将转换为 EFFECT_TYPE_* 常数)
-- @param cod string|number|nil 效果代码(支援常数名或数值,将转换为 EVENT_* 常数,可为 nil)
-- @param owner nil|Effect|Card 效果实体的持有者(若为 nil,仅建立表,不创建实体)
-- @param target boolean|Card|Group|player 注册目标(传入至 Reg 中),若为 boolean 则视为 force
-- @param force boolean 是否强制注册,跳过效果限制检查
-- @return table fuef 物件(含 typ, cod, handler, force 等栏位)
-- @raise 若 owner 非 nil 且无法转为卡片时,建立 Effect 可能触发错误
function
fuef
.
New
(
log
,
typ
,
cod
,
owner
,
target
,
force
)
local
log
=
fudf
.
StartLog
(
log
,
"fuef.New"
,
typ
,
cod
,
owner
,
target
,
force
)
local
E
=
setmetatable
({},
fuef
)
E
.
typ
=
fusf
.
ParseConstantKey
(
"etyp"
,
typ
)
log
:
Info
(
"set self.typ : "
..
fusf
.
CutHex
(
E
.
typ
))
if
cod
then
E
.
cod
=
fusf
.
ParseConstantKey
(
"cod"
,
cod
)
log
:
Info
(
"set self.cod : "
..
E
.
cod
)
end
owner
,
target
,
force
=
FixEffectAssignArgs
(
owner
,
target
,
force
)
E
.
handler
=
target
log
:
Info
(
"set handler : "
..
fusf
.
Type
(
target
))
E
.
force
=
force
log
:
Info
(
"set force : "
..
tostring
(
force
))
log
:
Info
(
"has owner : "
..
tostring
(
not
not
owner
))
if
not
owner
then
return
E
end
E
.
e
=
Effect
.
CreateEffect
(
fusf
.
ToCard
(
owner
))
log
:
Info
(
"set self.e"
)
E
.
e
:
SetType
(
E
.
typ
)
log
:
Info
(
"self.e SetType : "
..
fusf
.
CutHex
(
E
.
typ
))
if
E
.
cod
then
E
.
e
:
SetCode
(
E
.
cod
)
log
:
Info
(
"self.e SetCode : "
..
E
.
cod
)
end
-- Cover _cod
if
CE
.
typ
==
EFFECT_TYPE_FIELD
+
EFFECT_TYPE_GRANT
then
CE
:
OBJ
(
_cod
)
elseif
_cod
then
CE
.
cod
=
fusf
.
Get_Constant
(
"cod"
,
_cod
)
return
E
:
Reg
(
log
)
end
-- 注册 fuef 给 self.handler, 没有则注册给 owner
-- @param log 日志对象或层级(用于调试记录)
-- @return table 返回调用者 self,支持链式调用
function
fuef
:
Reg
(
log
,
target
,
force
)
if
self
.
isinit
then
return
self
end
local
log
=
fudf
.
StartLog
(
log
,
"fuef:Reg"
)
if
self
.
handler
==
false
then
log
:
Info
(
"no RegisterEffect"
)
self
.
handler
=
false
return
self
end
local
tg_typ
=
fusf
.
CheckTypes
(
self
.
handler
,
"nil/table/player"
)
if
tg_typ
==
"player"
then
log
:
Info
(
"RegisterEffect to player"
)
Duel
.
RegisterEffect
(
self
.
e
,
self
.
handler
)
return
self
elseif
tg_typ
==
"nil"
then
self
.
handler
=
{
self
.
e
:
GetOwner
()
}
log
:
Info
(
"set self.handler is owner"
)
end
-- Clone and return Clone
if
self
.
e
then
CE
.
e
=
self
.
e
:
Clone
()
-- Set Key and Register Effect
return
CE
:
SetKey
():
Reg
(
_handler
,
_ignore
)
if
self
.
force
==
nil
then
self
.
force
=
false
log
:
Info
(
"set self.force is false"
)
end
-- Clone Noc (
CE
.
pre
=
self
self
.
aft
=
CE
return
CE
end
--------------------------------------------------------------------------
-- Creat and Register Effect
function
fuef
:
Creat
(
_typ
,
_cod
,
_owner
,
_handler
,
_ignore
)
fusf
.
Debug
(
""
)
fusf
.
Debug
(
"Creat("
..
fusf
.
ValToDebug
(
fusf
.
CutHex
(
_typ
),
_cod
,
_owner
,
_handler
,
_ignore
)
..
")"
)
local
E
=
setmetatable
({
},
fuef
)
-- Set type and code and handler
E
.
typ
=
fusf
.
Get_Constant
(
"etyp"
,
_typ
)
E
.
cod
=
fusf
.
Get_Constant
(
"cod"
,
_cod
)
E
.
handler
=
_handler
-- use in no owner (Creat and Register in __call
if
not
_owner
then
return
E
end
-- Create Effect
E
.
e
=
Effect
.
CreateEffect
(
fusf
.
ToCard
(
_owner
))
-- Set type and code
if
_typ
then
E
.
e
:
SetType
(
E
.
typ
)
end
if
_cod
then
E
.
e
:
SetCode
(
E
.
cod
)
end
return
E
:
Reg
(
_handler
,
_ignore
)
end
function
fuef
:
CreatNoc
(
_owner
,
_handler
,
_ignore
)
fusf
.
Debug
(
"CreatNoc("
..
fusf
.
ValToDebug
(
_owner
,
_handler
,
_ignore
)
..
")"
)
local
rg
=
self
.
handler
local
fc
=
rg
[
1
]
fc
:
RegisterEffect
(
self
.
e
,
self
.
force
)
if
#
rg
>
1
then
self
.
clones
=
{
}
for
i
=
2
,
#
rg
do
local
e
=
self
.
e
:
Clone
()
table.insert
(
self
.
clones
,
e
)
local
c
=
rg
[
i
]
c
:
RegisterEffect
(
e
,
self
.
force
)
end
end
log
:
Info
(
"RegisterEffect to "
..
(
#
rg
)
..
" Card"
)
return
self
end
--- 支援语法糖:fuef物件可直接以 () 调用以复制自身
-- 等同于 self:Clone(...)
function
fuef
:
__call
(
cod
,
target
,
force
)
return
self
:
Clone
(
cod
,
target
,
force
)
end
--- 复制当前 fuef 效果对象,可用于复制已有效果结构
-- @param cod string|number|fuef 替换的 cod, 赋予效果会将 cod 放到 OBJ
-- @param target 注册目标,同 Reg 函数
-- @param force 是否强制注册,同 Reg 函数
-- @return table 新的 fuef 对象,可链式调用
-- @raise cod 为 number 且用于 GRANT 类型时抛错;self.e 类型不正确时报错
function
fuef
:
Clone
(
cod
,
target
,
force
)
local
log
=
fudf
.
StartLog
(
0
,
"fuef:Clone"
,
cod
,
target
,
force
)
local
cod_typ
=
fusf
.
CheckArgType
(
"Clone"
,
1
,
cod
,
"string/number/fuef"
)
local
E
=
setmetatable
({},
fuef
)
log
:
Info
(
"try Clone All key"
)
local
keys
=
"typ,des,cat,pro,ran,tran,ctl,val,con,cos,tg,op,func,res,lab,obj,pl,handler,force"
for
_
,
key
in
keys
:
ForCut
()
do
E
[
key
]
=
self
[
key
]
or
nil
end
log
:
Info
(
"check self.typ is F+G"
)
if
E
.
typ
==
EFFECT_TYPE_FIELD
+
EFFECT_TYPE_GRANT
then
E
:
OBJ
(
cod
)
else
E
.
cod
=
fusf
.
ParseConstantKey
(
"cod"
,
cod
)
log
:
Info
(
"set self.cod : "
..
E
.
cod
)
end
local
e_typ
,
e
=
fusf
.
CheckTypes
(
self
.
e
,
"nil/Effect"
)
if
e_typ
==
"Effect"
then
log
:
Info
(
"Clone Effect E"
)
E
.
e
=
e
:
Clone
()
local
_
,
target
,
force
=
FixEffectAssignArgs
(
nil
,
target
,
force
)
if
target
then
E
.
handler
=
target
log
:
Info
(
"set E.handler : "
..
fusf
.
Type
(
target
))
end
E
.
force
=
force
log
:
Info
(
"set E.force : "
..
tostring
(
force
))
E
.
depth
=
log
.
depth
return
E
:
SetKey
(
log
):
Reg
(
log
)
end
E
.
pre
=
self
self
.
aft
=
E
log
:
Info
(
"set E.pre and self.aft"
)
return
E
end
--- 初始化 fuef 链条的 Effect 实体,并设置所有字段属性
--
-- - 本方法用于延迟注册效果表(fuef),在 `initial_effect` 中设定持有者(owner)并依序初始化整条链。
-- - 链的起点是最早创建的 fuef(无 pre),终点为当前对象或后续的 aft。
-- - 每个节点会调用 `fuef.New` 创建 Effect 实体,依照字段依序设置属性(des、cat、val 等)。
-- - 所有链条节点都会生成独立实体效果,并注册(呼叫 `:Reg()`)。
--
-- ⚠ 若创建时未传入 owner,此函数为唯一可创建 Effect 实体的注册点。
--
-- @param name string 名称(用于日志打印)
-- @param owner Card|Effect 效果持有者(会被转为卡片用作 Effect.CreateEffect)
-- @param target nil|player 注册目标(用于设置 handler 字段,或 Reg 注册位置)
-- @return fuef 链尾节点(最后一个完成注册的效果表)
function
fuef
:
InitSetOwner
(
name
,
owner
,
target
)
local
log
=
fudf
.
StartLog
(
1
,
"fuef:InitSetOwner"
,
name
,
owner
,
target
)
local
tg_typ
=
fusf
.
CheckArgType
(
"InitSetOwner"
,
2
,
target
,
"nil/player"
)
log
:
Info
(
"find root"
)
local
root
=
self
while
root
.
pre
do
root
=
root
.
pre
end
local
keys
=
"des,cat,pro,ran,tran,ctl,val,con,cos,tg,op,res,lab,obj"
log
:
Info
(
"set root owner"
)
local
keys
=
"des,cat,pro,ran,tran,ctl,val,con,cos,tg,op,func,res,lab,obj,pl"
local
last
repeat
if
type
(
root
.
typ
)
==
"table"
then
root
.
typ
=
root
.
typ
[
1
]
end
if
root
.
handler
~=
nil
and
not
_handler
then
_handler
=
root
.
handler
end
last
=
fuef
:
Creat
(
root
.
typ
,
root
.
cod
,
_owner
,
_handler
,
_ignore
)
for
_
,
key
in
keys
:
ForCut
(
"CreatNoc"
)
do
if
root
[
key
]
then
fuef
[
key
:
upper
()](
last
,
table.unpack
(
root
[
key
]))
repeat
if
tg_typ
==
"player"
then
root
.
handler
=
target
end
last
=
fuef
.
New
(
log
,
root
.
typ
,
root
.
cod
,
owner
,
root
.
handler
)
last
.
isinit
=
true
for
_
,
key
in
keys
:
ForCut
()
do
if
root
[
key
]
then
local
method
=
key
:
sub
(
1
,
1
):
upper
()
..
key
:
sub
(
2
)
log
:
Info
(
"try call fuef:"
..
method
)
fuef
[
method
](
last
,
table.unpack
(
root
[
key
],
1
,
root
[
key
].
n
))
end
end
last
.
isinit
=
nil
last
:
Reload
(
log
)
root
=
root
.
aft
until
not
root
log
:
Info
(
name
..
" set owner down"
)
return
last
end
-- Register Effect
function
fuef
:
Reg
(
_handler
,
_ignore
,
_isreload
)
if
not
(
_isreload
or
fuef
.
StepReg
)
then
fusf
.
Debug
(
"Reg("
..
fusf
.
ValToDebug
(
_handler
,
_ignore
)
..
")"
)
end
-- not Reg (use in FG
if
self
.
handler
==
false
or
_handler
==
false
then
self
.
handler
=
false
return
self
end
-- get handler and ignore
local
handler
,
ignore
=
self
.
handler
or
self
.
e
:
GetOwner
(),
_ignore
if
_handler
==
true
then
-- handler equal owner and ignore == true
ignore
=
true
elseif
_handler
then
-- handler not equal owner and handler is Card, Group or tp
handler
=
_handler
end
-- cover handler
self
.
handler
=
handler
-- Handler is player
if
type
(
handler
)
==
"number"
then
Duel
.
RegisterEffect
(
self
.
e
,
handler
)
return
self
end
-- Handler is c or g
-- get handler group
handler
=
fusf
.
ToGroup
(
handler
)
-- check and cover ignore
if
type
(
ignore
)
~=
"boolean"
then
ignore
=
self
.
ignore
or
false
end
-- not input _ignore
self
.
ignore
=
ignore
-- Register First Card
local
fc
=
handler
:
GetFirst
()
fc
:
RegisterEffect
(
self
.
e
,
ignore
)
handler
:
RemoveCard
(
fc
)
-- handler is group
if
#
handler
>
0
then
-- Register other card
self
.
gclo
=
{
}
for
c
in
aux
.
Next
(
handler
)
do
local
E
=
self
.
e
:
Clone
()
self
.
gclo
[
#
self
.
gclo
+
1
]
=
E
c
:
RegisterEffect
(
E
,
ignore
)
end
end
-- 设置单个 Effect 属性(适用于非解包参数)
-- @param log 日志对象或层级(用于调试记录)
-- @param set_key Effect 的方法名,例如 "SetType"
-- @param val_key 当前对象中的字段名,例如 "typ"
-- @param val_typ 允许的类型,可以是字符串("number")或多个类型的字符串("function/number")或表
-- @return fuef 返回调用者 self,支持链式调用
function
fuef
:
SetEffVal
(
log
,
set_key
,
val_key
,
val_typ
)
local
val
=
self
[
val_key
]
if
not
val
then
return
self
end
fusf
.
CheckTypes
(
val
,
val_typ
)
Effect
[
set_key
](
self
.
e
,
val
)
log
:
Info
(
set_key
)
return
self
end
-- Set all Key
function
fuef
:
SetKey
()
if
self
.
typ
then
self
.
e
:
SetType
(
self
.
typ
)
end
if
self
.
cod
then
self
.
e
:
SetCode
(
self
.
cod
)
end
if
self
.
des
then
self
.
e
:
SetDescription
(
self
.
des
)
end
if
self
.
cat
then
self
.
e
:
SetCategory
(
self
.
cat
)
end
if
self
.
pro
then
self
.
e
:
SetProperty
(
self
.
pro
)
end
if
self
.
ran
then
self
.
e
:
SetRange
(
self
.
ran
)
end
if
self
.
tran
then
self
.
e
:
SetTargetRange
(
table.unpack
(
self
.
tran
))
end
if
self
.
ctl
then
self
.
e
:
SetCountLimit
(
table.unpack
(
self
.
ctl
))
end
if
self
.
val
then
self
.
e
:
SetValue
(
self
.
val
)
end
if
self
.
con
then
self
.
e
:
SetCondition
(
self
.
con
)
end
if
self
.
cos
then
self
.
e
:
SetCost
(
self
.
cos
)
end
if
self
.
tg
then
self
.
e
:
SetTarget
(
self
.
tg
)
end
if
self
.
op
then
self
.
e
:
SetOperation
(
self
.
op
)
end
if
self
.
res
then
self
.
e
:
SetReset
(
table.unpack
(
self
.
res
))
end
if
self
.
lab
then
self
.
e
:
SetLabel
(
table.unpack
(
self
.
lab
))
end
if
self
.
obj
then
self
.
e
:
SetLabelObject
(
self
.
obj
)
end
-- 设置需要 unpack 参数的 Effect 属性(适用于参数为 table 的字段)
-- @param log 日志对象或层级(用于调试记录)
-- @param set_key Effect 的方法名,例如 "SetTargetRange"
-- @param val_key 当前对象中的字段名,例如 "tran"
-- @return fuef 返回调用者 self,支持链式调用
function
fuef
:
SetEffValUnpack
(
log
,
set_key
,
val_key
)
local
val
=
self
[
val_key
]
if
not
val
then
return
self
end
fusf
.
CheckType
(
val
,
"table"
)
Effect
[
set_key
](
self
.
e
,
table.unpack
(
val
))
log
:
Info
(
set_key
)
return
self
end
-- Reset and Creat Effect and SetKey and Reg (use in every set key final return
function
fuef
:
Reload
(
de
)
-- Reset self
local
_owner
=
self
.
e
:
GetOwner
()
self
.
e
:
Reset
()
self
.
e
=
Effect
.
CreateEffect
(
_owner
)
-- Reset if handler is group
if
self
.
gclo
then
for
_
,
gcloe
in
ipairs
(
self
.
gclo
)
do
gcloe
:
Reset
(
)
end
self
.
gclo
=
nil
end
return
self
:
SetKey
(
de
):
Reg
(
nil
,
nil
,
true
)
end
function
fuef
:
IsNil
(
from
,
...
)
local
res
=
fusf
.
IsNil
(
...
)
if
res
then
fusf
.
Debug
(
"... IsNil <- "
..
from
)
end
return
res
end
function
fuef
:
PreChk
(
from
,
...
)
fusf
.
Debug
(
"set "
..
from
..
" : "
..
fusf
.
ValToDebug
(
...
)
)
if
not
self
.
e
then
--is Noc
self
[
from
:
lower
()]
=
{
...
}
return
false
end
return
not
self
:
IsNil
(
"PreChk <- "
..
from
,
...
)
-- 主设置函数:设置当前对象(fuef)中所有已定义的 Effect 关键字段
-- 支持类型检查、空值跳过、调试输出
-- @param log 日志对象或层级(用于调试记录)
-- @return fuef 返回调用者 self,支持链式调用
function
fuef
:
SetKey
(
log
)
local
log
=
fudf
.
StartLog
(
log
,
"fuef:SetKey"
)
self
:
SetEffVal
(
log
,
"SetType"
,
"typ"
,
"number"
)
self
:
SetEffVal
(
log
,
"SetCode"
,
"cod"
,
"number"
)
self
:
SetEffVal
(
log
,
"SetDescription"
,
"des"
,
"number"
)
self
:
SetEffVal
(
log
,
"SetCategory"
,
"cat"
,
"number"
)
self
:
SetEffVal
(
log
,
"SetProperty"
,
"pro"
,
"number"
)
self
:
SetEffVal
(
log
,
"SetRange"
,
"ran"
,
"number"
)
self
:
SetEffValUnpack
(
log
,
"SetTargetRange"
,
"tran"
)
self
:
SetEffValUnpack
(
log
,
"SetCountLimit"
,
"ctl"
)
self
:
SetEffVal
(
log
,
"SetValue"
,
"val"
,
"function/number/boolean"
)
self
:
SetEffVal
(
log
,
"SetCondition"
,
"con"
,
"function"
)
self
:
SetEffVal
(
log
,
"SetCost"
,
"cos"
,
"function"
)
self
:
SetEffVal
(
log
,
"SetTarget"
,
"tg"
,
"function"
)
self
:
SetEffVal
(
log
,
"SetOperation"
,
"op"
,
"function"
)
self
:
SetEffValUnpack
(
log
,
"SetReset"
,
"res"
)
self
:
SetEffValUnpack
(
log
,
"SetLabel"
,
"lab"
)
self
:
SetEffVal
(
log
,
"SetLabelObject"
,
"obj"
,
"Card/Group/Effect"
)
self
:
SetEffVal
(
log
,
"SetOwnerPlayer"
,
"pl"
,
"player"
)
return
self
end
-- 输出当前 fuef 对象的字段信息,用于调试
function
fuef
:
Info
()
Debug
.
Message
(
""
)
Debug
.
Message
(
"Info"
)
if
self
.
typ
then
Debug
.
Message
(
"typ : "
..
fusf
.
CutHex
(
self
.
typ
,
", "
))
end
if
self
.
typ
then
Debug
.
Message
(
"typ : "
..
fusf
.
CutHex
(
self
.
typ
))
end
if
self
.
cod
then
Debug
.
Message
(
"cod : "
..
self
.
cod
)
end
if
self
.
des
then
Debug
.
Message
(
"des : "
..
(
self
.
des
//
16
)
..
", "
..
(
self
.
des
%
16
))
end
if
self
.
cat
then
Debug
.
Message
(
"cat : "
..
fusf
.
CutHex
(
self
.
cat
,
", "
))
end
if
self
.
pro
then
Debug
.
Message
(
"pro : "
..
fusf
.
CutHex
(
self
.
pro
,
", "
))
end
if
self
.
cat
then
Debug
.
Message
(
"cat : "
..
fusf
.
CutHex
(
self
.
cat
))
end
if
self
.
pro
then
Debug
.
Message
(
"pro : "
..
fusf
.
CutHex
(
self
.
pro
))
end
if
self
.
ran
then
Debug
.
Message
(
"ran : "
..
self
.
ran
)
end
if
self
.
tran
then
Debug
.
Message
(
"tran : "
..
table.concat
(
self
.
tran
,
", "
))
end
if
self
.
ctl
then
Debug
.
Message
(
"ctl : "
..
table.concat
(
self
.
ctl
,
", "
))
end
...
...
@@ -248,245 +460,447 @@ function fuef:Info()
if
self
.
cos
then
Debug
.
Message
(
"cos : "
..
tostring
(
self
.
cos
))
end
if
self
.
tg
then
Debug
.
Message
(
"tg : "
..
tostring
(
self
.
tg
))
end
if
self
.
op
then
Debug
.
Message
(
"op : "
..
tostring
(
self
.
op
))
end
if
self
.
res
then
Debug
.
Message
(
"res : "
..
fusf
.
CutHex
(
self
.
res
[
1
])
..
", "
..
self
.
res
[
2
]
,
", "
)
end
if
self
.
res
then
Debug
.
Message
(
"res : "
..
fusf
.
CutHex
(
self
.
res
[
1
])
..
", "
..
self
.
res
[
2
])
end
if
self
.
lab
then
Debug
.
Message
(
"lab : "
..
table.concat
(
self
.
lab
,
", "
))
end
if
self
.
obj
then
Debug
.
Message
(
"obj : "
..
aux
.
GetValueType
(
self
.
obj
))
end
if
self
.
handler
then
Debug
.
Message
(
"handler : "
..
(
handler
==
false
and
"false"
or
aux
.
GetValueType
(
self
.
handler
)))
end
end
----------------------------------------------------------------DES
function
fuef
:
DES
(
_code
,
_id
)
-- (0), ("n"), (m), ("+1")
if
not
self
:
PreChk
(
"DES"
,
_code
,
_id
)
then
return
self
end
self
.
des
=
fusf
.
GetDES
(
_code
,
_id
,
self
.
e
:
GetOwner
():
GetOriginalCode
())
return
self
:
Reload
()
end
----------------------------------------------------------------TYP, COD, CAT and PRO
function
fuef
:
Cons_Model
(
_key
,
_val
)
if
not
self
:
PreChk
(
_key
:
upper
(),
_val
)
then
return
self
end
local
_keytype
=
_key
==
"typ"
and
"etyp"
or
_key
local
val
,
des
=
fusf
.
Get_Constant
(
_keytype
,
_val
)
self
[
_key
]
=
val
if
_key
==
"cat"
and
des
then
self
.
des
=
self
.
des
or
des
end
return
self
:
Reload
()
end
function
fuef
:
TYP
(
_val
)
return
self
:
Cons_Model
(
"typ"
,
_val
)
end
function
fuef
:
COD
(
_val
)
return
self
:
Cons_Model
(
"cod"
,
_val
)
end
function
fuef
:
CAT
(
_val
)
return
self
:
Cons_Model
(
"cat"
,
_val
)
end
function
fuef
:
PRO
(
_val
)
return
self
:
Cons_Model
(
"pro"
,
_val
)
end
----------------------------------------------------------------RAN and TRAN
function
fuef
:
RAN
(
_loc
)
if
not
self
:
PreChk
(
"RAN"
,
_loc
)
then
return
self
end
self
.
ran
=
fusf
.
Get_Loc
(
_loc
,
nil
,
"fuef:RAN()"
)
return
self
:
Reload
()
end
function
fuef
:
TRAN
(
_loc1
,
_loc2
)
if
not
self
:
PreChk
(
"TRAN"
,
_loc1
,
_loc2
)
then
return
self
end
self
.
tran
=
{
fusf
.
Get_Loc
(
_loc1
,
_loc2
,
"fuef:TRAN()"
)}
return
self
:
Reload
()
end
----------------------------------------------------------------CTL
function
fuef
:
CTL
(
_count
,
_code
,
_pro
)
--count, code, pro
if
not
self
:
PreChk
(
"CTL"
,
_count
,
_code
,
_pro
)
then
return
self
end
if
type
(
_count
)
==
"string"
or
_count
>
99
then
-- ("n+D") or (m) -> (1, "n+D") or (1, m)
_count
,
_code
,
_pro
=
1
,
_count
,
_code
end
if
_code
==
"m"
then
_code
=
self
.
e
:
GetOwner
():
GetOriginalCode
()
end
local
res
,
ctl_val
=
{
_code
or
0
,
_pro
or
0
},
{
O
=
EFFECT_COUNT_CODE_OATH
,
D
=
EFFECT_COUNT_CODE_DUEL
,
C
=
EFFECT_COUNT_CODE_CHAIN
,
}
if
_pro
then
-- (1, n, "D")
res
=
{
fusf
.
M_chk
(
_code
),
ctl_val
[
_pro
:
match
(
"[ODC]"
)]}
elseif
type
(
_code
)
==
"string"
then
-- (1, "n+D")
res
=
_code
:
Cut
(
"CTL_1"
,
"+"
)
-- (n), (n, d), (d)
if
res
[
1
]:
match
(
"[ODC]"
)
then
res
=
{
0
,
res
[
1
]}
elseif
res
[
1
]:
match
(
"m"
)
then
res
[
1
]
=
self
.
e
:
GetOwner
():
GetOriginalCode
()
else
res
[
1
]
=
fusf
.
M_chk
(
tonumber
(
res
[
1
]))
if
self
.
obj
then
Debug
.
Message
(
"obj : "
..
fusf
.
Type
(
self
.
obj
))
end
if
self
.
handler
then
Debug
.
Message
(
"handler : "
..
fusf
.
Type
(
self
.
handler
))
end
end
--- initial 检查,仅当尚未创建效果实体(self.e 为 nil)时执行初始化
-- @param log 日志对象或层级(用于调试记录)
-- @param key string 要初始化的字段名(会转为小写)
-- @param ... any 初始化值,将作为 table 存入字段
-- @return boolean 是否在 initial 调用
function
fuef
:
InitCheck
(
log
,
key
,
...
)
if
self
.
e
then
return
false
end
local
log
=
fudf
.
StartLog
(
log
,
"fuef:InitCheck"
,
key
,
...
)
self
[
key
]
=
table.pack
(
...
)
log
:
Info
(
"set self."
..
key
)
return
true
end
--- 重置 fuef.e 并以 fuef.e 的 owner 再创建一个效果并重新应用 Key
-- 会先 Reset 原本的效果实体并重新创建,清除 clones
-- @param log 日志对象或层级(用于调试记录)
-- @return fuef 返回 self(可链式调用)
function
fuef
:
Reload
(
log
)
if
self
.
isinit
then
return
self
end
local
log
=
fudf
.
StartLog
(
log
,
"fuef:Reload"
)
log
:
Info
(
"recreate Effect"
)
local
owner
=
self
.
e
:
GetOwner
()
self
.
e
:
Reset
()
self
.
e
=
Effect
.
CreateEffect
(
owner
)
if
self
.
clones
and
#
self
.
clones
>
0
then
log
:
Info
(
"clean self.clones"
)
for
_
,
e
in
ipairs
(
self
.
clones
)
do
e
:
Reset
()
end
if
res
[
2
]
then
res
[
2
]
=
ctl_val
[
res
[
2
]:
match
(
"[ODC]"
)]
end
if
res
[
2
]
&
0x30000000
>
0
and
res
[
1
]
==
0
then
res
[
1
]
=
self
.
e
:
GetOwner
():
GetOriginalCode
()
end
-- is O or D
self
.
clones
=
nil
end
self
.
ctl
=
{
_count
,
res
[
1
]
+
res
[
2
]}
return
self
:
Reload
(
)
return
self
:
SetKey
(
log
):
Reg
(
log
)
end
----------------------------------------------------------------VAL, CON, COS, TG and OP
function
fuef
:
Func
(
_val
,
_func
,
...
)
-- func = ("val,con,cos(v1,v2),tg,op") or ("con(v1,v2),op") or (val, "con,op(v1, v2)"), if v = %1~n then { ... } is value table
if
fusf
.
IsNil
(
_val
,
_func
)
then
-- nil chk
fusf
.
Debug
(
"_val, _func IsNil <- Func"
..
_from
)
return
self
----------------------------------------------------------------DES
--- 设置描述字段(des),支持延迟初始化
-- 若尚未创建效果实体,则记录并延后设置;否则立即设置并重载
-- @param code string|number 描述代码(将传入 ResolveDescription)
-- @param id string|number 描述 ID(将传入 ResolveDescription)
-- @return fuef 返回 self(可链式调用)
function
fuef
:
Des
(
code
,
id
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Des"
,
code
,
id
)
fusf
.
CheckEmptyArgs
(
"Des"
,
code
,
id
)
if
self
:
InitCheck
(
log
,
"des"
,
code
,
id
)
then
return
self
end
local
m
=
self
.
e
:
GetOwner
():
GetOriginalCode
()
self
.
des
=
fusf
.
ResolveDescription
(
code
,
id
,
m
)
log
:
Info
(
"set self.des : "
..
self
.
des
)
return
self
:
Reload
(
log
)
end
----------------------------------------------------------------Const
--- 设定常数型栏位(如 typ、cod、cat 等),若尚未建立效果物件则先记录初始值
-- 若已存在效果物件则立即重新加载
-- @param log 日志对象或层级(用于调试记录)
-- @param key string 栏位名称(如 "typ", "cod", "cat" 等)
-- @param val any 欲设定的常数值(支援名称字串或数值)
-- @return self fuef 物件
function
fuef
:
SetConstField
(
log
,
key
,
val
)
local
log
=
fudf
.
StartLog
(
log
,
"fuef:SetConstField"
,
key
,
val
)
fusf
.
CheckArgType
(
key
,
1
,
val
,
"number/string"
)
key
=
key
:
lower
()
if
self
:
InitCheck
(
log
,
key
,
val
)
then
return
self
end
local
table_key
=
(
key
==
"typ"
)
and
"etyp"
or
key
local
val
,
des
=
fusf
.
ParseConstantKey
(
table_key
,
val
)
self
[
key
]
=
val
log
:
Info
((
"set self.%s : %s"
):
format
(
key
,
val
))
if
key
==
"cat"
and
des
then
self
.
des
=
self
.
des
or
des
log
:
Info
(
"set self.des : "
..
self
.
des
)
end
local
vals
=
{
...
}
if
not
(
type
(
_val
)
==
"string"
and
_val
:
match
(
"%,"
))
then
-- check _val is val
local
val
=
{
_val
}
if
type
(
_val
)
==
"string"
and
_val
:
match
(
"%%"
)
then
val
=
{
_val
,
...
}
end
self
.
val
=
val
else
-- _val is _func
vals
,
_func
=
{
_func
,
...
},
_val
return
self
:
Reload
(
log
)
end
--- 设定 type
function
fuef
:
Typ
(
typ
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Typ"
,
typ
)
return
self
:
SetConstField
(
log
,
"Typ"
,
typ
)
end
--- 设定 code
function
fuef
:
Cod
(
code
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Cod"
,
code
)
return
self
:
SetConstField
(
log
,
"Cod"
,
code
)
end
--- 设定 category
function
fuef
:
Cat
(
category
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Cat"
,
category
)
return
self
:
SetConstField
(
log
,
"Cat"
,
category
)
end
--- 设定 property
function
fuef
:
Pro
(
property
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Pro"
,
property
)
return
self
:
SetConstField
(
log
,
"Pro"
,
property
)
end
----------------------------------------------------------------Range
--- 设定效果适用的区域(Range)
-- @param loc string|number 区域常数或其字串名称
-- @return self fuef 物件
function
fuef
:
Ran
(
loc
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Ran"
,
loc
)
fusf
.
CheckArgType
(
"Ran"
,
1
,
loc
,
"number/string"
)
if
self
:
InitCheck
(
log
,
"ran"
,
loc
)
then
return
self
end
loc
=
fusf
.
GetLoc
(
loc
)
self
.
ran
=
loc
log
:
Info
(
"set self.ran : "
..
loc
)
return
self
:
Reload
(
log
)
end
--- 设定效果于自己与对手区域的作用范围(TargetRange)
-- @param self_loc string|number 自己场地的区域
-- @param oppo_loc string|number 对手场地的区域
-- @return self fuef 物件
function
fuef
:
Tran
(
self_loc
,
oppo_loc
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Tran"
,
self_loc
,
oppo_loc
)
fusf
.
CheckEmptyArgs
(
"Tran"
,
self_loc
,
oppo_loc
)
if
self
:
InitCheck
(
log
,
"tran"
,
self_loc
,
oppo_loc
)
then
return
self
end
self_loc
,
oppo_loc
=
fusf
.
GetLoc
(
self_loc
,
oppo_loc
)
self
.
tran
=
{
self_loc
,
oppo_loc
}
log
:
Info
((
"set self.tran : %s / %s"
):
format
(
self_loc
,
oppo_loc
))
return
self
:
Reload
(
log
)
end
----------------------------------------------------------------CountLimit
--- 设定效果限制条件(Count Limit),支援多种输入格式。
-- @param count number|string 可为数字(使用次数)或字串(如 "100+O")
-- @param code number|string|nil 可为卡号、字符串(含限制类型 "O/D/C"),或留空
-- @param pro string|nil 限制类型("O"=OATH, "D"=DUEL, "C"=CHAIN)
-- @return fuef 返回自身以支援链式调用
function
fuef
:
Ctl
(
count
,
code
,
pro
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Ctl"
,
count
,
code
,
pro
)
fusf
.
CheckEmptyArgs
(
"Ctl"
,
count
,
code
,
pro
)
if
self
:
InitCheck
(
log
,
"ctl"
,
count
,
code
,
pro
)
then
return
self
end
local
ct_typ
=
fusf
.
CheckArgType
(
"Ctl"
,
1
,
count
,
"number/string"
)
if
ct_typ
==
"string"
or
count
>
99
then
-- ("n+D") or (m) -> (1, "n+D") or (1, m)
count
,
code
,
pro
=
1
,
count
,
code
end
-- "val,con,cos,tg,op" or "con,op" , if cant match then follow a sequence
local
seqs
,
place
,
sets
=
{
"val"
,
"con"
,
"cos"
,
"tg"
,
"op"
},
1
,
{
}
-- "f1,f2(%1,v2),f3" -> {"f1", {"f2", vals[1], "v2"}, "f3"}, ... use in vi = %i
for
i
,
func
in
fusf
.
ForTable
(
fusf
.
Val_Cuts
(
_func
,
table.unpack
(
vals
)))
do
local
fname
,
fval
=
func
,
func
if
type
(
fname
)
==
"table"
then
fname
=
table.remove
(
fval
,
1
)
else
fval
=
nil
end
-- find fname can match seqs
local
match
=
0
for
j
=
place
,
5
do
local
temp
=
fname
:
find
(
seqs
[
j
])
if
temp
and
temp
>
match
then
place
,
match
=
j
,
temp
local
cod_typ
=
fusf
.
CheckArgType
(
"Ctl"
,
2
,
code
,
"nil/number/string"
)
local
m
=
self
.
e
:
GetOwner
():
GetOriginalCode
()
local
ctl_consts
=
fusf
.
Findfucs
(
"ctl"
)
local
_code
,
_pro
=
0
,
0
fusf
.
CheckArgType
(
"Ctl"
,
3
,
pro
,
"nil/string"
)
if
pro
then
_pro
=
fusf
.
FindTables
(
pro
,
ctl_consts
)
end
if
cod_typ
==
"number"
then
_code
=
fusf
.
NormalizeID
(
code
,
m
)
elseif
cod_typ
==
"string"
then
for
_
,
val
in
code
:
ForCut
(
"+"
)
do
local
match
=
val
:
match
(
"[ODC]"
)
if
match
then
if
_pro
~=
0
then
error
(
"repeat set fuef:Ctl pro in string"
,
2
)
end
_pro
=
fusf
.
FindTables
(
match
,
ctl_consts
)
else
_code
=
fusf
.
NormalizeID
(
val
,
m
)
end
end
-- cant match seqs
if
match
==
0
then
place
=
i
end
-- set self[key] and save key
func
=
seqs
[
place
]
self
[
func
],
sets
[
#
sets
+
1
]
=
{
fname
,
fval
},
func
-- self[func] = {name, {...}} or {name}
end
if
not
self
.
e
then
return
self
end
-- self[key] = {func, ...}
if
sets
[
1
]
==
"val"
then
table.remove
(
sets
,
1
)
local
val
=
self
.
val
[
1
]
if
type
(
val
)
==
"string"
then
self
.
val
=
tonumber
(
val
)
or
fucs
.
val
[
val
]
or
fusf
.
Get_Func
(
self
.
e
:
GetOwner
(),
table.unpack
(
self
.
val
))
if
not
self
.
val
then
fusf
.
Debug
(
"val Func value is nil"
)
end
else
-- number or function
if
_code
==
0
and
(
_pro
==
ctl_consts
[
"O"
]
or
_pro
==
ctl_consts
[
"D"
])
then
_code
=
m
end
self
.
ctl
=
{
count
,
_code
+
_pro
}
log
:
Info
((
"set self.ctl : %s / %s"
):
format
(
count
,
self
.
ctl
[
2
]))
return
self
:
Reload
(
log
)
end
----------------------------------------------------------------VAL, CON, COS, TG and OP
--- 设定函数型栏位,如 val、con、tar、op 等,可接受函数名、表达式或函数本体
-- @param log 日志对象或层级(用于调试记录)
-- @param key string 欲设定的栏位名称
-- @param func string|function|number 欲指定的函数或值
-- @param ... 可选的参数,用于传递给 ResolveFunction 或 ParseCallExprString
-- @return fuef 返回自身以支援链式调用
function
fuef
:
SetFuncField
(
log
,
key
,
func
,
...
)
local
log
=
fudf
.
StartLog
(
log
,
"fuef:SetFuncField"
,
key
,
func
,
...
)
fusf
.
CheckEmptyArgs
(
key
,
func
,
...
)
key
=
key
:
lower
()
local
types
=
"string/function"
if
key
==
"val"
then
types
=
types
..
"/number"
end
local
f_typ
=
fusf
.
CheckArgType
(
key
,
1
,
func
,
types
)
if
self
:
InitCheck
(
log
,
key
,
func
,
...
)
then
return
self
end
local
has_arg
=
select
(
"#"
,
...
)
>
0
if
f_typ
==
"function"
then
if
has_arg
then
func
=
func
(
...
)
end
self
[
key
]
=
func
log
:
Info
((
"set self.%s : %s"
):
format
(
key
,
tostring
(
func
)))
return
self
:
Reload
(
log
)
end
if
key
==
"val"
then
local
val
=
tonumber
(
func
)
or
fucs
.
val
[
func
]
or
aux
[
func
]
if
val
~=
nil
then
self
.
val
=
val
log
:
Info
(
"set self.val : "
..
tostring
(
val
))
return
self
:
Reload
(
log
)
end
end
for
_
,
set
in
ipairs
(
sets
)
do
local
res
=
fusf
.
Get_Func
(
self
.
e
:
GetOwner
(),
table.unpack
(
self
[
set
]))
if
not
res
then
fusf
.
Debug
(
set
..
" Func value is nil"
)
end
self
[
set
]
=
res
local
f
,
args
=
func
,
nil
if
has_arg
then
args
=
table.pack
(
...
)
end
if
func
:
match
(
"%("
)
then
f
,
args
=
fusf
.
ParseCallExprString
(
func
,
args
)
end
return
self
:
Reload
()
end
function
fuef
:
Func_Model
(
_key
,
_func
,
...
)
if
not
self
:
PreChk
(
_key
:
upper
(),
_func
,
...
)
then
return
self
end
local
val_chk
=
_key
==
"val"
and
(
tonumber
(
_func
)
or
fucs
.
val
[
_func
])
or
nil
local
vals
=
select
(
"#"
,
...
)
>
0
and
{
...
}
or
nil
if
type
(
_func
)
==
"string"
and
_func
:
match
(
"%("
)
then
_func
=
fusf
.
Val_Cuts
(
_func
,
...
)[
1
]
vals
=
_func
if
type
(
_func
)
==
"table"
then
_func
=
table.remove
(
vals
,
1
)
else
vals
=
nil
local
c
=
self
.
e
:
GetOwner
()
f
=
fusf
.
ResolveFunction
(
f
,
args
,
fusf
.
Getcm
(
c
),
c
.
lib
)
self
[
key
]
=
f
log
:
Info
((
"set self.%s : %s"
):
format
(
key
,
tostring
(
f
)))
return
self
:
Reload
(
log
)
end
--- 设定效果的 value(数值或函数),可为 number|string|function
-- @param val number|string|function 数值或函数(或名称)
-- @param ... 可选的额外参数(若 val 是函数字串会带入)
-- @return fuef 返回自身以支援链式调用
function
fuef
:
Val
(
val
,
...
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Val"
,
val
,
...
)
return
self
:
SetFuncField
(
log
,
"Val"
,
val
,
...
)
end
--- 设定效果的 condition(条件),可为 string|function
-- @param condition function|string 条件函数或其名称
-- @param ... 可选的额外参数(若为函数字串会带入)
-- @return fuef 返回自身以支援链式调用
function
fuef
:
Con
(
condition
,
...
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Con"
,
condition
,
...
)
return
self
:
SetFuncField
(
log
,
"Con"
,
condition
,
...
)
end
--- 设定效果的 cost(代价),可为 string|function
-- @param cost function|string 条件函数或其名称
-- @param ... 可选的额外参数(若为函数字串会带入)
-- @return fuef 返回自身以支援链式调用
function
fuef
:
Cos
(
cost
,
...
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Cos"
,
cost
,
...
)
return
self
:
SetFuncField
(
log
,
"Cos"
,
cost
,
...
)
end
--- 设定效果的 target(目标),可为 string|function
-- @param target function|string 条件函数或其名称
-- @param ... 可选的额外参数(若为函数字串会带入)
-- @return fuef 返回自身以支援链式调用
function
fuef
:
Tg
(
target
,
...
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Tg"
,
target
,
...
)
return
self
:
SetFuncField
(
log
,
"Tg"
,
target
,
...
)
end
--- 设定效果的 operation(执行动作),可为 string|function
-- @param operation function|string 条件函数或其名称
-- @param ... 可选的额外参数(若为函数字串会带入)
-- @return fuef 返回自身以支援链式调用
function
fuef
:
Op
(
operation
,
...
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Op"
,
operation
,
...
)
return
self
:
SetFuncField
(
log
,
"Op"
,
operation
,
...
)
end
--- 依据传入的函数结构设定 fuef 物件的多个栏位(val/con/cos/tg/op)
-- 支援多种格式的输入,并自动解析每一段功能模块,依照顺序填入栏位
-- @param val 可能是 val 值,或实际的函数名(视情况而定)
-- @param func 字串描述或 table 结构,代表要设置的功能函数模块
-- @param ... 其他额外参数,可能为 val 的对应值,或函数模块的参数
-- @return fuef 返回自身以支援链式调用
function
fuef
:
Func
(
val
,
func
,
...
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Func"
,
val
,
func
,
...
)
fusf
.
CheckEmptyArgs
(
"Func"
,
val
,
func
,
...
)
if
self
:
InitCheck
(
log
,
"func"
,
val
,
func
,
...
)
then
return
self
end
local
val_typ
=
fusf
.
CheckArgType
(
up_key
,
1
,
val
,
"string/function/number"
)
log
:
Info
(
"try match val"
)
local
args
=
{
...
}
if
MatchValFormat
(
val
,
val_typ
)
then
self
:
SetFuncField
(
log
,
"val"
,
val
,
...
)
else
func
,
args
=
val
,
{
func
,
...
}
end
local
c
=
self
.
e
:
GetOwner
()
local
cm
=
fusf
.
Getcm
(
c
)
local
keys
,
key_ind
=
{
"val"
,
"con"
,
"cos"
,
"tg"
,
"op"
},
1
local
func_table
=
fusf
.
ParseCallGroupString
(
func
,
args
)
if
func_table
.
n
>
5
then
error
(
"Func : invalid func len"
,
2
)
end
log
:
Info
(
"try match keys"
)
for
i
,
unit
in
fusf
.
ForTable
(
func_table
)
do
local
fname
,
fargs
=
unit
if
type
(
unit
)
==
"table"
then
fname
,
fargs
=
unit
[
1
],
unit
[
2
]
end
elseif
vals
and
#
vals
==
1
and
type
(
vals
[
1
])
==
"table"
then
vals
=
vals
[
1
]
-- 若 vals 中只有一个表,则直接解包表
log
:
Info
(
i
..
" : "
..
fname
)
local
f
=
fusf
.
ResolveFunction
(
fname
,
fargs
,
cm
,
c
.
lib
)
local
match
=
0
for
j
=
key_ind
,
5
do
local
ind
=
fname
:
find
(
keys
[
j
])
if
ind
and
ind
>
match
then
key_ind
,
match
=
j
,
ind
end
end
if
match
==
0
then
key_ind
=
i
end
local
key
=
keys
[
key_ind
]
log
:
Info
(
"match "
..
key
)
self
:
SetFuncField
(
log
,
key
,
f
)
end
self
[
_key
]
=
val_chk
or
fusf
.
Get_Func
(
self
.
e
:
GetOwner
(),
_func
,
vals
)
if
not
self
[
_key
]
then
fusf
.
Debug
(
_key
..
" Func value is nil"
)
end
return
self
:
Reload
()
end
function
fuef
:
VAL
(
_func
,
...
)
return
self
:
Func_Model
(
"val"
,
_func
,
...
)
end
function
fuef
:
CON
(
_func
,
...
)
return
self
:
Func_Model
(
"con"
,
_func
,
...
)
end
function
fuef
:
COS
(
_func
,
...
)
return
self
:
Func_Model
(
"cos"
,
_func
,
...
)
end
function
fuef
:
TG
(
_func
,
...
)
return
self
:
Func_Model
(
"tg"
,
_func
,
...
)
end
function
fuef
:
OP
(
_func
,
...
)
return
self
:
Func_Model
(
"op"
,
_func
,
...
)
log
:
Info
(
"all match down"
)
return
self
end
----------------------------------------------------------------RES
function
fuef
:
RES
(
_flag
,
_count
)
-- _flag = a + b/b1/b2 + c | 1
if
not
self
:
PreChk
(
"RES"
,
_flag
,
_count
)
then
return
self
end
self
.
res
=
fusf
.
GetRES
(
_flag
,
_count
)
return
self
:
Reload
()
end
----------------------------------------------------------------LAB
function
fuef
:
LAB
(
...
)
if
not
self
:
PreChk
(
"LAB"
,
...
)
then
return
self
end
local
elabs
=
{
}
for
_
,
labs
in
ipairs
({
...
})
do
if
type
(
labs
)
==
"string"
then
for
_
,
lab
in
labs
:
ForCut
(
"LAB"
,
"+"
)
do
elabs
[
#
elabs
+
1
]
=
(
lab
==
"m"
)
and
self
.
e
:
GetOwner
():
GetOriginalCode
()
or
tonumber
(
lab
)
--- 设定效果的 reset(重置条件)
-- @param flag string|number 条件描述(如 "a + b - c , 1")
-- @param count number? 可选的重置次数,若省略则从字串中解析
-- @return fuef 返回自身以支援链式调用
function
fuef
:
Res
(
flag
,
count
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Res"
,
flag
,
count
)
fusf
.
CheckEmptyArgs
(
"Res"
,
flag
,
count
)
if
self
:
InitCheck
(
log
,
"res"
,
flag
,
count
)
then
return
self
end
flag
,
count
=
fusf
.
ResolveReset
(
flag
,
count
)
self
.
res
=
{
flag
,
count
}
log
:
Info
((
"set self.res : %s / %d"
):
format
(
fusf
.
CutHex
(
flag
),
count
))
return
self
:
Reload
(
log
)
end
----------------------------------------------------------------LAB & OBJ
--- 设定 label 参数,支援数字、字串(可用 "+" 拆分)与特别标记 "m"
-- @param ... 可为数字、字串(如 "1+2+m")等,会转为数字阵列
-- @return fuef 返回自身,用于链式调用
function
fuef
:
Lab
(
...
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Lab"
,
...
)
fusf
.
CheckEmptyArgs
(
"Lab"
,
...
)
if
self
:
InitCheck
(
log
,
"lab"
,
...
)
then
return
self
end
local
m
=
self
.
e
:
GetOwner
():
GetOriginalCode
()
local
args
=
{}
for
i
,
val
in
ipairs
{
...
}
do
local
typ
=
fusf
.
CheckArgType
(
"Lab"
,
i
,
val
,
"string/number"
)
if
typ
==
"string"
then
for
_
,
lab
in
val
:
ForCut
(
"+"
)
do
args
[
#
args
+
1
]
=
(
lab
==
"m"
)
and
m
or
tonumber
(
lab
)
end
else
elabs
[
#
elabs
+
1
]
=
labs
args
[
#
args
+
1
]
=
val
end
end
self
.
lab
=
elabs
return
self
:
Reload
()
end
----------------------------------------------------------------OBJ
function
fuef
:
OBJ
(
_val
)
if
not
self
:
PreChk
(
"OBJ"
,
_val
)
then
return
self
end
if
type
(
_val
)
==
"string"
then
-- ex: cm.e3 = fuef.FG("e1") -> obj == cm.e1
_val
=
fusf
.
Getcm
(
self
)[
"es"
][
_val
].
e
end
self
.
obj
=
_val
return
self
:
Reload
(
1
)
end
--------------------------------------------------------------------------"Support Effect function"
function
fuef
.
initial
(
_lib
,
_glo
,
_exop_func
,
...
)
local
cm
,
m
=
GetID
()
local
exop_val
=
{
...
}
cm
.
es
,
cm
.
lib
=
{},
_lib
cm
.
initial_effect
=
cm
.
initial_effect
or
function
(
c
)
-- do ex_op
if
_exop_func
then
local
place
=
1
if
type
(
_exop_func
)
~=
"table"
then
_exop_func
=
{
_exop_func
}
end
for
_
,
exop_func
in
ipairs
(
_exop_func
)
do
if
type
(
exop_func
)
==
"string"
then
for
_
,
func
in
exop_func
:
ForCut
(
"fuef.initial"
)
do
local
f
=
fucf
[
func
]
or
Card
[
func
]
if
f
then
f
(
c
,
exop_val
[
place
])
else
cm
[
func
]
=
exop_val
[
place
](
c
)
end
place
=
place
+
1
end
else
exop_func
(
c
,
exop_val
[
place
])
place
=
place
+
1
end
end
end
local
dof
=
function
(
_name
,
_exval
)
local
n
=
1
while
cm
[
_name
..
n
]
do
cm
.
es
[
_name
..
n
]
=
cm
[
_name
..
n
](
c
,
_exval
)
n
=
n
+
1
end
self
.
lab
=
args
log
:
Info
((
"set self.lab : %d arg"
):
format
(
#
args
))
return
self
:
Reload
(
log
)
end
--- 设置效果的关联对象(object),可为字符串代号或实际对象
-- @param val string|Card|Group|Effect 关联对象,字符串将解析为 cm.elist 的键
-- @return fuef 返回自身,用于链式调用
-- @raise 类型不符时抛出错误
function
fuef
:
Obj
(
val
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Obj"
,
val
)
local
typ
=
fusf
.
CheckArgType
(
"Obj"
,
1
,
val
,
"string/fuef/Card/Group/Effect"
)
if
self
:
InitCheck
(
log
,
"obj"
,
val
)
then
return
self
end
if
typ
==
"string"
then
local
e
=
fusf
.
Getcm
(
self
).
elist
[
val
]
if
not
e
or
not
e
.
e
then
error
(
"Obj: elist entry for '"
..
val
..
"' is missing or invalid"
,
2
)
end
dof
(
"e"
)
-- do e1 ~ en
dof
(
"pe"
)
-- do e1 ~ en in lib pre set
-- if cm[_glo] then do ge1 ~ gen
if
not
(
_glo
and
not
cm
[
_glo
])
then
return
end
cm
[
_glo
]
=
{
0
,
0
}
dof
(
"ge"
,
1
)
val
=
fusf
.
CheckType
(
e
.
e
,
"Effect"
)
end
return
cm
,
m
self
.
obj
=
val
log
:
Info
(
"set self.obj : "
..
typ
)
return
self
:
Reload
(
log
)
end
---------------------------------------------------------------- OwnerPlayer
--- 设置效果的 OwnerPlayer 属性为 player
-- @param p player 玩家
-- @return self fuef 物件
function
fuef
:
Pl
(
p
)
local
log
=
fudf
.
StartLog
(
self
,
"fuef:Pl"
,
p
)
fusf
.
CheckArgType
(
"Pl"
,
1
,
p
,
"player"
)
if
self
:
InitCheck
(
log
,
"Pl"
,
p
)
then
return
self
end
self
.
pl
=
p
log
:
Info
(
"set self.pl : "
..
p
)
return
self
:
Reload
(
log
)
end
function
fuef
.
tg_is_cos
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
)
e
:
SetLabel
(
100
)
if
chk
==
0
then
return
true
end
end
\ No newline at end of file
expansions/script/c20099997.lua
View file @
14515cb1
dofile
(
"expansions/script/c20099998.lua"
)
if
fucf
then
return
end
fucf
,
fugf
=
{
},
{
}
dofile
(
"expansions/script/c20099998.lua"
)
-------------------------------------- Group function
--- 根据卡片过滤条件构造一个群组过滤器(可回传过滤后的卡片群组或判断数量)
-- @param f string|function 过滤函数或名称,传入 MakeCardFilter 使用
-- @param v any 传入过滤函数的参数,可为单值或表
-- @param ... 可选占位参数,传给 MakeCardFilter
-- @return function function(Group, number?): Group | boolean
-- 若不提供 n,返回符合条件的子群组;
-- 若提供正整数 n,返回群组中符合条件的卡片数量是否 ≥ n;
-- 若提供负整数 -n,返回是否 ≤ -n。
function
fugf
.
MakeGroupFilter
(
f
,
v
)
return
function
(
g
,
n
,
...
)
fusf
.
CheckArgType
(
"MakeGroupFilter"
,
1
,
g
,
"Group"
)
local
ok
,
res
=
pcall
(
fusf
.
CheckArgType
,
"MakeGroupFilter"
,
2
,
n
,
"nil/number"
)
if
not
ok
then
error
(
res
,
2
)
end
g
=
g
:
Filter
(
fucf
.
MakeCardFilter
(
f
,
v
,
...
),
nil
)
if
not
n
then
return
g
end
return
n
>
0
and
#
g
>=
n
or
#
g
<=
-
n
end
end
--- 返回以 p 来看的 loc (自己以及对方区域以+分开)位置的卡片组
-- @param p number 玩家编号(必须是 0 或 1)
-- @param loc string 表示区域的字符串(如 "H+HM" 等)
-- @return Group 返回该区域内所有卡片的 Group
function
fugf
.
Get
(
p
,
loc
)
return
Duel
.
GetFieldGroup
(
p
,
fusf
.
Get_Loc
(
loc
))
fusf
.
CheckArgType
(
"Get"
,
1
,
p
,
"player"
)
return
Duel
.
GetFieldGroup
(
p
,
fusf
.
GetLoc
(
loc
))
end
--- 以指定条件过滤 Group 中的卡片(支持数量判断)
-- @param g Group 要过滤的卡片群组
-- @param f string|function 用于 MakeCardFilter 的过滤函数或名称
-- @param v any 用于传入过滤器的参数(可为单值、表等)
-- @param n number|nil 可选值:
-- - 若为 nil,返回过滤后的 Group;
-- - 若为正数,判断是否有 ≥ n 张符合条件的卡片,返回 boolean;
-- - 若为负数,判断是否有 ≤ n 张符合条件的卡片,返回 boolean。
-- @param ... any 可选参数,传入 MakeCardFilter,用于额外参数或占位
-- @return Group|boolean 返回过滤后的 Group,或符合数量条件的布尔值
function
fugf
.
Filter
(
g
,
f
,
v
,
n
,
...
)
return
fu
sf
.
Creat_GF
(
f
,
v
,
...
)(
g
,
n
)
return
fu
gf
.
MakeGroupFilter
(
f
,
v
)(
g
,
n
,
...
)
end
--- 获取并过滤指定玩家区域内的卡片
-- @param p number 玩家编号(必须是 0 或 1)
-- @param loc string 表示区域的字符串(如 "H+HM" 等)
-- @param f string|function 过滤函数或名称,传入 MakeCardFilter 使用
-- @param v any 传入过滤函数的参数(可为单值或表)
-- @param n number|nil 可选数量条件(正数:≥n,负数:≤n,nil:返回过滤后的 Group)
-- @param ... 可选额外参数,传给 MakeCardFilter
-- @return Group|boolean 返回过滤后的 Group,或是否符合数量条件
function
fugf
.
GetFilter
(
p
,
loc
,
f
,
v
,
n
,
...
)
return
fugf
.
Filter
(
fugf
.
Get
(
p
,
loc
),
f
,
v
,
n
,
...
)
end
function
fugf
.
GetNoP
(
loc
,
f
,
v
,
n
,
...
)
local
val
=
{
...
}
return
function
(
p
)
return
fugf
.
GetFilter
(
p
,
loc
,
f
,
v
,
n
,
table.unpack
(
val
))
--- 构造一个带默认位置与过滤条件的 Group 过滤器函数
-- @param loc string 预设区域字符串(如 "M", "H+M")
-- @param f string|function 过滤函数或名称,用于 MakeCardFilter
-- @param v any 传给过滤函数的参数
-- @param n number|nil 数量要求(正:≥n,负:≤n,nil:返回过滤后的 Group)
-- @return function(p: number, ...): Group|boolean
-- 返回一个函数,该函数接受 p 及 ... 并执行过滤
function
fugf
.
MakeFilter
(
loc
,
f
,
v
,
n
)
return
function
(
p
,
...
)
return
fugf
.
GetFilter
(
p
,
loc
,
f
,
v
,
n
,
...
)
end
end
--- 从卡片组中选择卡片(带筛选、数量控制)
-- @param p number 控制玩家编号(0或1)
-- @param g Group|string 卡片组,或为关键字字符串(如 "HAND+MONSTER")
-- @param f function|number 筛选函数或最小选择数量
-- @param v any 若 f 为函数时传入的首个额外参数
-- @param min number? 最小选择数量(若 f 为 number,此值会从 f 推出)
-- @param max number? 最大选择数量(默认与 min 相同)
-- @param ... any 筛选函数的其它额外参数
-- @return Group 返回选择的卡片组(Group 类型)
function
fugf
.
Select
(
p
,
g
,
f
,
v
,
min
,
max
,
...
)
if
type
(
g
)
==
"string"
then
g
=
fugf
.
Get
(
p
,
g
)
end
-- _g is loc
local
g_typ
=
fusf
.
CheckArgType
(
"Select"
,
2
,
g
,
"Group/string"
)
if
g_typ
==
"string"
then
g
=
fugf
.
Get
(
p
,
g
)
end
if
type
(
f
)
==
"number"
then
-- f is min
min
,
max
=
f
,
v
elseif
f
then
-- f is func
...
...
@@ -29,136 +88,369 @@ function fugf.Select(p, g, f, v, min, max, ...)
if
#
g
==
min
then
return
g
end
return
g
:
Select
(
p
,
min
,
max
,
nil
)
end
--- 从指定卡组中选择目标卡并设定为效果目标
-- @param p number 玩家编号(0 或 1)
-- @param g Group|string 卡片群组,或表示卡片来源的字符串(会调用 fugf.Get)
-- @param f function|string|number 可选过滤函数或数量
-- - 若为 number,代表 min 数量,v 将视为 max;
-- - 若为 function/string,则视为过滤器(将用于 Filter)
-- @param v any 过滤器附加参数
-- @param min number 最小选择数量(默认 1)
-- @param max number 最大选择数量(默认等于 min)
-- @param ... 其他传给过滤器的参数
-- @return Group 被选择并设定为目标的卡片群组
function
fugf
.
SelectTg
(
p
,
g
,
f
,
v
,
min
,
max
,
...
)
local
g
=
fugf
.
Select
(
p
,
g
,
f
,
v
,
min
,
max
,
...
)
Duel
.
SetTargetCard
(
g
)
return
g
end
--------------------------------------"Card function" (use in initial (no return
function
fucf
.
AddCode
(
c
,
...
)
local
codes
=
{
}
for
_
,
_code
in
ipairs
({
...
})
do
if
type
(
_code
)
==
"string"
then
for
_
,
cod
in
_code
:
ForCut
(
"fucf.AddCode"
)
do
codes
[
#
codes
+
1
]
=
fusf
.
M_chk
(
cod
)
--------------------------------------"Card function"
--- 根据函数与参数构造一个卡片过滤器(返回一个 function(Card) -> bool)
-- @param func string|function 过滤函数或其名称,支援组合逻辑与反向(如 "~IsType+IsRace")
-- @param args table|string|number 传入的参数,可为字符串(含占位符)或具体值
-- @param ... 可选的占位参数(会传给 %1、%2 等)
-- @return function 过滤器函数,接受卡片并返回布林值
function
fucf
.
MakeCardFilter
(
func
,
args
,
...
)
if
not
func
then
return
function
(
c
)
return
true
end
end
local
typ
=
fusf
.
CheckArgType
(
"MakeCardFilter"
,
1
,
func
,
"string/function"
)
-- trans args
if
type
(
args
)
~=
"table"
then
args
=
{
args
}
end
local
arg_table
,
arg_count
=
{},
0
for
_
,
arg
in
ipairs
(
args
)
do
if
type
(
arg
)
==
"string"
then
for
_
,
v
in
fusf
.
ForTable
(
fusf
.
ParseCallGroupString
(
arg
,
{
...
}))
do
arg_count
=
arg_count
+
1
arg_table
[
arg_count
]
=
v
end
else
codes
[
#
codes
+
1
]
=
fusf
.
M_chk
(
_code
)
arg_count
=
arg_count
+
1
arg_table
[
arg_count
]
=
arg
end
end
-- func is function
if
typ
==
"function"
then
return
function
(
c
)
fusf
.
CheckArgType
(
"MakeCardFilter"
,
1
,
c
,
"Card"
)
return
func
(
c
,
table.unpack
(
arg_table
,
1
,
arg_count
))
end
end
aux
.
AddCodeList
(
c
,
table.unpack
(
codes
))
end
fucf
.
ReviveLimit
=
Card
.
EnableReviveLimit
--------------------------------------"Card function" (use in Filter
function
fucf
.
Filter
(
c
,
_func
,
...
)
return
fusf
.
Creat_CF
(
_func
,
{
...
})(
c
)
--return fugf.Filter(Group.FromCards(c), func, {...}, 1)
end
fucf
.
IsRk
=
fusf
.
IsN
(
"GetRank"
)
fucf
.
IsLv
=
fusf
.
IsN
(
"GetLevel"
)
fucf
.
IsRLv
=
fusf
.
IsN
(
"GetRitualLevel"
)
fucf
.
IsLk
=
fusf
.
IsN
(
"GetLink"
)
fucf
.
IsAtk
=
fusf
.
IsN
(
"GetAttack"
)
fucf
.
IsDef
=
fusf
.
IsN
(
"GetDefense"
)
fucf
.
IsSeq
=
fusf
.
IsN
(
"GetSequence"
)
fucf
.
IsPSeq
=
fusf
.
IsN
(
"GetPreviousSequence"
)
function
fucf
.
Not
(
c
,
val
)
if
aux
.
GetValueType
(
val
)
==
"Card"
then
-- func is string
local
func_expr
=
fusf
.
InfixToPostfix
(
func
,
...
)
local
fucf
,
Card
,
aux
=
fucf
,
Card
,
aux
if
#
func_expr
==
1
then
-- func just one
local
find_func
=
fusf
.
FindTables
(
func_expr
[
1
],
fucf
,
Card
,
aux
)
fusf
.
CheckType
(
find_func
,
"function"
)
return
function
(
c
)
fusf
.
CheckArgType
(
"MakeCardFilter"
,
1
,
c
,
"Card"
)
return
find_func
(
c
,
table.unpack
(
arg_table
,
1
,
arg_count
))
end
end
-- func is multi
return
function
(
c
)
fusf
.
CheckArgType
(
"MakeCardFilter"
,
1
,
c
,
"Card"
)
local
stack
,
arg_ind
=
{},
1
for
_
,
func
in
ipairs
(
func_expr
)
do
if
func
==
"~"
then
stack
[
#
stack
]
=
not
stack
[
#
stack
]
elseif
type
(
func
)
==
"string"
and
#
func
==
1
then
local
valR
,
valL
=
table.remove
(
stack
),
table.remove
(
stack
)
local
Cal
=
{
[
"+"
]
=
valL
and
valR
,
[
"-"
]
=
valL
and
not
valR
,
[
"/"
]
=
valL
or
valR
}
local
temp
=
Cal
[
func
]
if
temp
==
nil
then
error
(
"invalid operators : "
..
func
)
end
stack
[
#
stack
+
1
]
=
temp
else
if
type
(
func
)
==
"string"
then
func
=
fusf
.
FindTables
(
func
,
fucf
,
Card
,
aux
)
fusf
.
CheckType
(
func
,
"function"
)
end
local
arg
=
arg_table
[
arg_ind
]
arg_ind
=
arg_ind
+
1
if
type
(
arg
)
~=
"table"
then
arg
=
{
arg
,
n
=
1
}
end
stack
[
#
stack
+
1
]
=
func
(
c
,
table.unpack
(
arg
,
1
,
arg
.
n
))
end
end
return
table.remove
(
stack
)
end
end
--- 判断卡片是否满足给定的过滤条件
-- @param c Card 欲判断的卡片对象
-- @param f string|function 过滤器(可为函数或其名称)
-- @param args table|string|number 传入的参数,可为字符串(含占位符)或具体值
-- @param ... 可选的占位参数(会传给 %1、%2 等)
-- @return boolean 若卡片符合条件,返回 true,否则返回 false
function
fucf
.
Filter
(
c
,
f
,
v
,
...
)
fusf
.
CheckArgType
(
"Filter"
,
1
,
c
,
"Card"
)
return
fucf
.
MakeCardFilter
(
f
,
v
,
...
)(
c
)
end
fucf
.
IsRk
=
fusf
.
MakeValCheck
(
"GetRank"
)
fucf
.
IsLv
=
fusf
.
MakeValCheck
(
"GetLevel"
)
fucf
.
IsRLv
=
fusf
.
MakeValCheck
(
"GetRitualLevel"
)
fucf
.
IsLk
=
fusf
.
MakeValCheck
(
"GetLink"
)
fucf
.
IsAtk
=
fusf
.
MakeValCheck
(
"GetAttack"
)
fucf
.
IsDef
=
fusf
.
MakeValCheck
(
"GetDefense"
)
fucf
.
IsSeq
=
fusf
.
MakeValCheck
(
"GetSequence"
)
fucf
.
IsPSeq
=
fusf
.
MakeValCheck
(
"GetPreviousSequence"
)
--- 判断卡片 c 是否“不等于”给定的 val
-- @param c Card 需要判断的卡片对象
-- @param val Card|Effect|Group|function 参考值,可以是卡片、效果、卡片组或过滤函数
-- @return boolean 如果 c 与 val 不匹配则返回 true,否则 false
--
-- - 若 val 是 Card,则比较是否为不同卡片
-- - 若 val 是 Effect,则比较 c 是否不是该效果的持有者
-- - 若 val 是 Group,则判断 c 是否不包含在该组内
-- - 若 val 是 function,则调用该函数传入 c,结果取反
-- - 其他情况返回 false
function
fucf
.
Not
(
c
,
val
)
fusf
.
CheckArgType
(
"Not"
,
1
,
c
,
"Card"
)
local
typ
=
fusf
.
CheckArgType
(
"Not"
,
2
,
val
,
"Card/Effect/function"
)
if
typ
==
"Card"
then
return
c
~=
val
elseif
aux
.
GetValueType
(
val
)
==
"Effect"
then
elseif
typ
==
"Effect"
then
return
c
~=
val
:
GetHandler
()
elseif
aux
.
GetValueType
(
val
)
==
"Group"
then
return
not
val
:
IsContains
(
c
)
elseif
aux
.
GetValueType
(
val
)
==
"function"
then
elseif
typ
==
"function"
then
return
not
val
(
c
)
end
return
false
end
--- 判断卡片是否属于指定系列(Set)
-- @param c Card 要检查的卡片
-- @param sets number|string 系列编号或由多个系列编号组成的字串(用 "/" 分隔)
-- @return boolean 若属于任一指定系列则返回 true,否则返回 false
--
-- fucf.IsSet(c, 0xfd1) → 检查是否属于系列 0xfd1
-- fucf.IsSet(c, "fd1+fd2") → 检查是否属于 0xfd1 或 0xfd2
function
fucf
.
IsSet
(
c
,
sets
)
if
type
(
sets
)
==
"number"
then
return
c
:
IsSetCard
(
sets
)
end
for
_
,
set
in
sets
:
ForCut
(
"fucf.IsSet"
,
"/"
)
do
fusf
.
CheckArgType
(
"IsSet"
,
1
,
c
,
"Card"
)
local
typ
=
fusf
.
CheckArgType
(
"IsSet"
,
2
,
sets
,
"number/string"
)
if
typ
==
"number"
then
return
c
:
IsSetCard
(
sets
)
end
for
_
,
set
in
sets
:
ForCut
(
"+"
)
do
set
=
tonumber
(
set
,
16
)
if
set
and
c
:
IsSetCard
(
set
)
then
return
true
end
end
return
false
end
function
fucf
.
AbleTo
(
c
,
loc
)
local
func
=
{
--- 判断卡片是否能以指定方式送去特定区域
-- @param c Card 要检查的卡片
-- @param loc string 目标区域代号,可选前缀 "*" 表示作为 cost
-- 可用区域代号:
-- "H" = 手牌(Hand)
-- "D" = 卡组(Deck)
-- "G" = 墓地(Grave)
-- "R" = 除外(Remove)
-- "E" = 额外卡组(Extra)
-- 例:"*G" 表示是否能作为 cost 被送去墓地
-- @return boolean 若能送去指定区域,则返回 true,否则返回 false
-- @raise 若 loc 非法,将抛出错误
function
fucf
.
AbleTo
(
c
,
loc
)
fusf
.
CheckArgType
(
"AbleTo"
,
1
,
c
,
"Card"
)
fusf
.
CheckArgType
(
"AbleTo"
,
2
,
loc
,
"string"
)
local
iscos
=
loc
:
match
(
"*"
)
loc
=
loc
:
match
(
"[HDGRE]"
)
if
not
loc
then
error
(
"InfixToPostfix : param 1 is invalid param"
,
2
)
end
local
locs
=
{
[
"H"
]
=
"Hand"
,
[
"D"
]
=
"Deck"
,
[
"G"
]
=
"Grave"
,
[
"R"
]
=
"Remove"
,
[
"E"
]
=
"Extra"
,
}
local
iscos
=
string.sub
(
loc
,
1
,
1
)
==
"*"
if
iscos
then
loc
=
string.sub
(
loc
,
2
)
end
return
Card
[
"IsAbleTo"
..
func
[
loc
]
..
(
iscos
and
"AsCost"
or
""
)](
c
)
return
Card
[
"IsAbleTo"
..
locs
[
loc
]
..
(
iscos
and
"AsCost"
or
""
)](
c
)
end
function
fucf
.
CanSp
(
c
,
e
,
typ
,
tp
,
nochk
,
nolimit
,
pos
,
totp
,
zone
)
if
not
tp
then
tp
=
e
:
GetHandlerPlayer
()
end
if
typ
==
SUMMON_TYPE_RITUAL
or
typ
==
"RI"
then
--- 检查 c 是否可以特殊召唤
-- @param c Card 要特殊召唤的卡片
-- @param e Effect 用于特殊召唤的效果
-- @param typ number|string 特召方式类型(数值或缩写,如 "RI" 表示仪式召唤)
-- @param tp number 特召的执行玩家(预设为 e:GetHandlerPlayer())
-- @param pos number|string 特召时卡片的表示形式(预设为 POS_FACEUP,可用字串)
-- @param lg Card |Group|nil 检查 lg 离开后的区域数量(有的话)
-- @param nochk boolean 是否忽略召唤条件(预设视 typ 而定)
-- @param nolimit boolean 是否忽略召唤次数限制(预设视 typ 而定)
-- @param totp number 特召后控制该卡的玩家(预设为 tp)
-- @param zone number 特召位置的区域 mask(预设为 0xff,即所有主怪兽区)
-- @return boolean 是否可以被特殊召唤
function
fucf
.
CanSp
(
c
,
e
,
typ
,
tp
,
pos
,
lg
,
nochk
,
nolimit
,
totp
,
zone
)
fusf
.
CheckArgType
(
"CanSp"
,
1
,
c
,
"Card"
)
if
not
c
:
IsType
(
TYPE_MONSTER
)
then
return
false
end
fusf
.
CheckArgType
(
"CanSp"
,
2
,
e
,
"Effect"
)
local
_
,
tp
=
fusf
.
CheckArgType
(
"CanSp"
,
4
,
tp
or
e
:
GetHandlerPlayer
(),
"player"
)
fusf
.
CheckArgType
(
"CanSp"
,
6
,
lg
,
"nil/Card/Group"
)
if
c
:
IsLocation
(
LOCATION_EXTRA
)
then
if
Duel
.
GetMZoneCount
(
tp
,
lg
)
==
0
then
return
false
end
else
if
Duel
.
GetLocationCountFromEx
(
tp
,
tp
,
lg
,
c
)
==
0
then
return
false
end
end
-- default chk
local
_
,
nochk
=
fusf
.
CheckArgType
(
"CanSp"
,
7
,
nochk
,
"nil/boolean"
)
local
_
,
nolimit
=
fusf
.
CheckArgType
(
"CanSp"
,
8
,
nolimit
,
"nil/boolean"
)
-- special default
local
_
,
typ
=
fusf
.
CheckArgType
(
"CanSp"
,
3
,
typ
or
0
,
"number/string"
)
if
typ
==
"RI"
then
typ
=
SUMMON_TYPE_RITUAL
nochk
=
nochk
or
false
nolimit
=
nolimit
or
true
if
nochk
==
nil
then
nochk
=
false
end
if
nolimit
==
nil
then
nolimit
=
true
end
end
return
c
:
IsCanBeSpecialSummoned
(
e
,
typ
,
tp
,
nochk
or
false
,
nolimit
or
false
,
pos
or
POS_FACEUP
,
totp
or
tp
,
zone
or
0xff
)
-- normal default
if
nochk
==
nil
then
nochk
=
false
end
if
nolimit
==
nil
then
nolimit
=
false
end
--
local
_
,
pos
=
fusf
.
CheckArgType
(
"CanSp"
,
5
,
pos
or
POS_FACEUP
,
"number/string"
)
pos
=
fusf
.
ParseConstantKey
(
"pos"
,
pos
)
local
_
,
totp
=
fusf
.
CheckArgType
(
"CanSp"
,
9
,
totp
or
tp
,
"player"
)
local
_
,
zone
=
fusf
.
CheckArgType
(
"CanSp"
,
10
,
zone
or
0xff
,
"number"
)
return
c
:
IsCanBeSpecialSummoned
(
e
,
typ
,
tp
,
nochk
,
nolimit
,
pos
,
totp
,
zone
)
end
function
fucf
.
IsCode
(
c
,
_cod
)
local
cod
if
aux
.
GetValueType
(
_cod
)
==
"number"
then
cod
=
{
_cod
}
elseif
aux
.
GetValueType
(
_cod
)
==
"string"
then
cod
=
_cod
:
Cut
(
"fucf.IsCode"
,
"+"
)
elseif
aux
.
GetValueType
(
_cod
)
==
"table"
then
cod
=
_cod
--- 判断 c 是否属于指定的卡号
-- @param c Card 要检查的卡片
-- @param cod number|string|table|Effect|Card|Group 可为单个卡号、以 "+" 分隔的字符串、卡号数组,或包含卡的 Group
-- @return boolean 是否匹配任意一个卡号
function
fucf
.
IsCode
(
c
,
cod
)
fusf
.
CheckArgType
(
"IsCode"
,
1
,
c
,
"Card"
)
return
c
:
IsCode
(
table.unpack
(
fusf
.
GetCodeTable
(
cod
)))
end
--- 判断 c 是否有卡名记述
-- @param c Card 要检查的卡片
-- @param cod number|string|table|Effect|Card|Group 为单个卡号、以 "+" 分隔的字符串、卡号数组,或包含卡的 Group
-- @return boolean 是否匹配任意一个卡名记述
function
fucf
.
HasCode
(
c
,
cod
)
fusf
.
CheckArgType
(
"HasCode"
,
1
,
c
,
"Card"
)
local
code_list
=
c
.
card_code_list
if
not
code_list
then
return
false
end
for
_
,
code
in
ipairs
(
fusf
.
GetCodeTable
(
cod
))
do
if
code_list
[
code
]
then
return
true
end
end
for
i
,
v
in
ipairs
(
cod
)
do
cod
[
i
]
=
fusf
.
M_chk
(
tonumber
(
v
))
return
false
end
--- 判断是否能将多张装备卡(eg)装备到指定怪兽卡 c
-- @param c Card 欲装备的目标怪兽
-- @param eg Effect|Card|Group 欲装备的卡(可为单一卡片或卡片群组)
-- @param tp number? 控制玩家(预设为 c 的控制者)
-- @return boolean 是否所有卡片都能合法装备给 c
function
fucf
.
CanEq
(
c
,
eg
,
tp
)
fusf
.
CheckArgType
(
"CanEq"
,
1
,
c
,
"Card"
)
eg
=
fusf
.
ToGroup
(
eg
)
tp
=
tp
or
c
:
GetControler
()
fusf
.
CheckArgType
(
"CanEq"
,
3
,
tp
,
"player"
)
if
Duel
.
GetLocationCount
(
tp
,
LOCATION_SZONE
)
<
#
eg
then
return
false
end
for
ec
in
aux
.
Next
(
eg
)
do
if
not
fucf
.
CanBeEq
(
ec
,
tp
,
c
,
true
)
then
return
false
end
end
return
c
:
IsCode
(
table.unpack
(
cod
))
return
true
end
function
fucf
.
HasCode
(
c
,
_cod
)
if
not
c
.
card_code_list
then
return
false
end
local
cod
,
has
if
aux
.
GetValueType
(
_cod
)
==
"number"
then
cod
=
{
_cod
}
elseif
aux
.
GetValueType
(
_cod
)
==
"string"
then
cod
=
_cod
:
Cut
(
"fucf.HasCode"
,
"+"
)
--- 判断卡片是否可以作为装备卡装备给指定对象
-- @param c Card 欲检查的装备卡(可为怪兽或装备魔法)
-- @param tp number? 预设视为控制装备卡的玩家,若 ec 存在则预设为 ec 的控制者
-- @param ec Card? 欲装备的目标怪兽卡
-- @param chk_loc boolean? 若为 true,跳过地区检查(例如已有预留 zone)
-- @return boolean 是否可被当作装备卡使用
function
fucf
.
CanBeEq
(
c
,
tp
,
ec
,
chk_loc
)
fusf
.
CheckArgType
(
"CanBeEq"
,
1
,
c
,
"Card"
)
if
ec
then
fusf
.
CheckArgType
(
"CanBeEq"
,
3
,
ec
,
"Card"
)
tp
=
tp
or
ec
:
GetControler
()
end
for
i
,
v
in
ipairs
(
cod
)
do
has
=
has
or
c
.
card_code_list
[
fusf
.
M_chk
(
tonumber
(
v
))]
fusf
.
CheckArgType
(
"CanBeEq"
,
2
,
tp
,
"player"
)
if
not
(
chk_loc
or
Duel
.
GetLocationCount
(
tp
,
LOCATION_SZONE
)
>
0
)
then
return
false
end
if
c
:
IsLocation
(
LOCATION_ONFIELD
)
then
if
not
c
:
IsFaceup
()
then
return
false
end
else
if
not
c
:
CheckUniqueOnField
(
tp
)
then
return
false
end
end
return
has
if
c
:
IsType
(
TYPE_MONSTER
)
then
return
c
:
IsControler
(
tp
)
or
c
:
IsAbleToChangeControler
()
elseif
c
:
IsType
(
TYPE_EQUIP
)
then
return
c
:
CheckEquipTarget
(
ec
)
end
error
(
"CanBeEq : mismatch card type"
,
2
)
end
function
fucf
.
CanEq
(
c
,
tp
)
return
c
:
CheckUniqueOnField
(
tp
)
and
Duel
.
GetLocationCount
(
tp
,
LOCATION_SZONE
)
>
0
--- 检查卡片 c 的种类为 cod 的标识效果的数量比较 n 的结果
-- @param c Card 要检查的卡片
-- @param cod number|string 旗标代码,可为数值或字串(将会正规化)
-- @param n number 可选,若提供则检查是否具有至少 n 层该 Flag
-- @return boolean Flag count 或 count 比较 n
function
fucf
.
IsFlag
(
c
,
cod
,
n
)
fusf
.
CheckArgType
(
"IsFlag"
,
1
,
c
,
"Card"
)
fusf
.
CheckArgType
(
"IsFlag"
,
3
,
n
,
"number"
)
return
fusf
.
GetFlag
(
c
,
cod
,
n
)
end
function
fucf
.
IsFlagLab
(
c
,
_cod
,
_lab
)
return
c
:
GetFlagEffectLabel
(
_cod
)
==
_lab
--- 检查卡片 c 的种类为 cod 的标识效果的 Label 是否是 lab
-- @param c Card 要检查的卡片
-- @param cod number|string 旗标代码,可为数值或字串(将会正规化)
-- @param lab number 要比较的 Label
-- @return boolean Label 或 Label == lab
function
fucf
.
IsFlagLab
(
c
,
cod
,
lab
)
fusf
.
CheckArgType
(
"IsFlagLab"
,
1
,
c
,
"Card"
)
fusf
.
CheckArgType
(
"IsFlagLab"
,
3
,
lab
,
"number"
)
return
fusf
.
GetFlagLabel
(
c
,
cod
,
lab
)
end
--- 检查卡片 c 的当前控制者是否是 p
-- @param c Card 要检查的卡片
-- @param p number 要比较的控制者玩家(0 或 1)
-- @return boolean 卡片 c 的当前控制者是否是 p
function
fucf
.
IsCon
(
c
,
p
)
if
type
(
p
)
==
"string"
then
p
=
tonumber
(
p
)
end
fusf
.
CheckArgType
(
"IsCon"
,
1
,
c
,
"Card"
)
fusf
.
CheckArgType
(
"IsCon"
,
2
,
p
,
"player"
)
return
c
:
IsControler
(
p
)
end
fucf
.
InGroup
=
function
(
c
,
g
)
return
g
:
IsContains
(
c
)
end
--- 检查卡片组 g 中是否存在卡片 c
-- @param c Card 要检查的卡片
-- @param g Group 要检查的卡片组
-- @return boolean 卡片组 g 中是否存在卡片 c
function
fucf
.
InG
(
c
,
g
)
fusf
.
CheckArgType
(
"InG"
,
1
,
c
,
"Card"
)
fusf
.
CheckArgType
(
"InG"
,
2
,
g
,
"Group"
)
return
g
:
IsContains
(
c
)
end
--- 检查卡片 c 没有受王家长眠之谷的影响,并且检查当前连锁能否被无效
-- @param c Card 要检查的卡片
-- @return boolean 卡片 c 没有受王家长眠之谷的影响,并且当前连锁能被无效
function
fucf
.
GChk
(
c
)
fusf
.
CheckArgType
(
"GChk"
,
1
,
c
,
"Card"
)
return
not
c
:
IsHasEffect
(
EFFECT_NECRO_VALLEY
)
and
Duel
.
IsChainDisablable
(
0
)
end
--- 检查卡片 c 当前位置是否是 loc
-- 注:loc == M 时,怪兽召唤(广义的)之际或被无效会返回 false
-- loc == S 时,魔陷发动无效会返回false
-- @param c Card 要检查的卡片
-- @param loc string|number 区域表示
-- @return boolean 检查卡片 c 当前位置是否是 loc
function
fucf
.
IsLoc
(
c
,
loc
)
fusf
.
CheckArgType
(
"IsLoc"
,
1
,
c
,
"Card"
)
loc
=
fusf
.
GetLoc
(
loc
)
return
c
:
IsLocation
(
loc
)
end
--- 检查卡片 c 之前的位置是否是 loc
-- @param c Card 要检查的卡片
-- @param loc string|number 区域表示
-- @return boolean 检查卡片 c 之前的位置是否是 loc
function
fucf
.
IsPLoc
(
c
,
loc
)
fusf
.
CheckArgType
(
"IsPLoc"
,
1
,
c
,
"Card"
)
loc
=
fusf
.
GetLoc
(
loc
)
return
c
:
IsPreviousLocation
(
loc
)
end
fucf
.
TgChk
=
Card
.
IsCanBeEffectTarget
fucf
.
GChk
=
function
(
c
)
return
not
c
:
IsHasEffect
(
EFFECT_NECRO_VALLEY
)
end
fucf
.
IsImm
=
Card
.
IsImmuneToEffect
fucf
.
IsPCon
=
Card
.
IsPreviousControler
fucf
.
IsLoc
=
function
(
c
,
loc
)
return
c
:
IsLocation
(
fusf
.
Get_Loc
(
loc
))
end
fucf
.
IsPLoc
=
function
(
c
,
loc
)
return
c
:
IsPreviousLocation
(
fusf
.
Get_Loc
(
loc
))
end
fucf
.
IsRea
=
fusf
.
Is_Cons
(
"GetReason"
,
"rea"
)
fucf
.
IsTyp
=
fusf
.
Is_Cons
(
"GetType"
,
"typ"
)
fucf
.
IsSTyp
=
fusf
.
Is_Cons
(
"GetSummonType"
,
"styp"
)
fucf
.
IsOTyp
=
fusf
.
Is_Cons
(
"GetOriginalType"
,
"typ"
)
fucf
.
IsAtt
=
fusf
.
Is_Cons
(
"GetAttribute"
,
"att"
)
fucf
.
IsRac
=
fusf
.
Is_Cons
(
"GetRace"
,
"rac"
)
fucf
.
IsPos
=
fusf
.
Is_Cons
(
"GetPosition"
,
"pos"
,
function
(
card_val
,
val
)
return
card_val
|
val
==
val
end
)
fucf
.
IsPPos
=
fusf
.
Is_Cons
(
"GetPreviousPosition"
,
"pos"
,
function
(
card_val
,
val
)
return
card_val
|
val
==
val
end
)
fucf
.
IsRea
=
fusf
.
MakeConsCheck
(
"GetReason"
,
"rea"
,
"&"
)
fucf
.
IsTyp
=
fusf
.
MakeConsCheck
(
"GetType"
,
"typ"
,
"&"
)
fucf
.
IsSTyp
=
fusf
.
MakeConsCheck
(
"GetSummonType"
,
"styp"
,
"&"
)
fucf
.
IsOTyp
=
fusf
.
MakeConsCheck
(
"GetOriginalType"
,
"typ"
,
"&"
)
fucf
.
IsAtt
=
fusf
.
MakeConsCheck
(
"GetAttribute"
,
"att"
,
"&"
)
fucf
.
IsRac
=
fusf
.
MakeConsCheck
(
"GetRace"
,
"rac"
,
"&"
)
fucf
.
IsPos
=
fusf
.
MakeConsCheck
(
"GetPosition"
,
"pos"
,
"|"
)
fucf
.
IsPPos
=
fusf
.
MakeConsCheck
(
"GetPreviousPosition"
,
"pos"
,
"|"
)
--[[
---------------------------------------------------------------- procedure
function fucf.RMFilter(c, rf, e, tp, g1, g2, level_function, greater_or_equal, chk)
if rf and not rf(c, e, tp, chk) then return false end
if
not
fucf
.
Filter
(
rc
,
"IsTyp+CanSp"
,
"RI+M"
,
{
e
,
SUMMON_TYPE_RITUAL
,
tp
,
false
,
true
})
then
return
false
end
if not fucf.Filter(rc, "IsTyp+CanSp", "RI+M", {e,
"RI"
}) then return false end
local g = g1:Filter(Card.IsCanBeRitualMaterial, c, c) + (g2 or Group.CreateGroup())
g = g:Filter(c.mat_filter or aux.TRUE, c, tp)
local lv = level_function(c)
...
...
@@ -166,4 +458,5 @@ function fucf.RMFilter(c, rf, e, tp, g1, g2, level_function, greater_or_equal, c
local res = g:CheckSubGroup(Auxiliary.RitualCheck, 1, lv, tp, c, lv, greater_or_equal)
Auxiliary.GCheckAdditional = nil
return res
end
\ No newline at end of file
end
--]]
\ No newline at end of file
expansions/script/c20099998.lua
View file @
14515cb1
dofile
(
"expansions/script/c20099999.lua"
)
if
fusf
then
return
end
fusf
=
{
}
dofile
(
"expansions/script/c20099999.lua"
)
fusf
=
{}
fudf
=
{}
fudf
.
__index
=
fudf
--------------------------------------"Debug function"
--- 若处于调试模式则输出函数调用信息和参数
-- @param log fudf|fuef|number log 实例/fuef 实例/层级数字
-- @param name string 函数名称
-- @param ... any 参数列表
-- @return fudf log 实例
function
fudf
.
StartLog
(
log
,
name
,
...
)
if
not
fuef
.
DebugMode
then
return
fudf
end
local
typ
=
fusf
.
CheckArgType
(
"StartLog"
,
1
,
log
,
"number/fudf/fuef"
)
fusf
.
CheckArgType
(
"StartLog"
,
2
,
name
,
"string"
)
local
lv
if
typ
==
"number"
then
lv
=
log
elseif
typ
==
"fuef"
then
lv
=
log
.
isinit
and
2
or
0
else
lv
=
log
.
depth
end
local
indent
=
(
"
\t
"
):
rep
(
lv
)
local
arg_str
=
""
local
args
=
{
...
}
local
len
=
select
(
"#"
,
...
)
if
len
>
0
then
local
out
=
{}
for
i
=
1
,
len
do
local
val
=
args
[
i
]
local
typ
=
type
(
val
)
if
typ
==
"userdata"
then
typ
=
fusf
.
Type
(
val
)
elseif
typ
==
"number"
or
typ
==
"boolean"
then
typ
=
tostring
(
val
)
elseif
typ
==
"string"
then
typ
=
'"'
..
val
..
'"'
end
table.insert
(
out
,
typ
)
end
arg_str
=
table.concat
(
out
,
", "
)
end
Debug
.
Message
((
"
\t
%s[CALL] : %s(%s)"
):
format
(
indent
,
name
,
arg_str
))
return
setmetatable
({
depth
=
lv
+
1
},
fudf
)
end
--- 若处于调试模式则印出 msg
-- @param msg any 调试信息
function
fudf
:
Info
(
msg
)
if
not
fuef
.
DebugMode
then
return
end
local
indent
=
(
"
\t
"
):
rep
(
self
.
depth
)
Debug
.
Message
(
"
\t
"
..
indent
..
"[INFO] : "
..
msg
)
end
--- 若处于调试模式则印出 msg
-- @param msg any 调试信息
function
fusf
.
Info
(
msg
)
if
not
fuef
.
DebugMode
then
return
end
Debug
.
Message
(
"
\t
[INFO] : "
..
msg
)
end
--------------------------------------"String function"
function
string
:
Cut
(
_from
,
_cut
)
_cut
=
_cut
or
","
-- default
if
type
(
self
)
~=
"string"
or
type
(
_cut
)
~=
"string"
then
local
_p
=
(
type
(
self
)
~=
"string"
and
"1"
or
""
)
..
(
type
(
_cut
)
~=
"string"
and
"2"
or
""
)
Debug
.
Message
(
"Invalid parameter "
..
_p
..
" in string:Cut <- "
..
_from
)
return
nil
end
local
str
,
list
,
char
=
self
..
_cut
,
{},
""
for
unit
in
str
:
gmatch
(
"."
)
do
if
unit
==
_cut
then
table.insert
(
list
,
char
)
char
=
""
--- 将字串以指定字元切割,保留空字串片段
-- @param cut string 分隔符,预设为逗号 ","
-- @return table 字串片段阵列,连续分隔符中间的空字串也会被保留
-- @raise 当 self 或 cut 非字串型态时抛出错误
function
string
:
Cut
(
cut
)
cut
=
cut
or
","
if
type
(
cut
)
~=
"string"
then
error
(
"Cut : param 1 should be string, got "
..
type
(
cut
),
2
)
end
local
res
,
part
=
{},
""
for
char
in
(
self
..
cut
):
gmatch
(
"."
)
do
if
char
==
cut
then
table.insert
(
res
,
part
)
part
=
""
else
char
=
char
..
unit
part
=
part
..
char
end
end
return
list
return
res
end
function
string
:
ForCut
(
_from
,
_cut
)
_cut
=
_cut
or
","
-- default
if
type
(
self
)
~=
"string"
or
type
(
_cut
)
~=
"string"
then
local
_p
=
(
type
(
self
)
~=
"string"
and
"1"
or
""
)
..
(
type
(
_cut
)
~=
"string"
and
"2"
or
""
)
Debug
.
Message
(
"Invalid parameter "
..
_p
..
" in string:ForCut <- "
..
_from
)
return
nil
end
local
list
=
self
:
Cut
(
"string:ForCut <- "
..
_from
,
_cut
)
--- 返回一个迭代器,遍历按指定分隔符切割后的字符串片段
-- @param cut string 分隔符,默认值为逗号 ","
-- @return function 迭代函数,每次调用返回当前索引和对应的字符串片段
-- @usage
-- for i, s in ("a,b,,c"):ForCut(",") do
-- print(i, s)
-- end
function
string
:
ForCut
(
cut
)
local
list
=
self
:
Cut
(
cut
)
local
ind
,
max
=
0
,
#
list
return
function
()
if
ind
>=
max
then
return
nil
end
...
...
@@ -35,159 +101,320 @@ function string:ForCut(_from, _cut)
return
ind
,
list
[
ind
]
end
end
--------------------------------------"Error function"
--- 检查 from 函数的参数是否为空,若为空则报错
-- @param from string 呼叫来源,用于错误提示
-- @param ... any 任意数量的参数
-- @raise 若参数皆为空,则触发错误,提示呼叫位置
function
fusf
.
CheckEmptyArgs
(
from
,
...
)
if
not
fusf
.
IsEmpty
(
...
)
then
return
end
error
(
from
..
" : Argument cannot be empty"
,
3
)
end
--- 检查 from 函数的第 i 个参数 val 的类型是否为 typs,否则报错
-- @param from string 呼叫来源,用于错误提示
-- @param i number 参数位置(从 1 开始)
-- @param val any 要检查的值
-- @param typs string 允许的类型,类型名以 `/` 分隔(如 "string/number")
-- @return string, any 若匹配,返回其匹配的类型及原值
-- @raise 若类型不符,报错并显示位置与类型资讯
function
fusf
.
CheckArgType
(
from
,
i
,
val
,
typs
)
local
is_typ
,
typ
=
pcall
(
fusf
.
CheckTypes
,
val
,
typs
)
if
is_typ
then
return
typ
,
val
end
local
err_msg
=
"%s : param %d should be %s, got %s"
err_msg
=
err_msg
:
format
(
from
,
i
,
typs
,
fusf
.
Type
(
val
))
error
(
err_msg
,
3
)
end
--------------------------------------"Support function"
function
fusf
.
Debug
(
msg
)
if
fuef
.
DebugMode
then
Debug
.
Message
(
msg
)
end
end
function
fusf
.
ValToDebug
(
...
)
local
tab
,
res
=
{
...
},
""
for
i
=
1
,
select
(
"#"
,
...
)
do
if
type
(
tab
[
i
])
==
"userdata"
then
res
=
res
..
", "
..
aux
.
GetValueType
(
tab
[
i
])
else
res
=
res
..
", "
..
tostring
(
tab
[
i
])
--- 更精确地取得物件的类型名称,支援 Card/Effect/Group/fuef 等
-- @param val 任意值
-- @return string 自定义类型名称或 Lua 原生类型名称
function
fusf
.
Type
(
val
)
local
typ
=
type
(
val
)
if
typ
==
"userdata"
then
return
aux
.
GetValueType
(
val
)
elseif
typ
==
"table"
then
local
metatable
=
getmetatable
(
val
)
if
metatable
==
fuef
then
return
"fuef"
elseif
metatable
==
fudf
then
return
"fudf"
end
end
return
res
:
sub
(
3
)
return
typ
end
function
fusf
.
Getcm
(
val
)
local
c
=
fusf
.
ToCard
(
val
,
true
)
if
getmetatable
(
val
)
==
fuef
then
c
=
val
.
e
:
GetOwner
()
end
if
not
c
then
Debug
.
Message
(
"Cant Get cm "
..
tostring
(
val
))
return
{
}
end
return
_G
[
"c"
..
val
.
e
:
GetOwner
():
GetCode
()]
end
function
fusf
.
CutHex
(
val
,
add
)
-- 转换 typ 等并分割
if
type
(
val
)
==
"string"
then
return
val
end
add
=
add
or
"+"
local
parts
=
{}
local
bit
=
1
while
val
>
0
do
if
val
%
2
==
1
then
table.insert
(
parts
,
string.format
(
"0x%X"
,
bit
))
--- 验证 val 的类型是否为 typ,若为 "player" 类型则进一步检查值是否合法(0 或 1)
-- @param val any 欲检查的值
-- @param typ string 预期的类型名称(如 "Card", "string", "number", "player" 等)
-- @return any 若类型正确,返回原值
-- @raise 若类型不符,会根据 arg_ind 抛出更明确的错误(包含参数编号)
function
fusf
.
CheckType
(
val
,
typ
)
if
type
(
typ
)
~=
"string"
then
error
((
"param %d should be %s, got %s"
):
format
(
2
,
"string"
,
type
(
typ
)),
2
)
end
if
typ
==
"player"
then
if
val
==
0
or
val
==
1
then
return
val
else
error
(
"invalid player index '"
..
val
..
"' (expected 0 or 1)"
,
3
)
end
val
=
math.floor
(
val
/
2
)
bit
=
bit
*
2
end
for
i
=
1
,
math.floor
(
#
parts
/
2
)
do
parts
[
i
],
parts
[
#
parts
-
i
+
1
]
=
parts
[
#
parts
-
i
+
1
],
parts
[
i
]
local
val_type
=
fusf
.
Type
(
val
)
if
val_type
==
typ
then
return
val
end
error
((
"should be %s, got %s"
):
format
(
typ
,
val_type
),
3
)
end
--- 验证 val 的 type 是否在 typs 内(以 "/" 分隔)
-- @param val any 欲检查的值
-- @param typs string 多个类型名称组成的字符串,如 "number/string"
-- @return string, any 若匹配,返回其匹配的类型及原值
-- @raise 若不符合任何类型,会抛出详细错误信息
function
fusf
.
CheckTypes
(
val
,
typs
)
typs
=
fusf
.
CheckType
(
typs
,
"string"
)
local
val_type
=
fusf
.
Type
(
val
)
for
_
,
typ
in
typs
:
ForCut
(
"/"
)
do
if
pcall
(
fusf
.
CheckType
,
val
,
typ
)
then
return
typ
,
val
end
end
return
table.concat
(
parts
,
add
)
error
((
"should be %s, got %s"
):
format
(
typs
,
val_type
),
3
)
end
function
fusf
.
ToCard
(
val
,
is_owner
)
local
g
=
fusf
.
ToGroup
(
val
,
is_owner
)
if
g
then
return
g
:
GetFirst
()
end
return
false
--- 从 fucs 下指定子表中查找常量值,或返回整个表
-- @param table_key string 欲查找的子表名称(如 "cod")
-- @param key? string 欲查找的键名称(可省略,省略时返回整个子表)
-- @return any 找到的值或整个子表
-- @raise 若子表不存在、键无效,则报错
function
fusf
.
Findfucs
(
table_key
,
key
)
fusf
.
CheckArgType
(
"Findfucs"
,
1
,
table_key
,
"string"
)
local
const_table
=
fusf
.
CheckType
(
fucs
[
table_key
],
"table"
)
if
not
key
then
return
const_table
end
return
fusf
.
FindTables
(
key
,
const_table
)
end
--- 在多个表中依序查找键值
-- @param key string 欲查找的键名称
-- @param ... table 可变参数,每个都是待查找的表格
-- @return any 若找到键,返回对应的值;否则抛出错误
function
fusf
.
FindTables
(
key
,
...
)
fusf
.
CheckArgType
(
"FindTables"
,
1
,
key
,
"string"
)
for
i
,
tab
in
ipairs
{
...
}
do
fusf
.
CheckArgType
(
"FindTables"
,
i
+
1
,
tab
,
"table"
)
if
tab
[
key
]
then
return
tab
[
key
]
end
end
error
(
"unknown constant key '"
..
key
..
"' in table"
,
2
)
end
--- 将 val 转为对应的 Group
-- @param val Card|Effect|Group 欲处理的对象
-- @param is_owner boolean 若为 Effect 时,是否取其 owner 而非 handler
-- @return Group 对应的 Group
-- @raise 若类型非 Card/Effect/Group,则抛出错误
function
fusf
.
ToGroup
(
val
,
is_owner
)
local
typ
=
aux
.
GetValueType
(
val
)
local
typ
=
fusf
.
CheckArgType
(
"ToGroup"
,
1
,
val
,
"Card/Effect/Group"
)
if
typ
==
"Effect"
then
return
Group
.
FromCards
(
is_owner
and
val
:
GetOwner
()
or
val
:
GetHandler
())
elseif
typ
==
"Card"
then
return
Group
.
FromCards
(
val
)
elseif
typ
==
"Group"
then
return
val
end
return
false
return
val
-- typ == "Group"
end
--- 将 val 转为对应的卡片组 table
-- @param val Card|Effect|Group 欲处理的对象
-- @return table 对应的 table
-- @raise 若无法转换为非空 Group,则抛出错误
function
fusf
.
ToGroupTable
(
val
)
local
g
=
fusf
.
ToGroup
(
val
)
if
#
g
==
0
then
error
(
"ToGroup("
..
fusf
.
Type
(
val
)
..
") is empty Group"
,
2
)
end
local
tab
=
{}
for
c
in
aux
.
Next
(
g
)
do
table.insert
(
tab
,
c
)
end
return
tab
end
--- 将 val 转为对应的 Card
-- @param val Card|Effect|Group 欲处理的对象
-- @param is_owner boolean 若为 Effect 时,是否取其 owner 而非 handler
-- @return Card 对应的 Card
-- @raise 若无法转换为非空 Group,则抛出错误
function
fusf
.
ToCard
(
val
,
is_owner
)
local
c
=
fusf
.
ToGroup
(
val
,
is_owner
):
GetFirst
()
if
c
then
return
c
end
error
(
"ToGroup("
..
fusf
.
Type
(
val
)
..
") is empty Group"
,
2
)
end
function
fusf
.
IsNil
(
...
)
local
vals
=
{
...
}
if
#
vals
==
0
then
return
true
end
--- 判断传入值是否为 nil, "", {}
-- @param ... 任意数量的参数
-- @return boolean 是否为 nil, "", {}
function
fusf
.
IsEmpty
(
...
)
local
vals
=
{
...
}
if
select
(
"#"
,
...
)
==
0
then
return
true
end
vals
=
#
vals
==
1
and
vals
[
1
]
or
vals
if
type
(
vals
)
==
"string"
then
return
vals
==
""
-- 非空字串
return
vals
==
""
elseif
type
(
vals
)
==
"table"
then
return
not
next
(
vals
)
-- 表有內容
end
return
not
vals
end
function
fusf
.
NotNil
(
...
)
return
not
fusf
.
IsNil
(
...
)
end
function
fusf
.
Get_Constant
(
_constable
,
_vals
)
-- string chk
if
type
(
_vals
)
~=
"string"
then
return
_vals
end
local
res
=
0
-- cod chk
if
_constable
==
"cod"
then
-- EVENT_CUSTOM
if
_vals
:
match
(
"CUS"
)
then
_vals
=
_vals
:
sub
(
5
)
-- owner code or number
res
=
EVENT_CUSTOM
+
fusf
.
M_chk
(
_vals
)
-- EVENT_PHASE or EVENT_PHASE_START
elseif
_vals
:
match
(
"PH"
)
then
for
_
,
val
in
_vals
:
ForCut
(
"Get_Constant_1"
,
"+"
)
do
local
_constable
=
val
:
match
(
"PH"
)
and
"cod"
or
"pha"
res
=
res
+
fucs
[
_constable
][
val
]
return
next
(
vals
)
==
nil
end
return
vals
==
nil
end
--- 根据 val 取得其对应的全局 cm 表
-- @param val Card|Effect|Group|fuef
-- @return table 对应的 cm 表
-- @raise 若无法取得卡片对象则抛出错误
function
fusf
.
Getcm
(
val
)
local
typ
=
fusf
.
CheckArgType
(
"Getcm"
,
1
,
val
,
"Card/Effect/Group/fuef"
)
local
c
if
typ
==
"fuef"
then
c
=
fusf
.
CheckType
(
val
.
e
,
"Effect"
):
GetOwner
()
else
c
=
fusf
.
ToCard
(
val
,
true
)
end
return
fusf
.
CheckType
(
_G
[
"c"
..
c
:
GetCode
()],
"table"
)
end
--- 规范化卡号,若小于 1000,则加上 base (20000000)
-- @param id number|string
-- @param base number 可选,若卡号 < 1000,将加上此值(默认 20000000)
-- @return number 规范化后的卡号
-- @raise 若 id 无法转为数字,或 base 非数字,将抛出错误
function
fusf
.
NormalizeID
(
id
,
base
)
id
=
tonumber
(
id
)
fusf
.
CheckArgType
(
"NormalizeID"
,
1
,
id
,
"number"
)
fusf
.
CheckArgType
(
"NormalizeID"
,
2
,
base
,
"nil/number"
)
base
=
base
or
20000000
return
id
<
1000
and
id
+
base
or
id
end
--- 解析 val 并回传一个对应的卡号 table
-- @param val any 可以是 Group、Card、Effect、number、string(用 + 分隔的代码)、table 等
-- @return table<number> 包含标准化过的卡号 table
function
fusf
.
GetCodeTable
(
val
)
local
result
=
{}
local
to_g
,
g
=
pcall
(
fusf
.
ToGroup
,
val
)
if
to_g
then
for
gc
in
aux
.
Next
(
g
)
do
for
_
,
cod
in
ipairs
{
gc
:
GetCode
()
}
do
table.insert
(
result
,
cod
)
end
end
if
res
~=
0
then
return
res
end
return
result
end
-- find _constable
local
vals
,
cons
,
des
=
_vals
:
Cut
(
"Get_Constant_2"
,
"+"
),
fucs
[
_constable
]
for
i
=
#
vals
,
1
,
-
1
do
local
_val
=
vals
[
i
]
des
=
fucs
.
des
[
_val
]
or
des
res
=
res
+
cons
[
_val
]
local
code_table
=
{}
local
typ
=
fusf
.
CheckTypes
(
val
,
"number/string/table"
)
if
typ
==
"number"
then
code_table
=
{
val
}
elseif
typ
==
"string"
then
code_table
=
val
:
Cut
(
"+"
)
elseif
typ
==
"table"
then
code_table
=
val
end
return
res
,
des
for
_
,
cod
in
ipairs
(
code_table
)
do
table.insert
(
result
,
fusf
.
NormalizeID
(
cod
))
end
if
#
result
>
0
then
return
result
end
error
(
"GetCodeTable : get empty table"
,
3
)
end
function
fusf
.
Get_Loc
(
_loc_s
,
_loc_o
,
_from
)
-- nil chk
if
not
fusf
.
NotNil
(
_loc_s
,
_loc_o
)
then
Debug
.
Message
(
"Get_Loc <- "
..
_from
)
return
nil
end
local
p_loc
=
{
0
,
0
}
-- _loc_o chk
if
_loc_o
then
p_loc
[
2
]
=
_loc_o
end
-- _loc_s string chk
if
type
(
_loc_s
)
~=
"string"
then
p_loc
[
1
]
=
_loc_s
return
table.unpack
(
p_loc
)
end
-- _loc_s is string and find fucs.ran
local
_res
=
0
for
i
,
loc
in
_loc_s
:
ForCut
(
"Get_Loc"
,
"+"
)
do
for
j
=
1
,
#
loc
do
p_loc
[
i
]
=
p_loc
[
i
]
+
fucs
.
ran
[
loc
:
sub
(
j
,
j
):
upper
()]
--- 将整数转换为 16 进制 string 表示(以 ", " 或指定符号连接)
-- @param val number|string 欲转换的数值,若为字串则直接返回
-- @return string 分解后的 16 进制表示,如 "0x1, 0x2, 0x8"
-- @raise 当参数类型不符时抛出错误
function
fusf
.
CutHex
(
val
)
local
typ
=
fusf
.
CheckArgType
(
"CutHex"
,
1
,
val
,
"string/number"
)
if
typ
==
"string"
then
return
val
end
local
parts
,
bit
=
{},
1
while
val
>
0
do
if
val
%
2
==
1
then
table.insert
(
parts
,
1
,
string.format
(
"0x%X"
,
bit
))
end
val
=
math.floor
(
val
/
2
)
bit
=
bit
*
2
end
return
table.
unpack
(
p_loc
)
return
table.
concat
(
parts
,
", "
)
end
function
fusf
.
M_chk
(
val
)
-- val : number|string
val
=
tonumber
(
val
)
if
val
<
19999999
then
return
val
+
20000000
end
return
val
--- 转换成前后两个区域后传回(self_loc包含两个区域时以+分开)
-- @param self_loc string|number 自己的区域表示,可为形如 "HM+M" 的字串,或直接为数值
-- @param oppo_loc number|nil 对方的区域数值
-- @return number, number 自己和对方的区域值
-- @raise 当 self_loc 和 oppo_loc 同时为空时抛出错误
-- @raise 当 oppo_loc 非 number or nil 时抛出错误
-- @raise 当 self_loc 字符无法在 fucs.ran 中找到对应值时抛出错误
function
fusf
.
GetLoc
(
self_loc
,
oppo_loc
)
fusf
.
CheckEmptyArgs
(
"GetLoc"
,
self_loc
,
oppo_loc
)
local
typ
=
fusf
.
CheckArgType
(
"GetLoc"
,
1
,
self_loc
,
"string/number"
)
fusf
.
CheckArgType
(
"GetLoc"
,
2
,
oppo_loc
,
"nil/number"
)
local
loc_list
=
{
0
,
0
}
if
oppo_loc
then
loc_list
[
2
]
=
oppo_loc
end
if
typ
==
"number"
then
loc_list
[
1
]
=
self_loc
return
table.unpack
(
loc_list
)
end
for
i
,
locs
in
self_loc
:
ForCut
(
"+"
)
do
for
j
=
1
,
#
locs
do
local
ch
=
locs
:
sub
(
j
,
j
):
upper
()
loc_list
[
i
]
=
loc_list
[
i
]
+
fusf
.
Findfucs
(
"ran"
,
ch
)
end
end
return
table.unpack
(
loc_list
)
end
function
fusf
.
PostFix_Trans
(
_str
,
...
)
local
vals
,
res
,
temp
,
i
=
{
...
},
{
},
{
},
1
while
i
<=
#
_str
do
local
ch
=
_str
:
sub
(
i
,
i
)
--- 将带变量占位符的中缀表达式转换成后缀表达式(逆波兰表达式)
-- 支持字母变量、占位符 %n 替换参数、括号以及 + - / ~ 运算符
-- @param expr string 形如 "A+(B-%1)/C" 的表达式字符串
-- @param ... 传入参数,用于替换表达式中的 %n 占位符(n为数字)
-- @return table 后缀表达式数组,元素为字符串或函数
function
fusf
.
InfixToPostfix
(
expr
,
...
)
fusf
.
CheckArgType
(
"InfixToPostfix"
,
1
,
expr
,
"string"
)
if
expr
==
""
then
error
(
"InfixToPostfix : param 1 is invalid param"
,
2
)
end
local
args
,
res
,
temp
,
i
=
{
...
},
{},
{},
1
while
i
<=
#
expr
do
local
ch
=
expr
:
sub
(
i
,
i
)
if
ch
:
match
(
"%a"
)
then
_
,
i
,
ch
=
_st
r
:
find
(
"(%a+)"
,
i
)
_
,
i
,
ch
=
exp
r
:
find
(
"(%a+)"
,
i
)
table.insert
(
res
,
ch
)
elseif
ch
==
"%"
then
_
,
i
,
ch
=
_str
:
find
(
"(%d+)"
,
i
)
ch
=
vals
[
tonumber
(
ch
)]
if
type
(
ch
)
==
"boolean"
then
local
b
=
ch
ch
=
function
()
return
b
end
_
,
i
,
ch
=
expr
:
find
(
"(%d+)"
,
i
)
if
not
ch
then
error
(
"'%' must be followed by a number at position : "
..
expr
,
2
)
end
table.insert
(
res
,
ch
)
local
val
=
args
[
tonumber
(
ch
)]
if
val
==
nil
then
error
(
"argument %"
..
ch
..
" is nil"
,
2
)
elseif
type
(
val
)
==
"boolean"
then
local
b
=
val
val
=
function
()
return
b
end
end
table.insert
(
res
,
val
)
elseif
ch
==
"("
or
ch
==
"~"
then
table.insert
(
temp
,
ch
)
elseif
ch
==
")"
then
while
#
temp
>
0
and
temp
[
#
temp
]
~=
"("
do
table.insert
(
res
,
table.remove
(
temp
))
local
found_left_paren
=
false
while
#
temp
>
0
do
local
op
=
table.remove
(
temp
)
if
op
==
"("
then
found_left_paren
=
true
break
else
table.insert
(
res
,
op
)
end
end
if
not
found_left_paren
then
error
(
"unexpected symbol near ')' : "
..
expr
,
2
)
end
table.remove
(
temp
)
elseif
ch
==
"+"
or
ch
==
"-"
then
while
#
temp
>
0
and
temp
[
#
temp
]
~=
"("
do
table.insert
(
res
,
table.remove
(
temp
))
...
...
@@ -198,6 +425,8 @@ function fusf.PostFix_Trans(_str, ...)
table.insert
(
res
,
table.remove
(
temp
))
end
table.insert
(
temp
,
ch
)
else
error
(
"unexpected character '"
..
ch
..
"' : "
..
expr
,
2
)
end
if
temp
[
#
temp
]
==
"~"
and
ch
:
match
(
"^[%a%)%%]"
)
then
table.insert
(
res
,
table.remove
(
temp
))
...
...
@@ -205,260 +434,644 @@ function fusf.PostFix_Trans(_str, ...)
i
=
i
+
1
end
while
#
temp
>
0
do
table.insert
(
res
,
table.remove
(
temp
))
local
op
=
table.remove
(
temp
)
if
op
==
"("
then
error
(
"expected ')' to close '(' : "
..
expr
,
2
)
end
table.insert
(
res
,
op
)
end
return
res
end
function
fusf
.
IsN
(
_func
)
return
function
(
_c
,
_val
,
_exval
)
local
c_val
=
Card
[
_func
](
_c
,
_exval
)
if
type
(
_val
)
==
"string"
then
local
oper
,
_val
=
_val
:
match
(
"[%+%-]"
),
_val
:
match
(
"%d+"
)
_val
=
tonumber
(
_val
)
if
oper
==
"+"
then
return
c_val
>=
_val
elseif
oper
==
"-"
then
return
c_val
<=
_val
end
return
c_val
==
_val
--- 构造一个用于判断卡片某个数值大小关系的函数
-- @param getter string Card 的函数名,如 "GetLevel"
-- @return function(c, target, ...) -> boolean
function
fusf
.
MakeValCheck
(
getter
)
local
card_func
=
fusf
.
CheckType
(
Card
[
getter
],
"function"
)
local
from
=
"MakeValCheck("
..
getter
return
function
(
c
,
target
,
...
)
fusf
.
CheckArgType
(
from
,
1
,
c
,
"Card"
)
local
typ
=
fusf
.
CheckArgType
(
from
,
2
,
target
,
"number/string"
)
local
card_val
=
fusf
.
CheckType
(
card_func
(
c
,
...
),
"number"
)
if
typ
==
"number"
then
return
target
>
0
and
card_val
==
target
or
card_val
<=
-
target
end
local
oper
=
target
:
match
(
"[%+%-]"
)
local
num
=
tonumber
(
target
:
match
(
"%d+"
))
if
oper
==
"+"
then
return
card_val
>=
num
elseif
oper
==
"-"
then
return
card_val
<=
num
end
if
_val
>
0
then
return
c_val
==
_val
end
return
c_val
<=
-
_val
-- _val = -n
return
card_val
==
num
end
end
function
fusf
.
Is_Cons
(
_func
,
_key
,
_cal
)
_cal
=
_cal
or
function
(
card_val
,
val
)
return
card_val
&
val
==
val
end
return
function
(
c
,
_cons
)
if
type
(
_cons
)
~=
"string"
then
return
_cal
(
Card
[
_func
](
c
),
_cons
)
end
local
res
,
valL
,
valR
=
{
}
for
_
,
val
in
ipairs
(
fusf
.
PostFix_Trans
(
_cons
))
do
--- 构造一个用于判断卡片某个数值是否符合常量条件的函数
-- @param getter string 要呼叫的 Card 方法名称,例如 "GetType"
-- @param table_key string 常量表名称,如 "cod"、"pha"(会传给 fusf.FindTables)
-- @param cal_type string? 校验类型("&" 代表包含、"|" 代表允许并集),预设为 "|"
-- @return function(card: Card, value: string|number): boolean 回传是否符合条件
function
fusf
.
MakeConsCheck
(
getter
,
table_key
,
cal_type
)
local
card_func
=
fusf
.
CheckType
(
Card
[
getter
],
"function"
)
local
const_table
=
fusf
.
Findfucs
(
table_key
)
cal_type
=
cal_type
or
"|"
local
cal_func
if
cal_type
==
"&"
then
cal_func
=
function
(
c
,
target
)
return
card_func
(
c
)
&
target
==
target
end
elseif
cal_type
==
"|"
then
cal_func
=
function
(
c
,
target
)
return
card_func
(
c
)
|
target
==
target
end
end
return
function
(
c
,
target
)
local
from
=
"MakeConsCheck("
..
getter
fusf
.
CheckArgType
(
from
,
1
,
c
,
"Card"
)
local
typ
=
fusf
.
CheckArgType
(
from
,
2
,
target
,
"number/string"
)
if
typ
==
"number"
then
return
cal_func
(
c
,
target
)
end
local
stack
=
{}
for
_
,
val
in
ipairs
(
fusf
.
InfixToPostfix
(
target
))
do
if
val
:
match
(
"[%-%~]"
)
then
res
[
#
res
]
=
not
res
[
#
res
]
stack
[
#
stack
]
=
not
stack
[
#
stack
]
elseif
val
:
match
(
"[%+%/]"
)
then
valR
=
table.remove
(
res
)
valL
=
table.remove
(
res
)
local
valR
,
valL
=
table.remove
(
stack
),
table.remove
(
stack
)
local
Cal
=
{
[
"+"
]
=
valL
and
valR
,
[
"/"
]
=
valL
or
valR
}
table.insert
(
res
,
Cal
[
val
])
table.insert
(
stack
,
Cal
[
val
])
else
table.insert
(
res
,
_cal
(
Card
[
_func
](
c
),
fucs
[
_key
][
val
:
upper
()]))
local
temp
=
fusf
.
FindTables
(
val
:
upper
(),
const_table
)
table.insert
(
stack
,
cal_func
(
c
,
temp
))
end
end
return
res
[
#
res
]
end
end
function
fusf
.
Get_Func
(
_c
,
_func
,
_val
)
if
type
(
_func
)
~=
"string"
then
return
_func
end
local
lib
=
_c
.
lib
or
{}
local
res
=
function
(
_func
)
return
_func
end
if
_func
:
match
(
"~"
)
then
_func
=
_func
:
sub
(
2
)
res
=
function
(
_func
)
return
function
(
...
)
return
not
_func
(
...
)
end
end
end
-- find cm, lib, fuef, aux
if
not
_val
then
return
res
(
_c
[
_func
]
or
lib
[
_func
]
or
fuef
[
_func
]
or
aux
[
_func
])
end
-- translate vals
for
i
,
val
in
ipairs
(
_val
)
do
_val
[
i
]
=
tonumber
(
val
)
or
val
end
-- find cm, lib, fuef, aux
for
_
,
Lib
in
ipairs
({
_c
,
lib
,
fuef
,
aux
})
do
if
Lib
[
_func
]
then
return
res
(
Lib
[
_func
](
table.unpack
(
_val
)))
end
end
Debug
.
Message
(
"Get_Func not found : "
..
_func
)
return
nil
end
function
fusf
.
Val_Cuts
(
_val
,
...
)
-- "f1,f2(v1,v2),(v3)" -> {"f1", {"f2", "v1", "v2"}, {"v3"}}, ... use in vi = %i
local
res_lst
,
res_ind
,
temp
=
{
},
0
,
{
}
for
_
,
val
in
_val
:
ForCut
(
"Val_Cuts"
)
do
res_ind
=
res_ind
+
1
local
is_st
=
val
:
match
(
"%("
)
local
is_ed
=
val
:
match
(
"%)"
)
-- is f(v1)
if
is_st
and
is_ed
then
-- f(v1) -> {"f", "v1"}
res_lst
[
res_ind
]
=
fusf
.
Val_Cuts_Table_Process
(
val
,
...
)
elseif
is_st
then
-- f(v1,v2,v3) st f(v1
temp
,
res_ind
=
val
,
res_ind
-
1
elseif
is_ed
then
-- f(v1,v2,v3) ed v3) -> {"f", "v1", "v2", "v3"}
res_lst
[
res_ind
]
=
fusf
.
Val_Cuts_Table_Process
(
temp
..
","
..
val
,
...
)
temp
=
""
elseif
#
temp
>
0
then
-- f(v1,v2,v3) mid v2
temp
,
res_ind
=
temp
..
","
..
val
,
res_ind
-
1
elseif
val
:
match
(
"%%"
)
then
res_lst
[
res_ind
]
=
({
...
})[
tonumber
(
val
:
sub
(
2
))]
elseif
val
~=
""
then
res_lst
[
res_ind
]
=
val
end
return
stack
[
#
stack
]
end
res_lst
.
len
=
res_ind
return
res_lst
end
function
fusf
.
Val_Cuts_Table_Process
(
_str
,
...
)
-- "f(%1,,3)" -> {"f", vals[1], nil, "3"}
local
vals
,
res_lst
,
st
=
{
...
},
{
},
_str
:
find
(
"%("
)
if
st
~=
1
then
res_lst
[
1
]
=
_str
:
sub
(
1
,
st
-
1
)
end
-- has f
if
st
+
1
==
#
_str
then
return
res_lst
end
-- "f()" -> {"f"}
_str
=
_str
:
sub
(
st
+
1
,
#
_str
-
1
)
local
res_ind
=
#
res_lst
for
_
,
val
in
_str
:
ForCut
(
"Val_Cuts_Table_Process"
)
do
res_ind
=
res_ind
+
1
if
val
:
match
(
"%%"
)
then
res_lst
[
res_ind
]
=
vals
[
tonumber
(
val
:
sub
(
2
))]
elseif
val
~=
""
then
res_lst
[
res_ind
]
=
val
end
--- 从常量表找寻对应 keys 合计值
-- @param table_key string 常量表名称,如 "cod", "pha"
-- @param keys number|string 欲解析的常量名,多个以 "+" 连接
-- @return number 合并的常量值, 可选返回常量描述
-- @raise 当参数类型错误或无法找到对应常量时抛出错误
function
fusf
.
ParseConstantKey
(
table_key
,
keys
)
local
typ
=
fusf
.
CheckArgType
(
"ParseConstantKey"
,
2
,
keys
,
"number/string"
)
if
typ
==
"number"
then
return
keys
end
if
keys
==
""
then
error
(
"ParseConstantKey : param 2 is invalid param"
,
2
)
end
local
keys_list
,
res
=
keys
:
Cut
(
"+"
),
0
-- is special keys in cod table
if
table_key
==
"cod"
then
if
keys_list
[
1
]
==
"CUS"
then
res
=
EVENT_CUSTOM
+
fusf
.
NormalizeID
(
keys_list
[
2
])
-- EVENT_PHASE or EVENT_PHASE_START + PHASE_
elseif
keys_list
[
1
]:
match
(
"PH"
)
then
for
_
,
key
in
ipairs
(
keys_list
)
do
res
=
res
+
fusf
.
FindTables
(
key
,
fucs
.
cod
,
fucs
.
pha
)
end
end
if
res
>
0
then
return
res
end
end
res_lst
.
len
=
res_ind
return
res_lst
end
function
fusf
.
Creat_CF
(
_func
,
_val
,
...
)
if
not
_func
then
return
function
(
c
)
return
true
end
end
-- trans _val
if
type
(
_val
)
~=
"table"
then
_val
=
{
_val
}
end
local
temp_val
,
v_ind
=
{
},
0
for
_
,
f_val
in
ipairs
(
_val
)
do
if
type
(
f_val
)
==
"string"
then
for
_
,
val
in
fusf
.
ForTable
(
fusf
.
Val_Cuts
(
f_val
,
...
))
do
v_ind
=
v_ind
+
1
temp_val
[
v_ind
]
=
val
end
-- find table_key
local
const_table
=
fusf
.
Findfucs
(
table_key
)
local
des
for
i
=
#
keys_list
,
1
,
-
1
do
local
key
=
keys_list
[
i
]
res
=
res
+
fusf
.
FindTables
(
key
,
const_table
)
des
=
fucs
.
des
[
key
]
or
des
end
return
res
,
des
end
--- 查找并解析函数 func,支持反向逻辑
-- @param func string|function 函数名称或函数对象,若为字串则从 c/lib/fuef/aux 中查找,支持 "~" 前缀取反
-- @param args table? 若存在则立即调用目标函数,并传入该参数表
-- @param ... table 可选优先查找表,最后搜索 fuef, aux
-- @return function|any 若有 args,返回函数执行结果
-- @raise 若 func 为字串且无法解析为有效函数,将抛出错误
function
fusf
.
ResolveFunction
(
func
,
args
,
...
)
fusf
.
CheckArgType
(
"ResolveFunction"
,
2
,
args
,
"nil/table"
)
local
typ
=
fusf
.
CheckArgType
(
"ResolveFunction"
,
1
,
func
,
"string/function"
)
if
typ
==
"function"
then
return
func
end
local
fix
=
function
(
f
)
return
f
end
local
f
=
func
if
func
:
match
(
"~"
)
then
f
=
func
:
sub
(
2
)
fix
=
function
(
f
)
return
function
(
...
)
return
not
f
(
...
)
end
end
end
local
tabs
=
{
...
}
table.insert
(
tabs
,
fuef
)
table.insert
(
tabs
,
aux
)
f
=
fusf
.
FindTables
(
f
,
table.unpack
(
tabs
))
if
func
==
"tgoval"
then
Debug
.
Message
(
type
(
f
))
end
fusf
.
CheckType
(
f
,
"function"
)
if
args
then
if
args
.
n
then
f
=
f
(
table.unpack
(
args
,
1
,
args
.
n
))
else
v_ind
=
v_ind
+
1
temp_val
[
v_ind
]
=
f_val
f
=
f
(
table.unpack
(
args
))
end
end
_val
,
temp_val
=
temp_val
-- _func is function
if
type
(
_func
)
==
"function"
then
return
function
(
c
)
return
_func
(
c
,
table.unpack
(
_val
,
1
,
v_ind
))
end
end
-- _func is string
_func
=
fusf
.
PostFix_Trans
(
_func
,
...
)
local
fucf
,
Card
,
aux
=
fucf
,
Card
,
aux
if
#
_func
==
1
then
-- _func just one
_func
=
fucf
[
_func
[
1
]
]
or
Card
[
_func
[
1
]
]
or
aux
[
_func
[
1
]
]
return
function
(
c
)
return
_func
(
c
,
table.unpack
(
_val
,
1
,
v_ind
))
end
end
-- _func is multi
return
function
(
c
)
local
stack
,
v_ind
,
temp_val
=
{
},
1
for
_
,
func
in
ipairs
(
_func
)
do
if
func
==
"~"
then
stack
[
#
stack
]
=
not
stack
[
#
stack
]
elseif
type
(
func
)
==
"string"
and
#
func
==
1
then
local
valR
,
valL
=
table.remove
(
stack
),
table.remove
(
stack
)
local
Cal
=
{
[
"+"
]
=
valL
and
valR
,
[
"-"
]
=
valL
and
not
valR
,
[
"/"
]
=
valL
or
valR
}
stack
[
#
stack
+
1
]
=
Cal
[
func
]
return
fix
(
f
)
end
--- 将可能包含多个函数呼叫与括号参数的表达式字串解析为表结构(支援嵌套与占位符替换)
-- 如 "f1,,f2(%1,%2),(%3)" 会被解析为 { "f1", nil, { "f2", {replace[1], replace[2]} }, { replace[3] } }
-- @param expr_str string 欲解析的整体表达式,如 "f1,,f2(%1,%2),(%3)"
-- @param replace_table table 替换占位符用的参数表
-- @return table 解析结果为表结构,内含函数名与参数的混合列表,巢状呼叫以子表表示,附加栏位 n 表示数量
-- @raise 若有未关闭括号或非法占位符,将抛出错误
function
fusf
.
ParseCallGroupString
(
expr_str
,
replace_table
)
local
result
,
length
,
pending
=
{},
0
,
""
for
_
,
unit
in
expr_str
:
ForCut
()
do
length
=
length
+
1
local
is_st
=
unit
:
match
(
"%("
)
local
is_ed
=
unit
:
match
(
"%)"
)
-- is f(v1)
if
is_st
and
is_ed
then
local
fname
,
args
=
fusf
.
ParseCallExprString
(
unit
,
replace_table
)
if
fname
==
""
then
result
[
length
]
=
args
else
if
type
(
func
)
==
"string"
then
func
=
fucf
[
func
]
or
Card
[
func
]
or
aux
[
func
]
end
temp_val
,
v_ind
=
_val
[
v_ind
],
v_ind
+
1
if
type
(
temp_val
)
~=
"table"
then
temp_val
=
{
temp_val
,
len
=
1
}
end
stack
[
#
stack
+
1
]
=
func
(
c
,
table.unpack
(
temp_val
,
1
,
temp_val
.
len
))
result
[
length
]
=
{
fname
,
args
}
end
elseif
is_st
then
pending
,
length
=
unit
,
length
-
1
elseif
is_ed
then
local
fname
,
args
=
fusf
.
ParseCallExprString
(
pending
..
","
..
unit
,
replace_table
)
if
fname
==
""
then
result
[
length
]
=
args
else
result
[
length
]
=
{
fname
,
args
}
end
pending
=
""
elseif
#
pending
>
0
then
pending
,
length
=
pending
..
","
..
unit
,
length
-
1
elseif
unit
:
match
(
"%%"
)
then
local
ind
=
tonumber
(
unit
:
sub
(
2
))
if
not
ind
or
ind
<
1
then
error
(
"invalid replace_table index : "
..
expr_str
)
end
result
[
length
]
=
replace_table
[
ind
]
elseif
unit
~=
""
then
result
[
length
]
=
unit
end
return
table.remove
(
stack
)
end
if
pending
~=
""
then
error
(
"unclosed in ParseCallGroupString : "
..
expr_str
)
end
result
.
n
=
length
return
result
end
--- 解析可能带有函数名称与括号参数的呼叫字串,并进行占位替换
-- 如 "Func(%1,,3)" 会被解析为 "Func",与参数表 { replace[1], nil, "3" }
-- @param expr_str string 表达式形式的呼叫字串,如 "Func(%1,,3)"
-- @param replace_table table 替换占位符用的参数表
-- @return string, table 函数名称以及对应参数表,附加栏位 len 表示参数数量
-- @raise 当占位符无效或格式错误时会报错
function
fusf
.
ParseCallExprString
(
expr_str
,
replace_table
)
local
fname
,
start_pos
=
""
,
expr_str
:
find
(
"%("
)
if
start_pos
~=
1
then
fname
=
expr_str
:
sub
(
1
,
start_pos
-
1
)
end
if
start_pos
+
1
==
#
expr_str
then
-- "f()" -> {"f"}
return
fname
,
{
len
=
0
}
end
local
args_str
=
expr_str
:
sub
(
start_pos
+
1
,
-
2
)
return
fname
,
fusf
.
ParseArgsString
(
args_str
,
replace_table
)
end
function
fusf
.
Creat_GF
(
_func
,
_val
,
...
)
local
ex_val
=
{
...
}
return
function
(
g
,
n
)
g
=
g
:
Filter
(
fusf
.
Creat_CF
(
_func
,
_val
,
table.unpack
(
ex_val
)),
nil
)
if
not
n
then
return
g
end
return
n
>
0
and
#
g
>=
n
or
#
g
<=
-
n
--- 解析以逗号分隔的参数字串,并替换其中的占位符(如 %1, %2 等)
-- 如 "%1,,3" 会被解析为 { replace[1], nil, "3" }
-- @param args_str string 欲解析的字串,如 "%1,,3"
-- @param replace_table table 替换占位符用的参数表
-- @return table 解析后的参数 table ,附加栏位 n 表示参数数量
-- @raise 若占位符无效(非正整数)则触发错误
function
fusf
.
ParseArgsString
(
args_str
,
replace_table
)
local
result
,
length
=
{},
0
for
_
,
arg
in
args_str
:
ForCut
()
do
length
=
length
+
1
if
arg
:
match
(
"%%"
)
then
local
ind
=
tonumber
(
arg
:
sub
(
2
))
if
not
ind
or
ind
<
1
then
error
(
"invalid replace_table index : "
..
args_str
)
end
result
[
length
]
=
replace_table
[
ind
]
elseif
arg
~=
""
then
result
[
length
]
=
arg
end
end
result
.
n
=
length
return
result
end
--- 遍历一个表(table),支援带 .n 栏位的自订长度
-- @param t table 欲遍历的表
-- @param n number? 若无 t.n,则使用此值作为最大索引(可选)
-- @return function 叠代器函数,返回 (index, value)
function
fusf
.
ForTable
(
t
,
n
)
local
i
,
max
=
0
,
t
.
le
n
or
n
local
i
,
max
=
0
,
t
.
n
or
n
return
function
()
if
i
>=
max
then
return
nil
end
i
=
i
+
1
return
i
,
t
[
i
]
end
end
function
fusf
.
GetDES
(
_code
,
_id
,
m
)
-- (0), ("n"), (m), ("+1")
if
_id
then
if
type
(
_code
)
==
"number"
then
_code
=
fusf
.
M_chk
(
_code
)
else
-- ("-1", 0)
_code
=
m
+
tonumber
(
_code
)
--- 解析文字讯息代码,支持多种输入格式(数字/字符串/偏移量)
-- @param code number|string 原始代码或偏移字符串,如 "+1"、"-2"
-- @param id number? 可选的消息编号(如 Stringid(code, id) 中的 id)
-- @param m number? 可选基准卡号,用于计算相对偏移
-- @return number 返回 aux.Stringid(code, id) 的值
function
fusf
.
ResolveDescription
(
code
,
id
,
m
)
-- (0), ("n"), (m), ("+1")
local
cod_typ
=
fusf
.
CheckArgType
(
"ResolveDescription"
,
1
,
code
,
"number/string"
)
local
id_typ
=
fusf
.
CheckArgType
(
"ResolveDescription"
,
2
,
id
,
"nil/number"
)
fusf
.
CheckArgType
(
"ResolveDescription"
,
3
,
m
,
"number"
)
if
id_typ
==
"number"
then
if
id
<
17
then
code
=
fusf
.
NormalizeID
(
code
,
m
)
end
elseif
type
(
_code
)
==
"number"
then
if
_code
<
17
then
-- in cdb and code is owner card code
_code
,
_id
=
m
,
_code
elseif
cod_typ
==
"number"
then
if
code
<
17
then
-- in cdb and code is owner card code
code
,
id
=
m
,
code
elseif
code
>
1000
then
code
,
id
=
0
,
code
else
_code
,
_id
=
fusf
.
M_chk
(
_code
),
0
code
,
id
=
fusf
.
NormalizeID
(
code
,
m
),
0
end
elseif
type
(
_code
)
==
"string"
then
if
tonumber
(
_code
)
then
-- code = m +- _
code
_code
,
_id
=
m
+
tonumber
(
_code
),
0
else
-- in fucs.des
_code
,
_id
=
0
,
fucs
.
des
[
_code
]
elseif
cod_typ
==
"string"
then
if
tonumber
(
code
)
then
-- code = m +-
code
code
,
id
=
fusf
.
NormalizeID
(
code
,
m
),
0
else
-- in fucs.des
code
,
id
=
0
,
fusf
.
CheckType
(
fucs
.
des
[
code
],
"number"
)
end
end
return
aux
.
Stringid
(
_code
,
_id
)
-- _code * 16 + _
id
return
aux
.
Stringid
(
code
,
id
)
-- code * 16 +
id
end
function
fusf
.
GetRES
(
_flag
,
_count
)
-- _flag = a + b/b1/b2 + c | 1
if
type
(
_flag
)
~=
"string"
then
return
{
_flag
or
0
,
_count
}
end
if
not
_count
then
-- cut count
_flag
=
_flag
:
Cut
(
"fusf.GetRES"
,
"|"
)
_flag
,
_count
=
_flag
[
1
],
tonumber
(
_flag
[
2
]
or
1
)
--- 解析重置条件字串,支援简单运算与预设数量
-- @param flag string|number 条件描述(如 "a + b - c , 1")
-- @param count number? 可选的重置次数,若省略则从字串中解析
-- @return table {flag: number, count: number} 重置条件与次数 table
function
fusf
.
ResolveReset
(
flag
,
count
)
local
typ
=
fusf
.
CheckArgType
(
"ResolveReset"
,
1
,
flag
,
"number/string"
)
fusf
.
CheckArgType
(
"ResolveReset"
,
2
,
count
,
"nil/number"
)
if
typ
==
"number"
then
return
flag
,
count
end
if
not
count
then
-- cut count
local
parts
=
flag
:
Cut
()
flag
,
count
=
parts
[
1
],
tonumber
(
parts
[
2
]
or
1
)
end
local
stack
=
{
}
for
_
,
unit
in
ipairs
(
fusf
.
PostFix_Trans
(
_flag
))
do
if
unit
:
match
(
"[+-/]"
)
then
local
stack
=
{}
local
res
,
pha
=
fucs
.
res
,
fucs
.
pha
for
_
,
unit
in
ipairs
(
fusf
.
InfixToPostfix
(
flag
))
do
if
unit
:
match
(
"[+-]"
)
then
local
valR
,
valL
=
table.remove
(
stack
),
table.remove
(
stack
)
table.insert
(
stack
,
unit
==
"-"
and
valL
-
valR
or
valL
|
valR
)
local
cal
=
(
unit
==
"-"
)
and
(
valL
-
valR
)
or
(
valL
|
valR
)
table.insert
(
stack
,
cal
)
else
table.insert
(
stack
,
fu
cs
.
res
[
unit
]
or
fucs
.
pha
[
unit
]
)
table.insert
(
stack
,
fu
sf
.
FindTables
(
unit
,
res
,
pha
)
)
end
end
_
flag
=
table.remove
(
stack
)
if
_flag
&
0xfff0000
>
0
then
_flag
=
_
flag
|
RESET_EVENT
end
if
_flag
&
0x00003ff
>
0
then
_flag
=
_
flag
|
RESET_PHASE
end
return
{
_flag
,
_count
}
flag
=
table.remove
(
stack
)
if
flag
&
0xfff0000
>
0
then
flag
=
flag
|
RESET_EVENT
end
if
flag
&
0x00003ff
>
0
then
flag
=
flag
|
RESET_PHASE
end
return
flag
,
count
end
--- 建立与事件 e 绑定的函数快取区(每个效果唯一识别),供函数查找与快取使用
-- @param e Effect 效果物件,用于识别对应的快取区
-- @return table 快取表,带栏位 lib 表示可供查找函数的函式库
function
fusf
.
MakeFuncCatch
(
e
)
local
cm
=
fusf
.
Getcm
(
e
)
local
id
=
tostring
(
e
):
sub
(
-
8
)
cm
[
id
]
=
cm
[
id
]
or
{
lib
=
cm
}
return
cm
[
id
]
end
--- 查找指定键值对应的函数,若未快取则解析后快取
-- @param catch table 快取区(来自 MakeFuncCatch)
-- @param key string 作为函数的识别名称(快取键)
-- @param func string|function 欲查找的函数或其字串表示,可带 "~" 表示反向逻辑
-- @return function 查找到的函数物件(已快取)
function
fusf
.
FindFuncCatch
(
catch
,
key
,
func
)
if
catch
[
key
]
then
return
catch
[
key
]
end
catch
[
key
]
=
fusf
.
ResolveFunction
(
func
,
nil
,
catch
.
lib
)
return
catch
[
key
]
end
--------------------------------------"Other Support function"
function
fusf
.
RegFlag
(
val
,
cod
,
res
,
pro
,
lab
,
des
)
-- val : Card|Effect|player(number)
cod
,
res
,
pro
=
fusf
.
M_chk
(
cod
),
fusf
.
GetRES
(
res
),
fusf
.
Get_Constant
(
"pro"
,
pro
)
or
0
if
des
then
des
,
pro
=
fusf
.
GetDES
(
des
,
nil
,
cod
),
(
pro
or
0
)
|
EFFECT_FLAG_CLIENT_HINT
end
local
typ
=
aux
.
GetValueType
(
val
)
if
typ
==
"Card"
then
val
:
RegisterFlagEffect
(
cod
,
res
[
1
],
pro
,
res
[
2
]
or
1
,
lab
or
0
,
des
)
elseif
typ
==
"Group"
then
for
c
in
aux
.
Next
(
val
)
do
c
:
RegisterFlagEffect
(
cod
,
res
[
1
],
pro
,
res
[
2
]
or
1
,
lab
or
0
,
des
)
end
elseif
typ
==
"Effect"
then
val
:
GetHandler
():
RegisterFlagEffect
(
cod
,
res
[
1
],
pro
,
res
[
2
]
or
1
,
lab
or
0
,
des
)
else
--- 为卡片、效果、玩家或卡片群组注册一个标识用效果(FlagEffect)
-- @param val Card|Group|Effect|number 目标对象,可为单张卡、卡组、效果对象,或玩家编号
-- @param cod number|string 标识效果的代码,可为数值或偏移表达式(将被规范化)
-- @param res string|number 标识的重置条件,可用表达式,如 "event1 + pha1 , 1"
-- @param pro string|number? 效果的属性(效果标志),默认值为 0,可为常量名或数值
-- @param des string|number? 效果提示描述(字符串ID),传入描述名或偏移,如 "+1"
-- @param lab number? 标签参数,可用于额外传值(如标记内容),默认 0
function
fusf
.
RegFlag
(
val
,
cod
,
res
,
pro
,
des
,
lab
)
local
typ
=
fusf
.
CheckArgType
(
"RegFlag"
,
1
,
val
,
"Card/Group/Effect/player"
)
fusf
.
CheckArgType
(
"RegFlag"
,
6
,
lab
,
"nil/number"
)
cod
=
fusf
.
NormalizeID
(
cod
)
-- 规范化代码(如字符串转数值)
res
=
{
fusf
.
ResolveReset
(
res
)}
-- 转换表达式或数值为 {flag, count}
pro
=
fusf
.
ParseConstantKey
(
"pro"
,
pro
or
0
)
-- 效果属性,默认为 0
if
des
then
des
=
fusf
.
ResolveDescription
(
des
,
nil
,
cod
)
pro
=
pro
|
EFFECT_FLAG_CLIENT_HINT
end
if
typ
==
"player"
then
Duel
.
RegisterFlagEffect
(
val
,
cod
,
res
[
1
],
pro
,
res
[
2
]
or
1
,
lab
or
0
)
return
end
for
c
in
aux
.
Next
(
fusf
.
ToGroup
(
val
))
do
c
:
RegisterFlagEffect
(
cod
,
res
[
1
],
pro
,
res
[
2
]
or
1
,
lab
or
0
,
des
)
end
end
--- 检查 val 的种类为 cod 的标识效果的数量, 有 n 则传回比较结果
-- @param val Card|Effect|number 目标对象,可为卡片、效果对象或玩家编号(0或1)
-- @param cod number|string FlagEffect 的代码,会被标准化(如偏移表达式 "+1")
-- @param n number? 可选,若指定则判断是否达到 n,负数则判断不到 -n
-- @return number|boolean 返回数量,或是否满足条件
function
fusf
.
GetFlag
(
val
,
cod
,
n
)
local
typ
=
fusf
.
CheckArgType
(
"GetFlag"
,
1
,
val
,
"Card/Effect/player"
)
fusf
.
CheckArgType
(
"GetFlag"
,
3
,
n
,
"nil/number"
)
cod
=
fusf
.
NormalizeID
(
cod
)
local
count
if
typ
==
"player"
then
count
=
Duel
.
GetFlagEffect
(
val
,
cod
)
else
count
=
fusf
.
ToCard
(
val
):
GetFlagEffect
(
cod
)
end
if
not
n
then
return
count
end
return
n
>
0
and
count
>=
n
or
count
<=
-
n
end
--- 检查 val 的种类为 cod 的标识效果的 Label, 有 lab 則傳回是否相等
-- @param val Card|Effect|player 要查询的对象,可以是卡片、效果或玩家
-- @param cod number|string FlagEffect 的代码,会被标准化(如偏移表达式 "+1")
-- @param lab any? 可选,用于比较 label 是否等于特定值
-- @return any|boolean 若提供 lab,则回传是否相等;否则回传该 Label(或 nil)
function
fusf
.
GetFlagLabel
(
val
,
cod
,
lab
)
local
typ
=
fusf
.
CheckArgType
(
"GetFlagLabel"
,
1
,
val
,
"Card/Effect/player"
)
fusf
.
CheckArgType
(
"GetFlagLabel"
,
3
,
lab
,
"nil/number"
)
cod
=
fusf
.
NormalizeID
(
cod
)
local
label
if
typ
==
"player"
then
label
=
{
Duel
.
GetFlagEffectLabel
(
val
,
cod
)}
else
label
=
{
fusf
.
ToCard
(
val
):
GetFlagEffectLabel
(
cod
)}
end
if
lab
then
return
label
[
1
]
==
lab
end
return
table.unpack
(
label
)
end
--- 取得成为对象的卡(若存在),并检测是否与 e 有联系
-- @param e Effect 当前效果物件
-- @param pos number|nil 过滤位置(可选,用于指定表示形式,如 POS_FACEUP)
-- @param is_imm boolean|nil 是否过滤能否被效果影响的卡片(可选)
-- @return Card|false 返回对象,若无或不满足条件则返回 false
function
fusf
.
GetTarget
(
e
,
pos
,
is_imm
)
local
tg
=
fusf
.
GetTargets
(
e
,
pos
,
is_imm
)
if
tg
then
tg
=
tg
:
GetFirst
()
end
return
tg
end
--- 取得成为对象的卡片组(若存在),并检测是否与 e 有联系
-- @param e Effect 当前效果物件
-- @param pos number|nil 过滤位置(可选,用于指定表示形式,如 POS_FACEUP)
-- @param is_imm boolean|nil 是否过滤能否被效果影响的卡片(可选)
-- @return Group|false 返回满足条件的对象卡片组,若无或都不满足条件则返回 false
function
fusf
.
GetTargets
(
e
,
pos
,
is_imm
)
local
tg
=
Duel
.
GetChainInfo
(
0
,
CHAININFO_TARGET_CARDS
):
Filter
(
Card
.
IsRelateToEffect
,
nil
,
e
)
if
pos
then
tg
=
fugf
.
Filter
(
tg
,
"IsPos"
,
pos
)
end
if
is_imm
then
tg
=
fugf
.
Filter
(
tg
,
"~IsImm"
,
e
)
end
if
#
tg
==
0
then
return
false
end
return
tg
end
--- 让玩家 tp 把卡片或卡片组 eg 作为装备卡装备给卡片 c,返回值表示是否成功
-- @param e Effect 装备效果
-- @param tp number 装备的玩家,必须为 0 或 1
-- @param eg Group|Card 要装备的卡片,支持单张或群组
-- @param c nil|Card 装备目标卡片,必须为面朝上的卡
-- @return boolean 装备成功返回 true,失败返回 false
function
fusf
.
Equip
(
e
,
tp
,
eg
,
c
)
fusf
.
CheckArgType
(
"Equip"
,
1
,
e
,
"Effect"
)
fusf
.
CheckArgType
(
"Equip"
,
2
,
tp
,
"player"
)
local
typ
=
fusf
.
CheckArgType
(
"Equip"
,
3
,
eg
,
"Group/Card"
)
eg
=
fusf
.
ToGroup
(
eg
)
if
Duel
.
GetLocationCount
(
tp
,
LOCATION_SZONE
)
<
#
eg
then
return
false
end
c
=
fusf
.
CheckArgType
(
"Equip"
,
4
,
c
or
e
:
GetHandler
(),
"Card"
)
if
c
:
IsFacedown
()
then
return
false
end
local
limit
=
function
(
e
,
c
)
return
c
==
e
:
GetLabelObject
()
end
if
typ
==
"Card"
then
local
ec
=
eg
:
GetFirst
()
if
not
Duel
.
Equip
(
tp
,
ec
,
c
)
then
return
false
end
if
ec
:
IsType
(
TYPE_MONSTER
)
then
fuef
.
S
(
e
,
EFFECT_EQUIP_LIMIT
,
ec
):
PRO
(
"CD"
):
VAL
(
limit
):
OBJ
(
c
):
RES
(
"STD"
)
end
return
true
end
for
ec
in
aux
.
Next
(
eg
)
do
Duel
.
Equip
(
tp
,
ec
,
c
,
true
,
true
)
if
ec
:
IsType
(
TYPE_MONSTER
)
then
fuef
.
S
(
e
,
EFFECT_EQUIP_LIMIT
,
ec
):
PRO
(
"CD"
):
VAL
(
limit
):
OBJ
(
c
):
RES
(
"STD"
)
end
end
Duel
.
EquipComplete
()
return
true
end
--- 检查计数器 id 的数量, 有 n 则传回比较结果
-- @param id number|string 计数器的 ID,会规范化
-- @param p number 玩家编号(0 或 1)
-- @param typ number|string 操作类型
-- @param n number? 可选,若指定则判断是否达到 n,负数则判断不到 -n
-- @return number|boolean 返回数量,或是否满足条件
function
fusf
.
GetCounter
(
id
,
p
,
typ
,
n
)
id
=
fusf
.
NormalizeID
(
id
)
typ
=
fusf
.
ParseConstantKey
(
"act"
,
typ
)
local
ct
=
Duel
.
GetCustomActivityCount
(
id
,
p
,
typ
)
if
not
n
then
return
ct
end
return
n
>
0
and
ct
>=
n
or
ct
<=
-
n
end
--- 判断目前是否处于指定的 Phase(支援逻辑运算)
-- 支援表达式:单一阶段(如 "BP")、多个阶段的 OR(如 "BP/M2")、NOT(如 "~EP")
-- @param pha number|string 阶段代码或逻辑表达式
-- @return boolean 是否处于该阶段
function
fusf
.
IsPhase
(
pha
)
local
phase
=
Duel
.
GetCurrentPhase
()
local
typ
=
fusf
.
CheckArgType
(
"IsPhase"
,
1
,
pha
,
"number/string"
)
if
typ
==
"number"
then
return
phase
==
pha
end
local
stack
=
{}
for
_
,
val
in
ipairs
(
fusf
.
InfixToPostfix
(
pha
))
do
if
val
:
match
(
"[%-%~]"
)
then
stack
[
#
stack
]
=
not
stack
[
#
stack
]
elseif
val
==
"/"
then
local
valR
,
valL
=
table.remove
(
stack
),
table.remove
(
stack
)
table.insert
(
stack
,
valL
or
valR
)
elseif
val
==
"BP"
then
table.insert
(
stack
,
Duel
.
IsBattlePhase
())
else
local
_pha
=
fusf
.
Findfucs
(
"pha"
,
val
)
table.insert
(
stack
,
phase
==
_pha
)
end
end
return
stack
[
#
stack
]
end
--------------------------------------------------------------------------"initial function"
--- 为卡片脚本提供统一初始化接口
-- @param lib table (可选)卡片使用的函式库
-- @param glo_key string (可选)表示是否有全域注册条件
-- @return cm 卡片表(即全局脚本的局部名 cm)
-- @return m 卡片 ID(编号)
function
fusf
.
Initial
(
lib
,
glo_key
)
local
cm
,
m
=
GetID
()
if
cm
.
initial_effect
then
return
cm
,
m
end
local
log
=
fudf
.
StartLog
(
0
,
"fusf.Initial"
,
lib
,
glo_key
)
log
:
Info
(
m
)
fusf
.
CheckArgType
(
"Initial"
,
1
,
lib
,
"nil/table"
)
fusf
.
CheckArgType
(
"Initial"
,
2
,
glo_key
,
"nil/string"
)
cm
.
lib
=
lib
or
{}
cm
.
e_list
=
{}
cm
.
init_list
=
{}
local
function
apply
(
log
,
c
,
name
,
val
)
log
:
Info
(
"try InitSetOwner "
..
name
)
local
i
=
1
local
key
=
name
..
i
while
cm
[
key
]
do
local
E
=
fusf
.
CheckType
(
cm
[
key
],
"fuef"
)
c
.
e_list
[
key
]
=
E
:
InitSetOwner
(
key
,
c
,
val
)
i
=
i
+
1
key
=
name
..
i
end
log
:
Info
((
"set %d %s"
):
format
(
i
-
1
,
name
))
end
cm
.
initial_effect
=
function
(
c
)
local
log
=
fudf
.
StartLog
(
0
,
"cm.initial_effect"
,
c
)
log
:
Info
(
m
)
apply
(
log
,
c
,
"pe"
)
-- pe1, pe2, ...
apply
(
log
,
c
,
"e"
)
-- e1, e2, ...
log
:
Info
(
"try ipairs cm.init_list"
)
for
_
,
f
in
ipairs
(
cm
.
init_list
)
do
f
(
c
)
end
log
:
Info
(
"set cm.init_list down"
)
if
not
glo_key
or
cm
[
glo_key
]
then
return
end
cm
[
glo_key
]
=
{
0
,
0
}
apply
(
log
,
c
,
"ge"
,
1
)
-- ge1, ge2, ...
end
log
:
Info
(
"set cm.initial_effect down"
)
return
cm
,
m
end
--- 在卡片的 initial_effect 中插入额外初始化函数
-- @param func function 需要插入的初始化函数
-- @raise 如果 cm.initial_effect 不存在或不是函数,则报错 "INITIAL"
function
fusf
.
InsertInitial
(
func
,
log
)
log
=
fudf
.
StartLog
(
log
or
0
,
"fusf.InsertInitial"
,
func
)
fusf
.
CheckArgType
(
"InsertInitial"
,
1
,
func
,
"function"
)
local
cm
,
m
=
GetID
()
if
not
cm
.
init_list
then
error
(
"You must call fusf.Initial first"
,
2
)
end
table.insert
(
cm
.
init_list
,
func
)
end
--- 为卡片添加卡名记述 ...
-- @param ... number|string 可为卡号、字符串(如 "100+200")、或多个卡号
-- 字符串会用 "+" 切割后批量处理,转换为标准卡号格式
function
fusf
.
AddCode
(
...
)
local
log
=
fudf
.
StartLog
(
0
,
"fusf.AddCode"
,
...
)
fusf
.
CheckEmptyArgs
(
"AddCode"
,
...
)
local
codes
=
{
}
for
i
,
val
in
ipairs
{
...
}
do
local
typ
=
fusf
.
CheckArgType
(
"AddCode"
,
i
,
val
,
"string/number"
)
if
typ
==
"string"
then
for
_
,
code
in
ipairs
(
fusf
.
GetCodeTable
(
val
))
do
log
:
Info
(
"add "
..
code
)
table.insert
(
codes
,
code
)
end
else
local
code
=
fusf
.
NormalizeID
(
val
)
log
:
Info
(
"add "
..
code
)
table.insert
(
codes
,
code
)
end
end
local
function
AddFunc
(
c
)
aux
.
AddCodeList
(
c
,
table.unpack
(
codes
))
end
fusf
.
InsertInitial
(
AddFunc
,
log
)
end
function
fusf
.
GetFlag
(
val
,
cod
)
-- val : Card|Effect|player(number)
cod
=
fusf
.
M_chk
(
cod
)
local
typ
=
aux
.
GetValueType
(
val
)
if
typ
==
"Card"
then
return
val
:
GetFlagEffect
(
cod
)
elseif
typ
==
"Effect"
then
return
val
:
GetHandler
():
GetFlagEffect
(
cod
)
--- 为卡片添加苏生限制
function
fusf
.
ReviveLimit
()
local
log
=
fudf
.
StartLog
(
0
,
"fusf.ReviveLimit"
)
local
function
AddFunc
(
c
)
c
:
EnableReviveLimit
()
end
return
Duel
.
GetFlagEffect
(
val
,
cod
)
fusf
.
InsertInitial
(
AddFunc
,
log
)
end
function
fusf
.
Equip
(
e
,
tp
,
ec
,
c
)
if
not
(
ec
and
c
and
Duel
.
Equip
(
tp
,
ec
,
c
))
then
return
false
end
local
eq
=
function
(
e
,
c
)
return
c
==
e
:
GetLabelObject
()
end
return
fuef
.
S
(
e
,
EFFECT_EQUIP_LIMIT
,
ec
):
PRO
(
"CD"
):
VAL
(
eq
):
OBJ
(
c
):
RES
(
"STD"
)
--- 添加自定义计数器
-- @param id number|string 计数器的 ID,会规范化
-- @param typ number|string 操作类型
-- @param func function|string 判断计数的过滤函数
function
fusf
.
AddCounter
(
id
,
typ
,
func
)
local
log
=
fudf
.
StartLog
(
0
,
"fusf.AddCounter"
,
id
,
typ
,
func
)
local
id
=
fusf
.
NormalizeID
(
id
)
log
:
Info
(
"NormalizeID id : "
..
id
)
local
typ
=
fusf
.
ParseConstantKey
(
"act"
,
typ
)
log
:
Info
(
"got act typ : "
..
fusf
.
CutHex
(
typ
))
if
fusf
.
CheckArgType
(
"AddCounter"
,
3
,
func
,
"function/string"
)
==
"string"
then
func
=
"~"
..
func
else
func
=
function
(
...
)
return
not
func
(
...
)
end
end
local
function
AddFunc
(
c
)
func
=
fusf
.
ResolveFunction
(
func
,
nil
,
fusf
.
Getcm
(
c
),
c
.
lib
)
Duel
.
AddCustomActivityCounter
(
id
,
typ
,
func
)
end
fusf
.
InsertInitial
(
AddFunc
,
log
)
end
\ No newline at end of file
expansions/script/c20099999.lua
View file @
14515cb1
...
...
@@ -124,9 +124,9 @@ fucs.cod = {
RE
=
EVENT_REMOVE
,
MO
=
EVENT_MOVE
,
--召唤
PS
=
EVENT_SUMMON
,
--召唤之际(怪兽还没上场、神宣等时点)
PSP
=
EVENT_SPSUMMON
,
--特殊召唤之际
PFS
=
EVENT_FLIP_SUMMON
,
--翻转召唤之际
PS
=
EVENT_SUMMON
,
--召唤之际(怪兽还没上场、神宣等时点)
PSP
=
EVENT_SPSUMMON
,
--特殊召唤之际
PFS
=
EVENT_FLIP_SUMMON
,
--翻转召唤之际
S
=
EVENT_SUMMON_SUCCESS
,
--通常召唤成功时
SP
=
EVENT_SPSUMMON_SUCCESS
,
--特殊召唤成功时
FS
=
EVENT_FLIP_SUMMON_SUCCESS
,
--翻转召唤成功时
...
...
@@ -150,30 +150,30 @@ fucs.cod = {
NEGS
=
EVENT_SUMMON_NEGATED
,
--召唤被无效时
NEGFS
=
EVENT_FLIP_SUMMON_NEGATED
,
--反转召唤被无效时
NEGSP
=
EVENT_SPSUMMON_NEGATED
,
--特殊召唤被无效时
NEGATK
=
EVENT_ATTACK_DISABLED
,
--攻击无效时(翻倍机会)
--连锁
CH
=
EVENT_CHAINING
,
--效果发动时
CHED
=
EVENT_CHAIN_SOLVED
,
--连锁处理结束时
----组合时点
PHS
=
EVENT_PHASE_START
,
--攻击
ATK
=
EVENT_ATTACK_ANNOUNCE
,
--攻击宣言时
BATK
=
EVENT_BE_BATTLE_TARGET
,
--被选为攻击对象时
--需组合 阶段时点
PH
=
EVENT_PHASE
,
--阶段结束时
PHS
=
EVENT_PHASE_START
,
--阶段开始时
--[[
EVENT_CHAIN_SOLVING =1020 --连锁处理开始时(EVENT_CHAIN_ACTIVATING之後)
EVENT_CHAIN_ACTIVATING =1021 --连锁处理准备中
EVENT_CHAIN_ACTIVATED =1023 --N/A
EVENT_CHAIN_NEGATED =1024 --连锁发动无效时(EVENT_CHAIN_ACTIVATING之後)
EVENT_CHAIN_DISABLED =1025 --连锁效果无效时
EVENT_CHAIN_END =1026 --连锁串结束时
EVENT_BECOME_TARGET =1028 --成为效果对象时
EVENT_BREAK_EFFECT =1050 --Duel.BreakEffect()被调用时
EVENT_MSET =1106 --放置怪兽时
EVENT_SSET =1107 --放置魔陷时
EVENT_DRAW =1110 --抽卡时
EVENT_DAMAGE =1111 --造成战斗/效果伤害时
EVENT_RECOVER =1112 --回复生命值时
EVENT_PREDRAW =1113 --抽卡阶段通常抽卡前
EVENT_CONTROL_CHANGED =1120 --控制权变更
EVENT_EQUIP =1121 --装备卡装备时
EVENT_ATTACK_ANNOUNCE =1130 --攻击宣言时
EVENT_BE_BATTLE_TARGET =1131 --被选为攻击对象时
EVENT_BATTLE_START =1132 --伤害步骤开始时(反转前)
EVENT_BATTLE_CONFIRM =1133 --伤害计算前(反转後)
EVENT_PRE_DAMAGE_CALCULATE =1134 --伤害计算时(羽斬)
...
...
@@ -184,7 +184,6 @@ EVENT_BATTLED =1138 --伤害计算后(异女、同反转效果时点)
EVENT_BATTLE_DESTROYING =1139 --以战斗破坏怪兽送去墓地时(BF-苍炎之修罗)
EVENT_BATTLE_DESTROYED =1140 --被战斗破坏送去墓地时(杀人番茄等)
EVENT_DAMAGE_STEP_END =1141 --伤害步骤结束时
EVENT_ATTACK_DISABLED =1142 --攻击无效时(翻倍机会)
EVENT_BATTLE_DAMAGE =1143 --造成战斗伤害时
EVENT_TOSS_DICE =1150 --掷骰子的结果产生后
EVENT_TOSS_COIN =1151 --抛硬币的结果产生后
...
...
@@ -194,8 +193,6 @@ EVENT_LEVEL_UP =1200 --等级上升时
EVENT_PAY_LPCOST =1201 --支付生命值时
EVENT_RETURN_TO_GRAVE =1203 --回到墓地时
EVENT_TURN_END =1210 --回合结束时
EVENT_PHASE =0x1000 --阶段结束时
EVENT_PHASE_START =0x2000 --阶段开始时
EVENT_ADD_COUNTER =0x10000 --增加指示物时
EVENT_REMOVE_COUNTER =0x20000 --去除指示物时(A指示物),Card.RemoveCounter()必須手動觸發此事件
--]]
...
...
@@ -219,7 +216,7 @@ fucs.pro = {
CAL
=
EFFECT_FLAG_DAMAGE_CAL
,
--可以在伤害计算时发动
OP
=
EFFECT_FLAG_EVENT_PLAYER
,
--发动/处理效果的玩家为触发事件的玩家而不是卡片的持有者,如仪式魔人,万魔殿
NR
=
EFFECT_FLAG_NO_TURN_RESET
,
--发条等“这张卡在场上只能发动一次”的效果
OE
=
0x40400
,
--EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE(out effect)
OE
=
0x40400
,
--EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE(out effect)
}
--Location Variable
fucs
.
ran
=
{
...
...
@@ -237,13 +234,19 @@ fucs.ran = {
[
"P"
]
=
LOCATION_PZONE
,
[
"A"
]
=
0xff
}
--Countlimit Variable
fucs
.
ctl
=
{
O
=
EFFECT_COUNT_CODE_OATH
,
D
=
EFFECT_COUNT_CODE_DUEL
,
C
=
EFFECT_COUNT_CODE_CHAIN
,
}
--Phase Variable
fucs
.
pha
=
{
DP
=
PHASE_DRAW
,
--抽卡阶段
SP
=
PHASE_STANDBY
,
--准备阶段
M1
=
PHASE_MAIN1
,
--主要阶段1
BPS
=
PHASE_BATTLE_START
,
--战斗阶段开始
B
P
=
PHASE_BATTLE_STEP
,
--战斗步驟
B
S
=
PHASE_BATTLE_STEP
,
--战斗步驟
DS
=
PHASE_DAMAGE
,
--伤害步驟
DC
=
PHASE_DAMAGE_CAL
,
--伤害计算时
BPE
=
PHASE_BATTLE
,
--战斗阶段結束
...
...
@@ -396,5 +399,21 @@ fucs.val = {
LI
=
SUMMON_TYPE_LINK
,
--Summon Value --特定的召唤方式
SELF
=
SUMMON_VALUE_SELF
,
SYM
=
SUMMON_VALUE_SYNCHRO_MATERIAL
}
\ No newline at end of file
SYM
=
SUMMON_VALUE_SYNCHRO_MATERIAL
,
--location Value --离场重定向
H
=
LOCATION_HAND
,
D
=
LOCATION_DECK
,
G
=
LOCATION_GRAVE
,
R
=
LOCATION_REMOVED
,
E
=
LOCATION_EXTRA
,
}
--Value Variable
fucs
.
act
=
{
S
=
ACTIVITY_SUMMON
,
--召唤(不包括通常召唤的set)
NS
=
ACTIVITY_NORMALSUMMON
,
--通常召唤(包括通常召唤的set)
SP
=
ACTIVITY_SPSUMMON
,
--特殊召唤
FS
=
ACTIVITY_FLIPSUMMON
,
--反转召唤
ATK
=
ACTIVITY_ATTACK
,
--攻击
CH
=
ACTIVITY_CHAIN
,
--发动效果
}
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