forked from YGOProjectUnderground/CardScripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproc_ritual_ext.lua
More file actions
243 lines (241 loc) · 10.1 KB
/
proc_ritual_ext.lua
File metadata and controls
243 lines (241 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
if not aux.RitualProcedure then
aux.RitualProcedure = {}
Ritual = aux.RitualProcedure
end
if not Ritual then
Ritual = aux.RitualProcedure
end
--required functions
local function ExtraReleaseFilter(c,tp)
return c:IsControler(1-tp) and c:IsHasEffect(EFFECT_EXTRA_RELEASE)
end
local function ForceExtraRelease(mg)
return function(e,tp,g,c)
return g:Includes(mg)
end
end
local function WrapTableReturn(func)
if func then
return function(...)
return {func(...)}
end
end
end
local function MergeForcedSelection(f1,f2)
if f1==nil or f2==nil then
return f1 or f2
end
return function(...)
local ret1,ret2=f1(...)
local repl1,repl2=f2(...)
return ret1 and repl1,ret2 or repl2
end
end
function Ritual.GetExtraLocationEffect(c,rc)
local effs={c:IsHasEffect(EFFECT_EXTRA_RITUAL_LOCATION)}
for _,eff in ipairs(effs) do
local val=eff:GetValue()
if (type(val)=="function" and val(eff,c,rc)) or val==1 then
return eff
end
end
end
function Ritual.ExtraLocationOPTCheck(c,rc,tp)
local extra_loc_eff=Ritual.GetExtraLocationEffect(c,rc)
return extra_loc_eff,extra_loc_eff and not extra_loc_eff:CheckCountLimit(tp)
end
function Ritual.UseExtraLocationCountLimit(c,rc,tp)
local extra_loc_eff=Ritual.GetExtraLocationEffect(c,rc)
if extra_loc_eff and extra_loc_eff:CheckCountLimit(tp) then
local extra_loc=extra_loc_eff:GetTargetRange()
if extra_loc_eff:GetType()&EFFECT_TYPE_SINGLE>0 or extra_loc and c:IsLocation(extra_loc) then
extra_loc_eff:UseCountLimit(tp)
if extra_loc_eff:GetProperty()&EFFECT_FLAG_GAIN_ONLY_ONE_PER_TURN>0 then
Duel.RegisterFlagEffect(tp,EFFECT_FLAG_GAIN_ONLY_ONE_PER_TURN,RESET_PHASE|PHASE_END,0,1)
end
end
end
end
function Ritual.ExtraLocFilter(c,filter,_type,e,tp,m,m2,forcedselection,specificmatfilter,lv,requirementfunc,sumpos,booltype,reqfunc)
if not (c:IsOriginalType(TYPE_RITUAL) and c:IsOriginalType(TYPE_MONSTER)) or (filter and not filter(c)) or not c:IsCanBeSpecialSummoned(e,SUMMON_TYPE_RITUAL,tp,false,true,sumpos) then return false end
local extra_loc_eff,used=Ritual.ExtraLocationOPTCheck(c,e:GetHandler(),tp)
if not extra_loc_eff or extra_loc_eff and used then return false end
if extra_loc_eff:GetProperty()&EFFECT_FLAG_GAIN_ONLY_ONE_PER_TURN>0 and Duel.HasFlagEffect(tp,EFFECT_FLAG_GAIN_ONLY_ONE_PER_TURN) then return false end
local lv=(lv and (type(lv)=="function" and lv(c)) or lv) or c:GetLevel()
lv=math.max(1,lv)
Ritual.SummoningLevel=lv
local mg=m:Filter(Card.IsCanBeRitualMaterial,c,c)
mg:Merge(m2-c)
if c.ritual_custom_condition then
return c:ritual_custom_condition(mg,forcedselection,_type)
end
if c.mat_filter then
mg:Match(c.mat_filter,c,tp)
end
if specificmatfilter then
mg:Match(specificmatfilter,nil,c,mg,tp)
end
forcedselection=MergeForcedSelection(c.ritual_custom_check,forcedselection)
local res=aux.SelectUnselectGroup(mg,e,tp,1,lv,Ritual.Check(c,lv,WrapTableReturn(forcedselection),_type,requirementfunc),0)
Ritual.SummoningLevel=nil
return res
end
Ritual.Target = aux.FunctionWithNamedArgs(
function(filter,_type,lv,extrafil,extraop,matfilter,stage2,location,forcedselection,specificmatfilter,requirementfunc,sumpos,extratg)
location = location or LOCATION_HAND
sumpos = sumpos or POS_FACEUP
return function(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then
local mg=Duel.GetRitualMaterial(tp,not requirementfunc)
local mg2=extrafil and extrafil(e,tp,eg,ep,ev,re,r,rp,chk) or Group.CreateGroup()
--if an EFFECT_EXTRA_RITUAL_MATERIAL effect has a forcedselection of its own
--add that forcedselection to the one of the Ritual Spell, if any
local extra_eff_g=mg:Filter(Card.IsHasEffect,nil,EFFECT_EXTRA_RITUAL_MATERIAL)
local func=forcedselection
--if a card controlled by the opponent has EFFECT_EXTRA_RELEASE, then it MUST be
--used as material
local extra_mat_g=mg:Filter(ExtraReleaseFilter,nil,tp)
if #extra_mat_g>0 then
func=MergeForcedSelection(ForceExtraRelease(extra_mat_g),func)
end
if #extra_eff_g>0 then
local prev_repl_function=nil
for tmp_c in extra_eff_g:Iter() do
local effs={tmp_c:IsHasEffect(EFFECT_EXTRA_RITUAL_MATERIAL)}
for _,eff in ipairs(effs) do
local repl_function=eff:GetLabelObject()
if repl_function and prev_repl_function~=repl_function[1] then
prev_repl_function=repl_function[1]
func=MergeForcedSelection(func,repl_function[1])
end
end
end
end
Ritual.CheckMatFilter(matfilter,e,tp,mg,mg2)
-- custom ----
local final_group=Group.CreateGroup()
local base_ritual_group=Duel.GetMatchingGroup(Ritual.Filter,tp,location,0,nil,filter,_type,e,tp,mg,mg2,func,specificmatfilter,lv,requirementfunc,sumpos)
local extra_loc_group=Duel.GetMatchingGroup(Ritual.ExtraLocFilter,tp,LOCATION_NOTHAND,0,nil,filter,_type,e,tp,mg,mg2,func,specificmatfilter,lv,requirementfunc,sumpos)
final_group:Merge(base_ritual_group)
final_group:Merge(extra_loc_group)
return #final_group>0
--------------
end
if extratg then extratg(e,tp,eg,ep,ev,re,r,rp,chk) end
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,nil,1,tp,location)
end
end,"filter","lvtype","lv","extrafil","extraop","matfilter","stage2","location","forcedselection","specificmatfilter","requirementfunc","sumpos","extratg")
Ritual.Operation = aux.FunctionWithNamedArgs(
function(filter,_type,lv,extrafil,extraop,matfilter,stage2,location,forcedselection,customoperation,specificmatfilter,requirementfunc,sumpos)
location = location or LOCATION_HAND
sumpos = sumpos or POS_FACEUP
return function(e,tp,eg,ep,ev,re,r,rp)
local mg=Duel.GetRitualMaterial(tp,not requirementfunc)
local mg2=extrafil and extrafil(e,tp,eg,ep,ev,re,r,rp) or Group.CreateGroup()
--if an EFFECT_EXTRA_RITUAL_MATERIAL effect has a forcedselection of its own
--add that forcedselection to the one of the Ritual Spell, if any
local func=forcedselection
local extra_eff_g=mg:Filter(Card.IsHasEffect,nil,EFFECT_EXTRA_RITUAL_MATERIAL)
if #extra_eff_g>0 then
local prev_repl_function=nil
for tmp_c in extra_eff_g:Iter() do
local effs={tmp_c:IsHasEffect(EFFECT_EXTRA_RITUAL_MATERIAL)}
for _,eff in ipairs(effs) do
local repl_function=eff:GetLabelObject()
if repl_function and prev_repl_function~=repl_function[1] then
prev_repl_function=repl_function[1]
func=MergeForcedSelection(func,repl_function[1])
end
end
end
end
--if a card controlled by the opponent has EFFECT_EXTRA_RELEASE, then it MUST be
--used as material
local extra_mat_g=mg:Filter(ExtraReleaseFilter,nil,tp)
if #extra_mat_g>0 then
func=MergeForcedSelection(ForceExtraRelease(extra_mat_g),func)
end
Ritual.CheckMatFilter(matfilter,e,tp,mg,mg2)
local ft=Duel.GetLocationCount(tp,LOCATION_MZONE)
-- custom ----
local tg=Group.CreateGroup()
local final_group=Group.CreateGroup()
local base_ritual_group=Duel.GetMatchingGroup(aux.NecroValleyFilter(Ritual.Filter),tp,location,0,nil,filter,_type,e,tp,mg,mg2,func,specificmatfilter,lv,requirementfunc,sumpos)
local extra_loc_group=Duel.GetMatchingGroup(aux.NecroValleyFilter(Ritual.ExtraLocFilter),tp,LOCATION_NOTHAND,0,nil,filter,_type,e,tp,mg,mg2,func,specificmatfilter,lv,requirementfunc,sumpos)
final_group:Merge(base_ritual_group)
final_group:Merge(extra_loc_group)
if #final_group>0 then
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_SPSUMMON)
tg=final_group:Select(tp,1,1,nil)
end
if #tg>0 then
local tc=tg:GetFirst()
Ritual.UseExtraLocationCountLimit(tc,e:GetHandler(),tp)
--------
local lv=(lv and (type(lv)=="function" and lv(tc)) or lv) or tc:GetLevel()
lv=math.max(1,lv)
Ritual.SummoningLevel=lv
local mat=nil
mg:Match(Card.IsCanBeRitualMaterial,tc,tc)
mg:Merge(mg2-tc)
if specificmatfilter then
mg:Match(specificmatfilter,nil,tc,mg,tp)
end
if tc.ritual_custom_operation then
tc:ritual_custom_operation(mg,func,_type)
mat=tc:GetMaterial()
else
func=MergeForcedSelection(tc.ritual_custom_check,func)
if tc.mat_filter then
mg:Match(tc.mat_filter,tc,tp)
end
if ft>0 and not func then
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_RELEASE)
if _type==RITPROC_EQUAL then
mat=mg:SelectWithSumEqual(tp,requirementfunc or Card.GetRitualLevel,lv,1,#mg,tc)
else
mat=mg:SelectWithSumGreater(tp,requirementfunc or Card.GetRitualLevel,lv,tc)
end
else
mat=aux.SelectUnselectGroup(mg,e,tp,1,lv,Ritual.Check(tc,lv,WrapTableReturn(func),_type,requirementfunc),1,tp,HINTMSG_RELEASE,Ritual.Finishcon(tc,lv,WrapTableReturn(func),requirementfunc,_type))
end
end
--check if a card from an "once per turn" EFFECT_EXTRA_RITUAL_MATERIAL effect was selected
local extra_eff_g=mat:Filter(Card.IsHasEffect,nil,EFFECT_EXTRA_RITUAL_MATERIAL)
for tmp_c in extra_eff_g:Iter() do
local effs={tmp_c:IsHasEffect(EFFECT_EXTRA_RITUAL_MATERIAL)}
for _,eff in ipairs(effs) do
--if eff is OPT and tmp_c is not returned
--by the Ritual Spell's exrafil
--then use the count limit and register
--the flag to turn the extra eff OFF
--requires the EFFECT_EXTRA_RITUAL_MATERIAL effect
--to check the flag in its condition
local _,max_count_limit=eff:GetCountLimit()
if max_count_limit>0 and not mg2:IsContains(tmp_c) then
eff:UseCountLimit(tp,1)
Duel.RegisterFlagEffect(tp,eff:GetHandler():GetCode(),RESET_PHASE+PHASE_END,0,1)
end
end
end
if not customoperation then
tc:SetMaterial(mat)
if extraop then
extraop(mat:Clone(),e,tp,eg,ep,ev,re,r,rp,tc)
else
Duel.ReleaseRitualMaterial(mat)
end
Duel.BreakEffect()
Duel.SpecialSummon(tc,SUMMON_TYPE_RITUAL,tp,tp,false,true,sumpos)
tc:CompleteProcedure()
if tc:IsFacedown() then Duel.ConfirmCards(1-tp,tc) end
if stage2 then
stage2(mat,e,tp,eg,ep,ev,re,r,rp,tc)
end
else
customoperation(mat:Clone(),e,tp,eg,ep,ev,re,r,rp,tc)
end
Ritual.SummoningLevel=nil
end
end
end,"filter","lvtype","lv","extrafil","extraop","matfilter","stage2","location","forcedselection","customoperation","specificmatfilter","requirementfunc","sumpos")