Commit d97d98da authored by Vury Leo's avatar Vury Leo

Add 究極竜魔導師

parent 2afce688
......@@ -2,6 +2,33 @@
local s,id,o=GetID()
function s.initial_effect(c)
aux.AddMaterialCodeList(c,23995346)
-- common Ritual‐monster filter: 「カオス」儀式モンスター
local ritual_filter=function(mc,tc)
if not mc:IsAllTypes(TYPE_MONSTER|TYPE_RITUAL) then return false end
return mc:IsFusionSetCard(0xcf)
end
Fusion.AddFusionProcedure(c,{
variants = {
-- Variant A: 1 × 青眼の究極竜 + 1 × 「カオス」儀式モンスター
{
slots = {
Fusion.Slot.Code(23995346),
Fusion.Slot.Filter(ritual_filter),
}
},
-- Variant B: 3 × 「ブルーアイズ」モンスター + 1 × 「カオス」儀式モンスター
{
slots = {
Fusion.Slot.Group({
min=3,
max=3,
filter=function(mc,tc) return mc:IsFusionSetCard(0xdd) end,
}),
Fusion.Slot.Filter(ritual_filter),
}
}
}
})
c:EnableReviveLimit()
--summon procedure
local e0=Effect.CreateEffect(c)
......@@ -10,13 +37,13 @@ function s.initial_effect(c)
e0:SetCode(EFFECT_SPSUMMON_CONDITION)
e0:SetValue(aux.fuslimit)
c:RegisterEffect(e0)
local e1=Effect.CreateEffect(c)
e1:SetType(EFFECT_TYPE_SINGLE)
e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e1:SetCode(EFFECT_FUSION_MATERIAL)
e1:SetCondition(s.fcondition)
e1:SetOperation(s.foperation)
c:RegisterEffect(e1)
-- local e1=Effect.CreateEffect(c)
-- e1:SetType(EFFECT_TYPE_SINGLE)
-- e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
-- e1:SetCode(EFFECT_FUSION_MATERIAL)
-- e1:SetCondition(s.fcondition)
-- e1:SetOperation(s.foperation)
-- c:RegisterEffect(e1)
--negate
local e2=Effect.CreateEffect(c)
e2:SetDescription(aux.Stringid(id,1))
......
......@@ -11,7 +11,14 @@ function s.initial_effect(c)
{ [0xff]=FusionSpell.FUSION_OPERATION_SHUFFLE }
},
stage_x_operation=s.stage_x_operation,
locked_codes={89631139,23995346}
locked_codes=function(tc)
if aux.IsMaterialListCode(tc,89631139)==true then
return {89631139}
elseif aux.IsMaterialListCode(tc,23995346)==true then
return {23995346}
end
return {}
end
})
e1:SetCategory(CATEGORY_SPECIAL_SUMMON+CATEGORY_FUSION_SUMMON+CATEGORY_GRAVE_ACTION)
e1:SetHintTiming(0,TIMINGS_CHECK_MONSTER+TIMING_MAIN_END)
......
......@@ -2255,7 +2255,7 @@ FusionSpell = {}
--- Whether skip the location count check, default false, used for 叛逆の堕天使, only works for target function
--- @field skip_location_count_check? boolean
--- Locked code, material code that can not use substitutes
--- @field locked_codes? integer[]
--- @field locked_codes? (integer[]|fun(tc:Card):integer[])
--- Add LOCATION_EXTRA and opponent mzone to EFFECT_EXTRA_FUSION_MATERIAL list, remove once core updated
......@@ -2407,7 +2407,7 @@ end
---@param fusion_spell_matfilter FUSION_SPELL_MATFILTER_FUNCTION a material must pass this to be legal as material come from fusion spell
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@param locked_codes integer[] Locked code, material code that can not use substitutes, used for 烙印融合
---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合
function FusionSpell.GetSummonTarget(
fusfilter,
matfilter,
......@@ -2460,7 +2460,7 @@ function FusionSpell.GetSummonTarget(
end
-- --- check for chain material targets
if sumtype&SUMMON_TYPE_FUSION~=0 then
local ce_sg=FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check)
local ce_sg=FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes)
if ce_sg==true then
return true
end
......@@ -2488,7 +2488,7 @@ end
---@param gc fun(e:Effect):Card|nil Function that returns a card that must be included in the fusion materials
---@param fusion_spell_matfilter FUSION_SPELL_MATFILTER_FUNCTION a material must pass this to be legal as material come from fusion spell
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param locked_codes integer[] Locked code, material code that can not use substitutes, used for 烙印融合
---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合
function FusionSpell.GetSummonOperation(
fusfilter,
matfilter,
......@@ -2597,7 +2597,11 @@ function FusionSpell.GetSummonOperation(
e,
mat_operation_code_map)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(additional_fgoalcheck,tp,tc,pre_select_mat_location,e)
Fusion.LockedCodes=locked_codes
if type(locked_codes)=='function' then
Fusion.LockedCodes=locked_codes(tc)
else
Fusion.LockedCodes=locked_codes
end
materials=Duel.SelectFusionMaterial(tp,tc,mg,gc(e),tp)
aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil
......@@ -2610,7 +2614,11 @@ function FusionSpell.GetSummonOperation(
assert(#chain_mg>0, "we are trying to apply a chain material, but it has no possible material")
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck,e)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(additional_fgoalcheck,e)
Fusion.LockedCodes=locked_codes
if type(locked_codes)=='function' then
Fusion.LockedCodes=locked_codes(tc)
else
Fusion.LockedCodes=locked_codes
end
materials=Duel.SelectFusionMaterial(tp,tc,chain_mg,gc(e),tp)
aux.FCheckAdditional=nil
aux.FGoalCheckAdditional=nil
......@@ -2879,7 +2887,7 @@ end
---@param fusion_spell_matfilter fun(c:Card):boolean a material must pass this to be legal as material come from fusion spell
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@param locked_codes integer[] Locked code, material code that can not use substitutes, used for 烙印融合
---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合
function FusionSpell.SummonTargetFilter(
c,
fusfilter,
......@@ -2932,7 +2940,11 @@ function FusionSpell.SummonTargetFilter(
e,
mat_operation_code_map)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunction(additional_fgoalcheck,tp,c,pre_select_mat_location,e)
Fusion.LockedCodes=locked_codes
if type(locked_codes)=='function' then
Fusion.LockedCodes=locked_codes(c)
else
Fusion.LockedCodes=locked_codes
end
local chkf=FusionSpell.GetCheckFieldPlayer(tp,skip_location_count_check)
local res=c:CheckFusionMaterial(mg,gc(e),chkf)
aux.FCheckAdditional=nil
......@@ -2973,8 +2985,9 @@ end
---@param gc fun(e:Effect):Card|nil
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合
---@return boolean res return whether there is a valid target for any chain material effect
function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check)
function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter,additional_fcheck,additional_fgoalcheck,fuslocation,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes)
local chain_material_effects={Duel.IsPlayerAffectedByEffect(tp,EFFECT_CHAIN_MATERIAL)}
---@type {[Effect]:Group}
for _,ce in ipairs(chain_material_effects) do
......@@ -2984,7 +2997,7 @@ function FusionSpell.IsExistsChainMaterialSummonTargets(e,tp,fusfilter,matfilter
if #chain_mg>0 then
local ce_fusfilter=ce:GetValue()
local res=Duel.IsExistingMatchingCard(function(c)
return FusionSpell.ChainMaterialSummonTargetFilter(c,aux.AND(ce_fusfilter,fusfilter or aux.TRUE),e,tp,chain_mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check)
return FusionSpell.ChainMaterialSummonTargetFilter(c,aux.AND(ce_fusfilter,fusfilter or aux.TRUE),e,tp,chain_mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes)
end,
tp,fuslocation,0,1,nil)
if res==true then
......@@ -3000,6 +3013,7 @@ end
---@param gc fun(e:Effect):Card|nil
---@param skip_summon_check boolean whether skip the IsCanBeSpecialSummoned check, for クロック・リザード
---@param skip_location_count_check boolean Whether skip the location count check, default false, used for 叛逆の堕天使
---@param locked_codes (integer[]|fun(tc:Card):integer[]) Locked code, material code that can not use substitutes, used for 烙印融合
---@return boolean result Whether c could be fusion summoned by this chain material effect
function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additional_fcheck,additional_fgoalcheck,sumtype,sumpos,gc,skip_summon_check,skip_location_count_check,locked_codes)
if not c:IsType(TYPE_FUSION) or fusfilter(c,e,tp)==false then
......@@ -3012,7 +3026,11 @@ function FusionSpell.ChainMaterialSummonTargetFilter(c,fusfilter,e,tp,mg,additio
end
aux.FCheckAdditional=FusionSpell.GetFusionSpellFCheckAdditionalFunctionForChainMaterial(additional_fcheck,e)
aux.FGoalCheckAdditional=FusionSpell.GetFusionSpellFGoalCheckAdditionalFunctionForChainMaterial(additional_fgoalcheck,e)
Fusion.LockedCodes=locked_codes
if type(locked_codes)=='function' then
Fusion.LockedCodes=locked_codes(c)
else
Fusion.LockedCodes=locked_codes
end
local chkf=FusionSpell.GetCheckFieldPlayer(tp,skip_location_count_check)
local res=c:CheckFusionMaterial(mg,gc(e),chkf)
aux.FCheckAdditional=nil
......@@ -3400,57 +3418,61 @@ Fusion={}
Fusion.LockedCodes=nil
function Fusion.AddFusionProcedure(c,opts)
local slots=opts.slots
local mat_filter=opts.mat_filter or nil
local fgoalcheck=opts.fgoalcheck or aux.TRUE
-- Register metadata
if c:IsStatus(STATUS_COPYING_EFFECT) then return end
local mat={}
local min_req=0
local max_req=0
for _,slot in ipairs(slots) do
if slot.match_code then
mat[slot.match_code]=true
min_req=min_req+1
max_req=max_req+1
elseif slot.match_codes then
for _,code in ipairs(slot.match_codes) do
mat[code]=true
end
min_req=min_req+1
max_req=max_req+1
elseif slot.filter then
local prev=slot.filter
slot.filter=function(mc,p_tc) return prev(mc,p_tc) and not mc:IsHasEffect(6205579) end
min_req=min_req+1
max_req=max_req+1
elseif slot.group then
local prev=slot.group.filter
slot.group.filter=function(mc,p_tc) return prev(mc,p_tc) and not mc:IsHasEffect(6205579) end
min_req=min_req+slot.group.min
max_req=max_req+slot.group.max
end
end
local mt=getmetatable(c)
if mt.material==nil then
mt.material=mat
end
if mt.material_count==nil then
mt.material_count={min_req,max_req}
end
for index,_ in pairs(mat) do
Auxiliary.AddCodeList(c,index)
end
-- Register effect
local e=Effect.CreateEffect(c)
e:SetType(EFFECT_TYPE_SINGLE)
e:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e:SetCode(EFFECT_FUSION_MATERIAL)
e:SetCondition(Fusion.FusionCondition(c,slots,mat_filter,fgoalcheck,true))
e:SetOperation(Fusion.FusionOperation(c,slots,mat_filter,fgoalcheck))
e:SetDescription(1379) --- 启用扩展卡包调试模式
c:RegisterEffect(e)
-- Refactored Fusion.AddFusionProcedure using the above helpers
function Fusion.AddFusionProcedure(c, opts)
local patterns=Fusion.BuildPatterns(opts)
--=== Metadata registration ===--
if c:IsStatus(STATUS_COPYING_EFFECT) then return end
-- collect all fusion codes and compute global min/max across patterns
local code_set={}
local global_min,global_max=math.huge,0
for _,pat in ipairs(patterns) do
local pmin,pmax=0,0
for _,slot in ipairs(pat.slots) do
if slot.match_code then
code_set[slot.match_code]=true
pmin=pmin+1
pmax=pmax+1
elseif slot.match_codes then
for _,cd in ipairs(slot.match_codes) do
code_set[cd]=true
end
pmin=pmin+1
pmax=pmax+1
elseif slot.group then
pmin=pmin+slot.group.min
pmax=pmax+slot.group.max
else
-- generic filter-slot
pmin=pmin+1
pmax=pmax+1
end
end
global_min=math.min(global_min,pmin)
global_max=math.max(global_max,pmax)
end
local mt=getmetatable(c)
if mt.material==nil then
mt.material=code_set
end
if mt.material_count==nil then
mt.material_count={global_min,global_max}
end
for cd,_ in pairs(code_set) do
Auxiliary.AddCodeList(c,cd)
end
--=== Effect registration ===--
local e = Effect.CreateEffect(c)
e:SetType(EFFECT_TYPE_SINGLE)
e:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e:SetCode(EFFECT_FUSION_MATERIAL)
e:SetCondition(Fusion.MultiCondition(c,patterns,true))
e:SetOperation(Fusion.MultiOperation(c,patterns))
e:SetDescription(1379)
c:RegisterEffect(e)
end
---@param allow_extras boolean whether to allow extra materials for checking propose
......@@ -3503,7 +3525,6 @@ function Fusion.FusionCondition(tc,slots,mat_filter,fgoalcheck,allow_extras,sele
for idx,slot in ipairs(single_slots) do
-- lock slot if its match_code equals code
if slot.match_code==code then
Debug.Message(string.format("locked %d, slot %d",code,idx))
locked_slots[idx]=true
break
end
......@@ -3773,92 +3794,6 @@ function Fusion.MatchSlot(mc,slot,tc)
return false,false
end
--- Generator: operation from named slots
---@param slots table[]
function Fusion.FusionOperation(tc,slots,mat_filter,fgoalcheck)
return function(e,tp,eg,ep,ev,re,rp,gc,chkf)
if mat_filter then
local pool=eg
pool=Group.CreateGroup()
for mc in aux.Next(eg) do
if mat_filter(mc,e:GetHandler()) then
pool:AddCard(mc)
end
end
eg=pool
end
-- strict final check (no extras)
local strict_cond=Fusion.FusionCondition(tc,slots,mat_filter,fgoalcheck,false)
-- precompute minimum materials required
local min_req=0
local max_req=0
for _,slot in ipairs(slots) do
if slot.group then
min_req=min_req+slot.group.min
max_req=max_req+slot.group.max
else
min_req=min_req+1
max_req=max_req+1
end
end
max_req=math.min(max_req,eg:GetCount())
-- prompt player
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_FMATERIAL)
local sg=Group.CreateGroup()
while true do
-- can we finish right now?
local finishable=(sg:GetCount()>=min_req) and strict_cond(e,sg,gc,chkf)
-- build “addable” via exhaustive mapping + completion test
local addable=Group.CreateGroup()
local candidates={}
for mc in aux.Next(eg) do
if not sg:IsContains(mc) then
table.insert(candidates,mc)
end
end
for _,mc in ipairs(candidates) do
sg:AddCard(mc)
if Fusion.CanCompleteFromMappings(e,sg,eg,slots,mat_filter,fgoalcheck,tc,gc,chkf) then
addable:AddCard(mc)
end
sg:RemoveCard(mc)
end
if addable:GetCount()==0 then
assert(finishable==true)
Duel.SetFusionMaterial(sg)
return
end
-- UI: let the player pick or finalize
local picked=Group.SelectUnselect(addable,sg,tp,finishable,true,min_req,max_req)
if not picked then
if finishable then
Duel.SetFusionMaterial(sg)
return -- user clicked “OK”
else
Duel.SetFusionMaterial(Group.CreateGroup())
return -- user clicked “Cancel” on invalid selection
end
end
assert(picked~=nil)
-- toggle selection
if sg:IsContains(picked) then
sg:RemoveCard(picked)
else
sg:AddCard(picked)
end
end
end
end
-- Slot constructors
Fusion.Slot={}
--- Create a slot for a single code (default allow_sub = true)
......@@ -3950,7 +3885,11 @@ function Fusion.FindAllMappings(cards_sel,slots,tc)
local all_maps={}
local mapping={} -- mapping[idx_in_cards_sel] = slot_index
local function dfs(idx)
local function dfs(idx,sub_count)
-- prune: no more than 1 substitute
if sub_count>1 then
return
end
if idx>#cards_sel then
-- Before recording, run unique_by on each group‐slot that has one
for i,slot in ipairs(slots) do
......@@ -3988,14 +3927,17 @@ function Fusion.FindAllMappings(cards_sel,slots,tc)
if not slot.group and not filled[i] then
local match,is_sub=Fusion.MatchSlot(mc,slot,tc)
if match then
-- skip substitute if slot is locked
-- skip if substitute and this slot is locked
if not (is_sub and locked_slots[i]) then
any_match=true
filled[i]=true
mapping[idx]=i
dfs(idx+1)
filled[i]=false
mapping[idx]=nil
local new_sub=sub_count+(is_sub and 1 or 0)
if new_sub<=1 then
any_match=true
filled[i]=true
mapping[idx]=i
dfs(idx+1,new_sub)
filled[i]=false
mapping[idx]=nil
end
end
end
end
......@@ -4050,7 +3992,7 @@ function Fusion.FindAllMappings(cards_sel,slots,tc)
any_match=true
group_assigned[i]=assigned + 1
mapping[idx]=i
dfs(idx+1)
dfs(idx+1,sub_count)
group_assigned[i]=assigned
mapping[idx]=nil
end
......@@ -4065,7 +4007,7 @@ function Fusion.FindAllMappings(cards_sel,slots,tc)
end
end
dfs(1)
dfs(1,0)
return all_maps
end
......@@ -4366,3 +4308,168 @@ function Fusion.MakeExcludeFilter(orig_filter,key_func,used_keys)
return true
end
end
-- Helper: build patterns list (single or variants)
function Fusion.BuildPatterns(opts)
local patterns={}
if opts.variants then
for _, v in ipairs(opts.variants) do
table.insert(patterns,{
slots=v.slots,
mat_filter=v.mat_filter,
fgoalcheck=v.fgoalcheck or aux.TRUE,
})
end
else
table.insert(patterns,{
slots=opts.slots,
mat_filter=opts.mat_filter,
fgoalcheck=opts.fgoalcheck or aux.TRUE,
})
end
return patterns
end
-- Helper: combine multiple patterns into one condition function (no goto)
function Fusion.MultiCondition(tc,patterns,allow_extras)
return function(e,g,gc,chkf)
if not g then return false end
local locked=Fusion.LockedCodes
for _, pat in ipairs(patterns) do
-- skip patterns that don't include all locked codes
local ok=true
if locked then
for _,code in ipairs(locked) do
if not Fusion.PatternIncludesCode(pat,code) then
ok=false
break
end
end
end
if ok then
local cond=Fusion.FusionCondition(tc,pat.slots,pat.mat_filter,pat.fgoalcheck,allow_extras)
if cond(e,g,gc,chkf) then
return true
end
end
end
return false
end
end
-- Helper: compute the minimal and maximal material counts across patterns
function Fusion.PatternsMinMax(patterns)
local min_req=math.huge
local max_req=0
for _, pat in ipairs(patterns) do
local lo,hi=0,0
for _, slot in ipairs(pat.slots) do
if slot.group then
lo=lo+slot.group.min
hi=hi+slot.group.max
else
lo=lo+1
hi=hi+1
end
end
min_req=math.min(min_req,lo)
max_req=math.max(max_req,hi)
end
return min_req,max_req
end
-- Helper: combine patterns into one operation function
function Fusion.MultiOperation(tc, patterns)
return function(e,tp,eg,ep,ev,re,rp,gc,chkf)
-- filter patterns by any locked codes, once per operation
local locked=Fusion.LockedCodes
local active_patterns={}
if locked then
for _,pat in ipairs(patterns) do
local ok=true
for _, code in ipairs(locked) do
if not Fusion.PatternIncludesCode(pat,code) then
ok=false
break
end
end
if ok then table.insert(active_patterns,pat) end
end
else
-- no locked codes: all patterns active
active_patterns=patterns
end
-- compute min/max over active patterns
local min_req,max_req=Fusion.PatternsMinMax(active_patterns)
max_req=math.min(max_req,eg:GetCount())
-- strict condition uses only active patterns
local strict_cond=Fusion.MultiCondition(tc,active_patterns,false)
Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_FMATERIAL)
local sg=Group.CreateGroup()
--- arraify eg
local eg_arr={}
for mc in aux.Next(eg) do
table.insert(eg_arr,mc)
end
while true do
local finishable=sg:GetCount()>=min_req and strict_cond(e, sg, gc, chkf)
local addable=Group.CreateGroup()
for _,mc in ipairs(eg_arr) do
if not sg:IsContains(mc) then
sg:AddCard(mc)
-- completion test against active patterns
for _,pat in ipairs(active_patterns) do
if Fusion.CanCompleteFromMappings(e,sg,eg,pat.slots,pat.mat_filter,pat.fgoalcheck,tc,gc,chkf) then
addable:AddCard(mc)
break
end
end
sg:RemoveCard(mc)
end
end
if addable:GetCount()==0 then
assert(finishable)
Duel.SetFusionMaterial(sg)
return
end
local picked=Group.SelectUnselect(addable,sg,tp,finishable,true,min_req,max_req)
if not picked then
if finishable then
Duel.SetFusionMaterial(sg)
else
Duel.SetFusionMaterial(Group.CreateGroup())
end
return
end
if sg:IsContains(picked) then
sg:RemoveCard(picked)
else
sg:AddCard(picked)
end
end
end
end
-- Helper: detect if a pattern has a slot for a given code
function Fusion.PatternIncludesCode(pat,code)
for _, slot in ipairs(pat.slots) do
if slot.match_code==code then
return true
end
if slot.match_codes then
for _, c in ipairs(slot.match_codes) do
if c==code then return true end
end
end
end
return false
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment