-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathMovelist-entry.lua
570 lines (513 loc) · 17.3 KB
/
Movelist-entry.lua
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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
-- Entries for movelists
local m = {}
-- stylua: ignore start
local mw = require('mw')
local txt = require('Wikilib-strings')
local tab = require('Wikilib-tables')
local forms = require('Wikilib-forms')
local w = require('Wikilib')
local multigen = require('Wikilib-multigen')
local gen = require('Wikilib-gens')
local lib = require('Wikilib-learnlists')
local ms = require('MiniSprite')
local links = require('Links')
local css = require('Css')
local cc = require('ChooseColor')
local resp = require('Resp')
local gendata = require("Gens-data")
local blackabbr = require("Blackabbrev-data")
local pokes = require("Poké-data")
local groups = require("PokéEggGroup-data")
local useless = require("UselessForms-data")
-- stylua: ignore end
--[[
This table holds all the interesting values for an entry
Level and tm are handled exactly the same way, so there's actually no reason to
differentiate the entries (they are aliases).
Breed is almost equal but for the parameters processing (#\d{3}# is replaced
with the MS).
Tutor and event are unique, and the latter almost prints its parameter without
processing.
The entries are generated by the "entry" function. This calls two main
functions, "head" that builds the first half of the entry and is independent
of the kind, and "tail" that build the rest of the entry.
The tail is built this way: the general "tail" function takes as parameter the
kind plus any other parameter needed. The kind is used both to select the mapper
from a table (indexed with kinds) AND to format them together.
--]]
local entry = {}
-- Boolean parameters representation
entry.boolDisplay = { no = "×", yes = "✔" }
-- Map from gen to list of game abbrs (that are parameters) of that gen
entry.genGames = {
[1] = { "Y" },
[2] = { "C" },
[3] = { "FRLG", "E" },
[4] = { "HGSS", "PtHGSS" },
[5] = { "B2W2" },
[6] = { "ORAS" },
[7] = { "USUM", "LGPE" },
[8] = { "SpSc", "BDSP", "LA" },
[9] = { "SV" },
}
-- Reverse of the previous table
entry.gameGens = {}
tab.map(entry.genGames, function(v, k)
tab.map(v, function(abbr)
entry.gameGens[abbr] = k
end)
end)
-- Strings for printing
entry.strings = {
CELLBOX = [[| class="${textcolor} height-100" style="padding: 0.8ex 0.3ex;${cs}" | <div class="text-center height-100 roundy-5 vert-middle" style="${bg}; padding: 0 0.3ex;">${cnt}</div>]],
}
-- Sorted background colors of tutor cells
entry.tutorCellsColors = {
"cristallo",
"rossofuoco",
"smeraldo",
"xd",
"diamante",
"platino",
"heartgold",
"nero",
"nero2",
"x",
"rubinoomega",
"sole",
"ultrasole",
"lgpikachu",
"spada",
"isolaarmatura",
"diamantelucente",
"leggendearceus",
}
--[[
Data to split parameters of games of the same generation.
This table has an entry for generation. Each generation has a table whose
indexes are the sorted concat of abbrs of game that are in the entry.
Each entry in a gen is a list of tables, with the following keys:
- bg: bgcolor for the corresponding box
- abbr: abbr of the corresponding game
- val: the name of the parameter whose value should be the content of this
cell. "base" stands for the base value of the current generation
- colspan (optional): the number of colspan. Defaults to 1
--]]
entry.levelCellsData = {
[1] = {
Y = {
{ bg = "rosso", abbr = "RVB", val = "base" },
{ bg = "giallo", abbr = "G", val = "Y" },
},
},
[2] = {
C = {
{ bg = "oro", abbr = "OA", val = "base" },
{ bg = "cristallo", abbr = "C", val = "C" },
},
},
[3] = {
FRLG = {
{ bg = "rubino", abbr = "RZS", val = "base", colspan = 2 },
{ bg = "rossofuoco", abbr = "RFVF", val = "FRLG" },
},
E = {
{ bg = "rubino", abbr = "RZRFVF", val = "base", colspan = 2 },
{ bg = "smeraldo", abbr = "S", val = "E" },
},
},
[4] = {
HGSS = {
{ bg = "diamante", abbr = "DPPt", val = "base", colspan = 2 },
{ bg = "heartgold", abbr = "HGSS", val = "HGSS" },
},
PtHGSS = {
{ bg = "diamante", abbr = "DP", val = "base", colspan = 2 },
{ bg = "heartgold", abbr = "PtHGSS", val = "PtHGSS" },
},
},
[5] = {
B2W2 = {
{ bg = "bianco", abbr = "NB", val = "base" },
{ bg = "bianco2", abbr = "N2B2", val = "B2W2" },
},
},
[6] = {
ORAS = {
{ bg = "x", abbr = "XY", val = "base" },
{ bg = "rubinoomega", abbr = "ROZA", val = "ORAS" },
},
},
[7] = {
USUM = {
{ bg = "sole", abbr = "SL", val = "base", colspan = 2 },
{ bg = "ultrasole", abbr = "UsUl", val = "USUM" },
},
LGPE = {
{ bg = "sole", abbr = "SLUsUl", val = "base", colspan = 2 },
{ bg = "lgp", abbr = "LGPE", val = "LGPE" },
},
USUMLGPE = {
{ bg = "sole", abbr = "SL", val = "base" },
{ bg = "ultrasole", abbr = "UsUl", val = "USUM" },
{ bg = "lgp", abbr = "LGPE", val = "LGPE" },
},
},
[8] = {
BDSP = {
{ bg = "spada", abbr = "SpSc", val = "base", colspan = 2 },
{ bg = "perlasplendente", abbr = "DLPS", val = "BDSP" },
},
LA = {
{ bg = "spada", abbr = "SpSc", val = "base", colspan = 2 },
{ bg = "leggendearceus", abbr = "LPA", val = "LA" },
},
BDSPLA = {
{ bg = "spada", abbr = "SpSc", val = "base" },
{ bg = "perlasplendente", abbr = "DLPS", val = "BDSP" },
{ bg = "leggendearceus", abbr = "LPA", val = "LA" },
},
},
[9] = {},
}
-- Maximum of level columns for a generation. Exported because used also in
-- Movelist/hf
m.maxCellsNumber = {
2, -- 1
2, -- 2
3, -- 3
3, -- 4
2, -- 5
2, -- 6
3, -- 7
3, -- 8
1, -- 9
}
--[[
Prints a (real) cell for a single value.
Arguments:
- text: text content
- bgcolor: name of bg color (from modulo colore)
- bold: whether the content should be bold or not
- colspan: the number of colspan (default 1)
- tt: tt text (optional)
- abbr: games abbr to add after text (optional)
--]]
entry.makeBox = function(text, bgcolor, bold, colspan, tt, abbr)
local bg = bgcolor:lower() == "fff" and ""
or css.horizGradLua({ type = bgcolor })
text = bold and table.concat({ "'''", text, "'''" }) or text
local cnt = tt and tt ~= "" and links.tt(text, tt) or text
local tc
if bgcolor:lower() == "fff" then
tc = "black-text"
else
tc = cc.forModGradBgLua(bgcolor)
end
return txt.interp(entry.strings.CELLBOX, {
bg = bg,
textcolor = tc,
cs = colspan and colspan ~= 1 and ('" colspan="' .. colspan) or "",
cnt = abbr and table.concat({
"<span>",
cnt,
blackabbr[abbr] or "",
"</span>",
}) or cnt,
})
end
--[[
Table of functions that maps a single value (i.e: one argument of the module) to
a cell, depending on the kind of the movelist.
It's actually a wrapper for makeBox that changes the text depending on kind,
chooses text color (often black) and chooses between tt and abbr.
Parameters are named because of many possible nil:
- data: the value of the parameter as passed to the module
- bg: the bg color
- abbr (optional): the abbr of the game
- colspan (optional): the number of colspan, default 1
--]]
entry.printValue = {
level = function(args)
local text = args.data or "N/D"
local bg = args.bg
if text:lower() == "no" then
text = entry.boolDisplay.no
bg = "fff"
elseif text:lower() == "r" then
text = links.tt(
"R",
"Questa mossa può essere appresa solo tramite Ricordamosse"
)
end
return entry.makeBox(text, bg, true, args.colspan, args.abbr)
end,
tm = function(args)
local text = args.data and entry.boolDisplay[args.data:lower()] or "N/D"
local bg = args.bg
if text == entry.boolDisplay.no then
bg = "fff"
end
return entry.makeBox(text, bg, true, args.colspan, args.abbr)
end,
breed = function(args)
local text = args.data or "N/D"
text = text:match("%#")
and lib.mslistToModal(text, nil, entry.boolDisplay.yes)
or text
local bg = args.bg
if text:lower() == "no" then
text = entry.boolDisplay.no
bg = "fff"
end
return entry.makeBox(text, bg, true, args.colspan, nil, args.abbr)
end,
tutor = function(args)
if not args.data or args.data:lower() == "x" then
return ""
elseif args.data:lower() == "no" then
return entry.makeBox(entry.boolDisplay.no, "fff", true)
elseif args.data:lower() == "yes" then
return entry.makeBox(entry.boolDisplay.yes, args.bg, true)
end
end,
event = function(args)
-- Should be wrapped in a div because this text may go to multiple lines
-- and this breaks vert-middle
local text = table.concat({ "<div>", args.data, "</div>" })
return entry.makeBox(text, args.bg, false)
end,
}
--[[
This table maps a kind to a function that maps the entry source data to the
string with the actual value.
For instance, given a value from entry.levelCellsData it returns the string
corresponding to the cell for that generation; or given a tutorCellsColors it
returns the cell with the ✔ or × or an empty string, if there is no cell at all.
Keys are the possible values of "kind". Values are functions with two or three
arguments:
- source: the value from the source table
- args: arguments of the module needed, as passed to the "tail" function
- valPrinter: the corresponding function from entry.printValue
- key (optional): the key of source in the source table
--]]
entry.valueMapper = {
level = function(source, args, valPrinter, key)
-- key + args.startGen is the generation of this source because
-- table.filter compacts integer keys
local gen = key + args.startGen - 1
-- Searches for parameters
local parameters =
table.concat(tab.mapToNum(entry.genGames[gen], function(v)
return args[v] and v or nil
end, ipairs))
if parameters == "" then
-- No extra parameters
return valPrinter({
data = args[key],
bg = gendata[gen].region,
colspan = m.maxCellsNumber[gen],
})
else
-- Extra parameters
local boxes = tab.map(source[parameters], function(printData)
local idx = printData.val == "base" and key or printData.val
return valPrinter({
data = args[idx],
bg = printData.bg,
abbr = printData.abbr,
colspan = printData.colspan,
})
end)
return table.concat(boxes, "\n")
end
end,
tutor = function(source, args, valPrinter, key)
return valPrinter({ data = args[key], bg = source })
end,
event = function(source, args, valPrinter)
return valPrinter({ data = args[1], bg = "fff" })
end,
}
entry.valueMapper.tm = entry.valueMapper.level
entry.valueMapper.breed = entry.valueMapper.level
--[[
Prints "tail" cells (the ones depending on the kind).
Arguments:
- kind: a string with the kind of movelist. One of "level", "tm", "breed",
"tutor" or "event".
- args: any other args, in a table because they depend on kind
args should contain the following, depending on kind:
- "level"/"tm"/"breed": args.startGen should be the starting gen of this
entry, and values from 1 to (currentGen - startGen) should contain
the value to be displayed. Any other game abbr should be a named parameter.
- "tutor": an array of "X", "yes" and "no" at most as long as
entry.tutorCellsColors. Each value is interpreted as no cell, can
learn and can't learn respectively. Trailing missing values are
the same as "X".
- "event": a single value args[1], that is printed as it is.
--]]
entry.tail = function(kind, args)
kind = kind:lower()
local dataSource
if tab.search({ "level", "tm", "breed" }, kind) then
dataSource = tab.filter(entry.levelCellsData, function(_, k)
return k >= args.startGen
end)
elseif kind == "tutor" then
dataSource = entry.tutorCellsColors
else
-- kind == "event" or any other value (shouldn't happen)
dataSource = { "" }
end
-- Fixing absence of gen 8
local cells = tab.map(dataSource, function(v, k)
-- Simply applies the right function, depending on kind
return entry.valueMapper[kind](v, args, entry.printValue[kind], k)
.. "\n"
end)
return table.concat(tab.filter(cells, function(v)
return txt.trim(v) ~= ""
end))
end
--[[
Print "head" cells (the ones independent of kind)
Arguments:
- ndex: ndex of the Pokémon
- args: optional parameters, named to avoid lots of nil in the call:
* STAB: a string with the STAB value (either the empty string, "''"
or "'''")
* notes: any note that should be added in tt after the Pokémon's name
* allforms: a true value means that this entry is about all the
forms of this Pokémon
* useless: a true value means that the form of this entry is
useless, and will be searched in the right module
* movename: the name of the move, if different from page name
--]]
entry.head = function(ndex, args)
local ndexNumber, abbr = forms.getndexabbr(ndex)
local ndexFigures = string.ff(ndexNumber)
local ndexAbbr = ndexFigures .. forms.toEmptyAbbr(abbr)
-- First tries ndex + abbr, then the numeric ndex
local pokedata = pokes[ndexAbbr]
or pokes[ndexNumber]
or { name = "Missingno.", ndex = "000" }
local forml = args.allforms
and '<div class="text-small">Tutte le forme</div>'
or (
args.useless and useless[ndexNumber].links[abbr]
or forms.getlink(ndexAbbr, "")
)
pokedata = tab.merge(
multigen.getGen(pokedata),
multigen.getGen(groups[pokedata.ndex] or { group1 = "sconosciuto" })
)
local movename = args.movename or mw.title.getCurrentTitle().text
local stab = args.STAB == "no" and ""
or args.STAB
or lib.computeSTAB(ndexAbbr, movename)
pokedata.group1show = pokedata.group1 == "coleottero" and "Coleot"
or (
pokedata.group1 == "non ancora scoperto"
and "Non ancora<div>scoperto</div>"
or txt.fu(pokedata.group1)
)
pokedata.group2show = pokedata.group2 == "coleottero" and "Coleot"
or txt.fu(pokedata.group2)
pokedata.type2 = pokedata.type2 ~= pokedata.type1 and txt.fu(pokedata.type2)
or nil
pokedata.type1 = txt.fu(pokedata.type1)
return txt.interp(
[=[|- class="height-100"
| class="hidden-xs" | ${num}
| ${ani}
| <span class="hidden-xs">${stab}[[${name}]]${stab}${notes}${forml}</span>
| class="hidden-sm height-100" style="padding: 0.8ex 0.3ex;" | ${types}
| class="hidden-sm height-100" style="padding: 0.8ex 0.3ex;" | ${groups}
]=],
{
num = gen.ndexToString(tonumber(ndexFigures)),
ani = ms.staticLua({ ndexAbbr }),
stab = stab,
name = pokedata.name,
notes = lib.makeNotes(args.notes or ""),
forml = forml,
types = resp.twoTypeBoxesLua(
pokedata.type1,
pokedata.type2,
{ "tiny" },
nil,
{ "vert-center" }
),
groups = resp.twoEggBoxesLua(
pokedata.group1,
pokedata.group2,
{ "tiny" },
nil,
{ "vert-center" }
),
}
)
end
--[[
Generic entry creation function.
Arguments:
- p: wikicode arguments table
- kind: a string with the kind of entry ("level", "tm", "breed", "tutor",
"event")
--]]
entry.entry = function(p, kind)
p = w.trimAll(p)
local gen
-- p[1] can be both a gen number or an ndex, depending on kind
if tab.search({ "level", "tm", "breed" }, kind) then
gen = tonumber(table.remove(p, 1))
p.startGen = gen
end
-- now p[1] is the ndex, and may be followed by old params
local ndex = table.remove(p, 1)
return entry.head(ndex, {
STAB = p.STAB,
notes = p.note,
allforms = p.allforms,
useless = p.useless,
movename = p.movename,
}) .. entry.tail(kind, p)
end
-- ========================= Wikicode interfaces ==============================
--[[
Entry level
--]]
m.level = function(frame)
return entry.entry(mw.clone(frame.args), "level")
end
m.Level = m.level
--[[
Entry tm
--]]
m.tm = function(frame)
return entry.entry(mw.clone(frame.args), "tm")
end
m.Tm, m.TM = m.tm, m.tm
--[[
Entry breed
--]]
m.breed = function(frame)
return entry.entry(mw.clone(frame.args), "breed")
end
m.Breed = m.breed
--[[
Entry event
--]]
m.event = function(frame)
return entry.entry(mw.clone(frame.args), "event")
end
m.Event = m.event
--[[
Entry tutor
--]]
m.tutor = function(frame)
return entry.entry(mw.clone(frame.args), "tutor")
end
m.Tutor = m.tutor
return m