-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathwfrp-4th-edition-random-grimoire.html
605 lines (566 loc) · 38.1 KB
/
wfrp-4th-edition-random-grimoire.html
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
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
<!DOCTYPE html>
<html lang="en">
<head>
<title>Random Magic Grimoire Generator</title>
<script>
// Arcane spell list placeholder
var AllArcane = [];
var Arcane = [
["Aethyric Armour", 2],
["Aethyric Arms", 2],
["Arrow Shield", 3],
["Blast", 4],
["Bolt", 4],
["Breath", 6],
["Bridge", 4],
["Chain Attack", 6],
["Corrosive Blood", 4],
["Dark Vision", 1],
["Distracting", 4],
["Dome", 7],
["Drop", 1],
["Entangle", 3],
["Fearsome", 3],
["Flight", 3],
["Magic Shield", 4],
["Move Object", 4],
["Mundane Aura", 4],
["Push", 6],
["Teleport", 5],
["Terrifying", 7],
["Ward", 5]
];
var ArcaneChaos = [
["Blast of Corruption", 8], ["Bolt of Corruption", 8], ["Daemonic Mien", 8],
["Foul Messenger", 8], ["Joyous Aspect", 4], ["Obsession", 8],
["Power of Chaos", 4], ["Rend Aethyr", 16], ["Slave to Darkness", 8]
];
var ArcaneWindsOfMagic = [
["Belligerence of the Bloodmarsh", 2], ["Collapse Construct", 6], ["Decipher Curse", 4],
["Disrupt Magic", 8], ["Fly-Infested Rotweed", 4], ["Lifebloom Silt", 4],
["Silence", 4]
];
var LoreSpells = {
// Combined spells from all sources will be merged here
};
var LoreSpellsCore = {
"Lore of Beasts": [["Amber Talons", 6], ["Beast Form", 5], ["Beast Master", 10],
["Beast Tongue", 3], ["Flock of Doom", 8], ["Hunter’s Hide", 6],
["The Amber Spear", 8], ["Wyssan’s Wildform", 8]],
"Lore of Death": [["Caress of Laniph", 7], ["Dying Words", 6], ["Purple Pall of Shyish", 6],
["Sanctify", 6], ["Scythe of Shyish", 6], ["Soul Vortex", 8],
["Steal Life", 7], ["Swift Passing", 6]],
"Lore of Fire": [["Aqshy’s Aegis", 5], ["Cauterise", 4], ["Crown of Flame", 8],
["Flaming Hearts", 8], ["Firewall", 6], ["Great Fires of U’Zhul", 10],
["Flaming Sword of Rhuin", 8], ["Purge", 10]],
"Lore of Heavens": [["Cerulean Shield", 7], ["Comet of Casandora", 10],
["Fate’s Fickle Finger", 6], ["Starcrossed", 7], ["T’Essla’s Arc", 7],
["The First Portent of Amul", 3], ["The Second Portent of Amul", 6],
["The Third Portent of Amul", 12]],
"Lore of Metal": [["Crucible of Chamon", 7], ["Enchant Weapon", 6],
["Feather of Lead", 5], ["Fool’s Gold", 4], ["Forge of Chamon", 9], ["Glittering Robe", 5],
["Mutable Metal", 5], ["Transmutation of Chamon", 12]],
"Lore of Life": [["Barkskin", 3], ["Earthblood", 6], ["Earthpool", 8], ["Fat of the Land", 4], ["Forest of Thorns", 6],
["Lie of the Land", 5], ["Lifebloom", 8], ["Regenerate", 6]],
"Lore of Light": [["Banishment", 12], ["Blinding Light", 5], ["Clarity of Thought", 6], ["Daemonbane", 10],
["Healing Light", 9], ["Net of Amyntok", 8], ["Phâ\'s Protection", 10], ["Speed of Thought", 8]],
"Lore of Shadows": [["Choking Shadows", 6], ["Doppelganger", 10], ["Illusion", 8],
["Mindslip", 6], ["Mystifying Miasma", 6], ["Shadowsteed", 6],
["Shadowstep", 8], ["Shroud of Invisibility", 8]],
"Lore of Hedgecraft": [["Goodwill", 0], ["Mirkride", 0], ["Nepenthe", 0], ["Nostrum", 0],
["Part the Branches", 0], ["Protective Charm", 0]],
"Lore of Witchcraft": [["Blight", 14], ["Creeping Menace", 6], ["Curse of Crippling Pain", 10],
["Curse of Ill-Fortune", 8], ["Haunting Horror", 8], ["The Evil Eye", 6]],
"Lore of Daemonology": [["Destroy Lesser Daemon", 6], ["Detect Daemon", 4],
["Manifest Lesser Daemon", 8]],
"Lore of Necromancy": [["Raise Dead", 8], ["Reanimate", 8],
["Screaming Skull", 8], ["Vanhel’s Cal", 6]],
"Lore of Nurgle": [["Stream of Corruption", 6]],
"Lore of Slaanesh": [["Acquiescence", 5]],
"Lore of Tzeentch": [["Treason of Tzeentch", 6]]
};
var LoreSpellsWindsOfMagic = {
"Lore of Light": [
["Abulla’s Snare", 5], ["Assault of Stone", 12], ["Banishment", 12],
["Blinding Light", 5], ["Clarity of Thought", 6], ["Crevasse", 8],
["Daemonbane", 10], ["Dazzling Brightness", 5], ["Driving Intent", 4],
["Healing Light", 9], ["Erect the Edifice", 9], ["Eyes of Volans", 6],
["Hands of Karkora", 8], ["Illuminate the Edifice", 4], ["Light of Purity", 6],
["Meissner’s Instantaneous Librarian", 2], ["Net of Amyntok", 8],
["Orb of Hysh", 5], ["Perfect Comprehension", 5], ["Phâ’s Protection", 10],
["Pierce the Veil", 4], ["Shimmering Cloak", 9], ["Speed of Thought", 8],
["Time Amok", 11]
],
"Lore of Metal": [
["Armour of Tin", 4], ["Breach the Unknown", 4], ["Crucible of Chamon", 7],
["Curse of Rust", 4], ["Enchant Weapon", 6], ["Fault of Form", 2],
["Feather of Lead", 5], ["Fool’s Gold", 4], ["Forge of Chamon", 9],
["Gehenna’s Golden Globe", 13], ["Gilded Cage", 9], ["Glittering Robe", 5],
["Golden Touch", 7], ["Goldsteel Shielding", 10], ["Inscription", 2],
["Knot Untied", 5], ["Metal Mended", 4], ["Meteoric Ironclad", 7],
["Mutable Metal", 5], ["Prismatic Refraction of Habermas", 5],
["Puchta’s Silver Compass", 2], ["Replication of Levorg", 6],
["Transmutation of Chamon", 12], ["Trial and Error", 3]
],
"Lore of Life": [
["Almanac", 4], ["Barkskin", 3], ["Dwellers Below", 13], ["Earthblood", 6],
["Earthpool", 8], ["Fat of the Land", 4], ["Flesh of Stone", 9],
["Forest of Thorns", 6], ["Gardener’s Warcry", 9], ["Geyser", 8],
["Invigorating Chant", 6], ["Jade Casket", 6], ["Leaf Fall", 6],
["Leyfinding", 5], ["Lie of the Land", 5], ["Lifebloom", 8],
["Nature’s Whisper", 8], ["Paranoth’s Pathway", 4], ["Regenerate", 6],
["Spiral Stair", 6], ["Vaunted Transmogrification of Colchis", 6],
["Verdant Apotheosis", 16], ["Vital Growth", 7], ["Wood Shape", 8]
],
"Lore of Heavens": [
["Azure Blades", 6], ["Cerulean Shield", 7], ["Comet of Casandora", 10],
["Curse of Fate", 8], ["Divination", 3], ["Enemy Foreseen", 4],
["Fantastic Foresight", 7], ["Fate’s Fickle Fingers", 6], ["Fate Illuminated", 5],
["Lens on the Sky", 3], ["Let the Four Winds Blow!", 9],
["Mistral From the Stratosphere", 7], ["Mystic Mirror", 7], ["Polish and Glean", 1],
["Project Spirit", 7], ["Sapphire Arch", 6], ["Starcrossed", 7], ["Starshine", 8],
["Storm of Shemtek", 11], ["T’Essla’s Arc", 7], ["The First Portent of Amul", 3],
["The Second Portent of Amul", 6], ["The Third Portent of Amul", 12],
["Thorsen’s Thunderstorm", 11]
],
"Lore of Shadows": [
["Bewilder", 5], ["Black Horrors", 6], ["Bridge of Shadows", 6],
["Choking Shadows", 6], ["Dance of Despair", 13], ["Deep Pockets", 5],
["Doppelganger", 10], ["Grand Illusion", 14], ["Grey Wings", 6],
["Horn of Andar", 5], ["Hush", 3], ["Illusion", 8], ["Mindslip", 6],
["Mutable Visage", 4], ["Mystifying Miasma", 6], ["Pit of Tarnus", 8],
["Ribauld’s Retroactive Illusion", 11], ["Shadow Grove", 5],
["Shadowsteed", 6], ["Shadowstep", 8], ["Shroud of Invisibility", 8],
["Substance of Shadow", 9], ["Traitor of Tarn", 12]
],
"Lore of Death": [
["Acceptance of Fate", 6], ["Amaranth", 7], ["Animus Imprisoned", 12],
["Ashes and Dust", 9], ["Caress of Laniph", 4], ["Compel Spirits", 6],
["Crystal Maze", 13], ["Death’s Release", 5], ["Dying Words", 6],
["Fate of Bjuna", 8], ["Iyrtu’s Embrace", 4], ["Limbwither", 5],
["Purple Pall of Shyish", 9], ["Sanctify", 10], ["Scythe of Shyish", 6],
["Shyish Uncovered", 4], ["Soul Vortex", 8], ["Speed of Lykos", 3],
["Steal Life", 7], ["Swift Passing", 6], ["Taste of Death", 7],
["Telepathy", 1], ["Tide of Years", 3], ["Wild Kin of Zandox", 5]
],
"Lore of Fire": [
["Aqshy’s Aegis", 5], ["Body of Fire", 5], ["Boiling Blood", 5],
["Burning Head", 6], ["Captivating Flame", 3], ["Cauterise", 4],
["Choleric", 2], ["Crown of Flame", 8], ["Firewall", 6],
["Flamestorm", 8], ["Flaming Hearts", 8], ["Flaming Sword of Rhuin", 8],
["Forge of Tarnus", 6], ["Great Fires of U’Zhul", 10], ["Ignite", 3],
["Inextinguishable Flame", 3], ["Kindleflame", 2], ["Kindred of the Hearth", 4],
["Magma Storm", 13], ["Purge", 10], ["Sanguine Swords", 6],
["Taste of Fire", 2], ["Withering Heat", 6], ["Ygethmor’s Flaming Blizzard", 12]
],
"Lore of Beasts": [
["Amber Talons", 6], ["Amber Trance", 4], ["Awakening of the Wood", 8],
["Beast Form", 5], ["Beast Master", 10], ["Beast Tongue", 3],
["Beast Unbroken", 4], ["Curse of Anraheir", 5], ["Eyes of the Pack", 3],
["Flock of Doom", 8], ["Follow Scent", 4], ["Hunter’s Hide", 6],
["Hunter’s Moons", 8], ["Merciw’s Monstrous Regiment", 13], ["Musk Spray", 2],
["Quick Passage", 4], ["Summon Mount", 6], ["The Amber Spear", 8],
["The Ox Stands", 5], ["Transformation of Kadon", 14], ["Vengeful Hood", 7],
["Winter Coat", 2], ["Writhing Worm", 4], ["Wyssan’s Wildform", 8]
]
};
var LoreSpellsArchivesOfEmpire3 = {
"Lore of Hedgecraft": [ ["Dagger of the Art", 4], ["Fellstave", 9],
["Goodwill", 0], ["Invigorate", 2], ["Lovelock", 10],
["Mirkride", 0], ["Nepenthe", 0], ["Nostrum", 0],
["Part the Branches", 0], ["Protection Pouch", 5], ["Protective Charm", 0],
["Sightstep", 7], ["Silvertide", 4], ["The Ousting", 8], ["Wyrd Ward", 0]]
};
var LoreSpellsBloodAndBramble = {
"Lore of Hedgecraft": [["Badwill", 0], ["Bonesetter", 0], ["Cleanslate", 0]],
"Lore of Witchcraft": [["Banishment of Böl", 8], ["Bonesnapper", 6], ["Congeal", 4]],
// (more spells)
};
var LoreSpellsSullasara = {
"Lore of Beasts": [["Beast Made Well", 3], ["Cruelty’s Deserts", 2], ["Wyssan’s Ally", 4],
["Wildercall", 2]],
"Lore of Death": [["Stay Death’s Hand", 3], ["Deathsight", 2], ["Preservation", 5]],
"Lore of Fire": [["Flashcook", 2], ["Comfort", 3], ["Ceaseless Flame", 2]],
"Lore of Heavens": [["Birdspeech", 4], ["Weathervane", 2], ["Gale", 5]],
"Lore of Metal": [["Tale of Metal", 3], ["Rigor of Steel", 3],["Sense Metal", 1]],
"Lore of Life": [["Ferment", 3], ["Timbervault", 4], ["Track’s Tale Told", 3]],
"Lore of Light": [["Cleansing Glow", 3], ["Disgust", 5], ["Illuminate", 3]],
"Lore of Shadows": [["Shadows of Splendour", 4], ["Cloak Activity", 6], ["Pall of Darkness", 5]]
};
var LoreSpellsEnemyInShadowsCompanion = {
"Lore of Tzeentch": [
["Boon of Tzeentch", 9], ["The Purple Hand", 3], ["Curse of Tzeentch", 9],
["Blue Fire of Tzeentch", 6], ["Bolt of Change", 9],
["The Flickering Flames of Fickle Fate", 4], ["Master of Fortune", 8],
["Mindfire", 6], ["Pink Fire of Tzeentch", 6], ["Sense the Skein", 3],
["Transformation of Tzeentch", 10], ["Tzeentch’s Firestorm", 11],
["Tzeentch’s Golden Aura", 7], ["Word of Tzeentch", 7]
]
};
var LoreSpellsDeathInTheReikCompanion = {
"Lore of Tzeentch": [
["Bension of Tzeentch", 9], ["Enrage Beast", 6], ["Climb", 5],
["Tremor", 8], ["Subvert Strength", 11], ["Gift of the Beast", 8],
["Transformation of the Beast", 12]
]
};
// Spells from "Power Behind the Throne Companion"
var LoreSpellsPowerBehindTheThroneCompanion = {
"Lore of Slaanesh": [
["Acquiescence", 8], ["Aura of Acquiescence", 12], ["Bonds of Slaanesh", 8],
["Breath of Inspiration", 8], ["Blissful Throes", 6], ["Cacophonic Caress", 6],
["Careless Whispers", 8], ["Chaos Spawn", 10], ["Cursed Caress", 8],
["Cutting Wit", 6], ["Delicious Excruciation", 6], ["Fleshy Curse", 10],
["Flesh Puppet", 10], ["From Pain, Pleasure", 6], ["Lash of Slaanesh", 6],
["Gift of Slaanesh", 8], ["Luxurious Torment", 8], ["Mask of Desire", 8],
["Pavane of Slaanesh", 8], ["Phantasmagoria", 8], ["Succubus’s Caress", 8],
["Summon Daemonette", 12], ["Summon Daemonette Pack", 25],
["Titillating Delusions", 8]
]
};
var LoreSpellsEmpireInRuinsCompanion = {
"Lore of Necromancy": [
["Spirit Walk", 6]
]
};
var LoreSpellsSeaOfClaws = {
"Lore of Heavens": [["Living Mire", 8], ["Watter Water Everywhere", 6], ["Whirlpool", 6]],
"Lore of Life": [["Blessings of Bel Shaaner", 2], ["Niezlib's Optimal Firing Solution", 6], ["Sea of Glass", 10]]
};
var LORECOLOUR = {
"Lore of Beasts": [["amber","brown","tan"]],
"Lore of Death": [["purple","black","dark"]],
"Lore of Fire": [["red","orange","yellow"]],
"Lore of Heavens": [["blue","celeste","silver"]],
"Lore of Metal": [["golden","yellow","bronze"]],
"Lore of Life": [["green","jade","tan"]],
"Lore of Light": [["white","silver","ivory"]],
"Lore of Shadows": [["black","dark","grey"]],
"Lore of Hedgecraft": [["green","brown","tan","black"]],
"Lore of Witchcraft": [["black","purple","red","blue","white","dark grey"]],
"Lore of Daemonology": [["black","purple","red","blue","white","dark grey"]],
"Lore of Necromancy": [["black","purple","red","blue","white","dark grey"]],
"Lore of Nurgle": [["green","brown","tan","black"]],
"Lore of Slaanesh": [["pink","purple","black","dark"]],
"Lore of Tzeentch": [["blue","celeste","silver","gold","multicoloured"]]
};
var LOREMATERIAL = {
"Lore of Beasts": [["hide", "$COLOUR leather", "fur covered", "bone covered"]],
"Lore of Death": [["$COLOUR velvet", "$COLOUR silk", "bone covered"]],
"Lore of Fire": [["iron covered","darkened $COLOUR leather","charred $COLOUR cloth"]],
"Lore of Heavens": [["$COLOUR silk", "$COLOUR velvet"]],
"Lore of Metal": [["gold covered", "$COLOUR metal covered"]],
"Lore of Life": [["jade covered", "$COLOUR cloth", "wood covered"]],
"Lore of Light": [["$COLOUR cloth","silver covered","ivory covered"]],
"Lore of Shadows": [["$COLOUR velvet","$COLOUR silk","$COLOUR canvas"]],
"Lore of Hedgecraft": [["plain canvas","wood covered"]],
"Lore of Witchcraft": [["$COLOUR leather"]],
"Lore of Daemonology": [["$COLOUR velvet","$COLOUR silk","bone covered","extrange $COLOUR leather"]],
"Lore of Necromancy": [["bone covered", "extrange $COLOUR leather"]],
"Lore of Nurgle": [["moist $COLOUR leather","rotting $COLOUR leather","rotting $COLOUR hide"]],
"Lore of Slaanesh": [["supple $COLOUR leather","$COLOUR silk","$COLOUR velvet"]],
"Lore of Tzeentch": [["$COLOUR velvet","$COLOUR silk","bone covered","extrange $COLOUR leather","gold","$COLOUR metal","$COLOUR wood","$COLOUR bone","$COLOUR parchment"]]
};
var LOREDECORATION = {
"Lore of Beasts": [[" with strings of animal teeth hanging from its spine", " adorned with a few wild feathers", " decorated with sharp claws strung along the edges"]],
"Lore of Death": [[" with skulls embossed on the cover"," with a few small bones pinned on it"," decorated with black and purple roses printed on the front"]],
"Lore of Fire": [[" etched with flames along the borders"," secured with a lock and seven keys"," adorned with fiery motifs blazing across the cover"]],
"Lore of Heavens": [[" covered with intricate star patterns"," with a few feathers"," illustrated with constellation motif"]],
"Lore of Metal": [[" covered with extrange alchemical simbols"," reinforced with metal corner guards", " with metal chains to keep it closed"]],
"Lore of Life": [[" within it, a few pressed flowers"," decorated with leaves motifs"," with a few petals tucked inside"]],
"Lore of Light": [[" adorned with winding serpent motifs"," with candle wax drip stains"," decorated with piramid motifs"]],
"Lore of Shadows": [[" with a few raven feathers to bookmark it"," looking like a common edition of a mundane book"," reinforced and rugged, prepared for travel"]],
"Lore of Hedgecraft": [[" with a few pressed herbs tucked inside"," with a few small bones pinned on it"," looking handmade"]],
"Lore of Witchcraft": [[" with a few small bones pinned on it"," spattered dark crimsom stains"]],
"Lore of Daemonology": [[" spattered dark crimsom stains"," with a few small bones pinned on it"]],
"Lore of Necromancy": [[" with a few small bones pinned on it"," with skulls embossed on the cover"," spattered dark crimsom stains",", it smells distinctly of dust"]],
"Lore of Nurgle": [[" that attracks flies"," with a few flatten maggots inside"," with a few small bones pinned on it"]],
"Lore of Slaanesh": [[", it smells of honey and perfume"," with a pleasant touch", " adorned tasteful gold inlays over it"]],
"Lore of Tzeentch": [[" illuminated with strange symbols in the margin"," with a few $COLOUR feathers tucked inside"," with a few $COLOUR gems embedded in the cover"]]
};
// Colors and book decorations
var COLOUR = [
"$LORECOLOUR", "$LORECOLOUR", "$LORECOLOUR", "$LORECOLOUR",
"black", "purple", "red", "blue", "white", "dark gray",
"yellow", "tan", "green", "brown"
];
var BOOKDECORATION = [
"",
"", // Empty string for no decoration
"$LOREDECORATION","$LOREDECORATION","$LOREDECORATION",
", within it are a few dried, pressed flowers between the pages",
" with a few $COLOUR ribbons carefully placed as bookmarks",
" with several $COLOUR strings tied around the spine as bookmarks",
" with intricate illuminations drawn in the margins",
" with a few $COLOUR feathers tucked between the pages",
" secured with a hefty lock and key to keep it closed",
" adorned with $COLOUR gems embedded in the cover",
" with an illegible ex-libris scrawled on its first page",
" reinforced with sturdy metal corner guards"
];
var BOOKCOVERMATERIAL = [
"$LOREMATERIAL", "$LOREMATERIAL", "$LOREMATERIAL", "$LOREMATERIAL",
"$COLOUR leather", "$COLOUR parchment", "$COLOUR silk", "$COLOUR velvet",
"$COLOUR canvas", "wooden covered", "thin metal covered"
];
var BOOKLOOKS = [
"old and worn", "new and pristine", "well-used", "well-loved", "ancient", "dog-eared"
];
// ALLSTRINGS array to map placeholders to arrays
var ALLSTRINGS = [
["$COLOUR", COLOUR],
["$BOOKCOVERMATERIAL", BOOKCOVERMATERIAL],
["$BOOKLOOKS", BOOKLOOKS],
["$BOOKDECORATION", BOOKDECORATION]
];
var BOOK = [
"A $BOOKLOOKS $BOOKCOVERMATERIAL book$BOOKDECORATION",
];
// Helper function to generate random number between min and max (inclusive)
function randomBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function removedoublespaces (str) {
str = str.replace(/ +(?= )/g,'');
str = str.replace(/\s+,/g, ',');
str = str.replace(/ \./g,'.');
return str;
}
function aanmanagement( str) {
var strnew = str.replace(/\b(a)\s([aeiou])/ig,'$1n $2');
return strnew;
}
// Helper function to randomly select N spells from a given list
function getRandomSpells(spellList, count) {
let spells = [];
while (spells.length < count) {
let spell = spellList[randomBetween(0, spellList.length - 1)];
if (!spells.includes(spell)) { // Avoid duplicates
spells.push(spell);
}
}
return spells;
}
function markSpellsWithSource(spellList, marker, markSource) {
return spellList.map(spell => markSource ? [spell[0] + `<sup>${marker}</sup>`, spell[1]] : spell);
}
function mergeSpells(chosenLore) {
// Reset LoreSpells
LoreSpells = {};
AllArcane = Arcane;
// Check if source marking is enabled
let markSource = document.getElementById("markSource").checked;
// Always include the base Rulebook spells
Object.keys(LoreSpellsCore).forEach(lore => {
if (!LoreSpells[lore]) LoreSpells[lore] = [];
LoreSpells[lore] = LoreSpells[lore].concat(LoreSpellsCore[lore]);
});
// Add Winds of Magic spells with marker if selected
if (document.getElementById("windsOfMagic").checked) {
Object.keys(LoreSpellsWindsOfMagic).forEach(lore => {
if (!LoreSpells[lore]) LoreSpells[lore] = [];
LoreSpells[lore] = markSpellsWithSource(LoreSpellsWindsOfMagic[lore], "WoM", markSource);
});
AllArcane = Arcane.concat(markSpellsWithSource(ArcaneWindsOfMagic, "WoM", markSource));
}
// Add Blood and Bramble spells with marker if selected
if (document.getElementById("bloodAndBramble").checked) {
Object.keys(LoreSpellsBloodAndBramble).forEach(lore => {
if (!LoreSpells[lore]) LoreSpells[lore] = [];
LoreSpells[lore] = LoreSpells[lore].concat(markSpellsWithSource(LoreSpellsBloodAndBramble[lore], "BnB", markSource));
});
}
// Add Sullasara’s Spells with marker if selected
if (document.getElementById("sullasaraSpells").checked) {
Object.keys(LoreSpellsSullasara).forEach(lore => {
if (!LoreSpells[lore]) LoreSpells[lore] = [];
LoreSpells[lore] = LoreSpells[lore].concat(markSpellsWithSource(LoreSpellsSullasara[lore], "SS", markSource));
});
}
// Add Enemy in Shadows Companion spells with marker if selected
if (document.getElementById("enemyInShadows").checked) {
Object.keys(LoreSpellsEnemyInShadowsCompanion).forEach(lore => {
if (!LoreSpells[lore]) LoreSpells[lore] = [];
LoreSpells[lore] = LoreSpells[lore].concat(markSpellsWithSource(LoreSpellsEnemyInShadowsCompanion[lore], "EiSC", markSource));
});
if (chosenLore === "Lore of Nurgle" || chosenLore === "Lore of Slaanesh" || chosenLore === "Lore of Tzeentch") {
AllArcane = Arcane.concat(markSpellsWithSource(ArcaneChaos, "EiSC", markSource));
}
}
// Add Death in the Reik Companion spells with marker if selected
if (document.getElementById("deathInTheReik").checked) {
Object.keys(LoreSpellsDeathInTheReikCompanion).forEach(lore => {
if (!LoreSpells[lore]) LoreSpells[lore] = [];
LoreSpells[lore] = LoreSpells[lore].concat(markSpellsWithSource(LoreSpellsDeathInTheReikCompanion[lore], "DitR", markSource));
});
}
// Add Power Behind the Throne Companion spells with marker if selected
if (document.getElementById("powerBehindThrone").checked) {
Object.keys(LoreSpellsPowerBehindTheThroneCompanion).forEach(lore => {
if (!LoreSpells[lore]) LoreSpells[lore] = [];
LoreSpells[lore] = LoreSpells[lore].concat(markSpellsWithSource(LoreSpellsPowerBehindTheThroneCompanion[lore], "PBtT", markSource));
});
}
// Add Empire in Ruins Companion spells with marker if selected
if (document.getElementById("empireInRuins").checked) {
Object.keys(LoreSpellsEmpireInRuinsCompanion).forEach(lore => {
if (!LoreSpells[lore]) LoreSpells[lore] = [];
LoreSpells[lore] = LoreSpells[lore].concat(markSpellsWithSource(LoreSpellsEmpireInRuinsCompanion[lore], "EiR", markSource));
});
}
// Add Archives of Empire 3 spells with marker if selected
if (document.getElementById("archivesOfEmpire3").checked) {
Object.keys(LoreSpellsArchivesOfEmpire3).forEach(lore => {
if (!LoreSpells[lore]) LoreSpells[lore] = [];
LoreSpells[lore] = markSpellsWithSource(LoreSpellsArchivesOfEmpire3[lore], "AotE3", markSource);
});
}
//Add Sea of Claws spells with marker if selected
if (document.getElementById("seaOfClaws").checked) {
Object.keys(LoreSpellsSeaOfClaws).forEach(lore => {
if (!LoreSpells[lore]) LoreSpells[lore] = [];
LoreSpells[lore] = LoreSpells[lore].concat(markSpellsWithSource(LoreSpellsSeaOfClaws[lore], "SoC", markSource));
});
}
}
// Function to generate a random grimoire
function generateGrimoire() {
// Get the chosen Lore
let loreNames = Object.keys(LoreSpells);
let chosenLore = document.getElementById("loreSelect").value;
if (chosenLore === "Random") {
let loreNames = Object.keys(LoreSpellsCore);
chosenLore = loreNames[randomBetween(0, loreNames.length - 1)];
}
console.log("Chosen Lore: " + chosenLore);
// Call mergeSpells to update LoreSpells based on user selections
mergeSpells(chosenLore);
// Determine the number of spells (4-8) with weighted probabilities
let spellCount = getSpellCount();
// Get the spells: mix between Arcane and the specific Lore spells
let arcaneSpells = getRandomSpells(AllArcane, Math.max(randomBetween(1, spellCount - 1), spellCount - LoreSpells[chosenLore].length)); // At least one Arcane spell
let loreSpells = getRandomSpells(LoreSpells[chosenLore], spellCount - arcaneSpells.length);
let allSpells = arcaneSpells.concat(loreSpells);
// Create the grimoire text
let grimoireText = "Grimoire of " + chosenLore + ":<br>";
allSpells.forEach(spell => {
grimoireText += `- ${spell[0]} (CN: ${spell[1]})<br>`;
});
// Add random decoration
grimoireText += "<br>Appearance: " + aanmanagement(removedoublespaces(generateBookAppearance(chosenLore)));
// Display the generated grimoire
document.getElementById("grimoire").innerHTML = grimoireText;
}
// Function to get spell count with weighted probabilities
function getSpellCount() {
let random = Math.random();
if (random < 0.30) return 4;
if (random < 0.55) return 5;
if (random < 0.75) return 6;
if (random < 0.90) return 7;
return 8;
}
// Function to generate a random book appearance
function generateBookAppearance(chosenLore) {
let template = getRandomElement(BOOK);
return replacePlaceholders(template, chosenLore);
}
// Helper function to get a random element from an array
function getRandomElement(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
function replacePlaceholders(originalString, chosenLore) {
let notdone = true;
while (notdone) {
notdone = false;
// Handle LOREXXXXX placeholders first
if (originalString.includes("$LORECOLOUR")) {
const replacement = getRandomElement(LORECOLOUR[chosenLore][0]);
originalString = originalString.replace("$LORECOLOUR", replacement);
notdone = true;
}
if (originalString.includes("$LOREMATERIAL")) {
const replacement = getRandomElement(LOREMATERIAL[chosenLore][0]);
originalString = originalString.replace("$LOREMATERIAL", replacement);
notdone = true;
}
if (originalString.includes("$LOREDECORATION")) {
const replacement = getRandomElement(LOREDECORATION[chosenLore][0]);
originalString = originalString.replace("$LOREDECORATION", replacement);
notdone = true;
}
// Replace other placeholders using ALLSTRINGS
for (let i = 0; i < ALLSTRINGS.length; i++) {
let lookingFor = ALLSTRINGS[i][0];
let possibleValues = ALLSTRINGS[i][1];
if (originalString.includes(lookingFor)) {
const replacement = getRandomElement(possibleValues);
originalString = originalString.replace(lookingFor, replacement);
notdone = true;
}
}
}
return originalString;
}
// Function to generate a random book appearance
function generateBookAppearance(chosenLore) {
let template = BOOK[randomBetween(0, BOOK.length - 1)];
return replacePlaceholders(template, chosenLore);
}
</script>
</head>
<body>
<h1>Random Magic Grimoire Generator</h1>
<label for="loreSelect">Select Lore:</label>
<select id="loreSelect">
<option value="Random" selected="selected">Random</option>
<option value="Lore of Beasts">Lore of Beasts</option>
<option value="Lore of Death">Lore of Death</option>
<option value="Lore of Fire">Lore of Fire</option>
<option value="Lore of Heavens">Lore of Heavens</option>
<option value="Lore of Metal">Lore of Metal</option>
<option value="Lore of Life">Lore of Life</option>
<option value="Lore of Light">Lore of Light</option>
<option value="Lore of Shadows">Lore of Shadows</option>
<option value="Lore of Hedgecraft">Lore of Hedgecraft</option>
<option value="Lore of Witchcraft">Lore of Witchcraft</option>
<option value="Lore of Daemonology">Lore of Daemonology</option>
<option value="Lore of Necromancy">Lore of Necromancy</option>
<option value="Lore of Nurgle">Lore of Nurgle</option>
<option value="Lore of Slaanesh">Lore of Slaanesh</option>
<option value="Lore of Tzeentch">Lore of Tzeentch</option>
</select>
<div>
<label><input type="checkbox" id="markSource" value="Mark Source"> Mark spells from expansions</label><br>
<label><input type="checkbox" id="windsOfMagic" value="Winds Of Magic"> Include <a href="https://www.drivethrurpg.com/es/product/388109/warhammer-fantasy-roleplay-winds-of-magic?affiliate_id=91369">"Winds Of Magic"</a> Expansion (Replace Colour Lore Spells)</label><br>
<label><input type="checkbox" id="bloodAndBramble" value="Blood and Bramble"> Include <a href="https://www.drivethrurpg.com/es/product/305317/warhammer-fantasy-role-play-blood-and-bramble?affiliate_id=91369">"Blood and Bramble"</a> Expansion</label><br>
<label><input type="checkbox" id="sullasaraSpells" value="Sullasara’s Spells"> Include <a href="https://www.drivethrurpg.com/es/product/354584/warhammer-fantasy-role-play-sullasara-s-spells-of-unrivalled-utility?affiliate_id=91369">"Sullasara’s Spells of Unrivaled Utility"</a> Expansion</label><br>
<label><input type="checkbox" id="enemyInShadows" value="Enemy in Shadows"> Include <a href="https://www.drivethrurpg.com/es/product/293881/warhammer-fantasy-roleplay-enemy-in-shadows-companion?affiliate_id=91369">"Enemy in Shadows Companion"</a> Expansion</label><br>
<label><input type="checkbox" id="deathInTheReik" value="Death in the Reik"> Include <a href="https://www.drivethrurpg.com/es/product/303922/warhammer-fantasy-role-play-death-on-the-reik-companion?affiliate_id=91369">"Death in the Reik Companion"</a> Expansion</label><br>
<label><input type="checkbox" id="powerBehindThrone" value="Power Behind the Throne"> Include <a href="https://www.drivethrurpg.com/es/product/303926/warhammer-fantasy-role-play-power-behind-the-throne-companion?affiliate_id=91369">"Power Behind the Throne Companion"</a> Expansion</label><br>
<label><input type="checkbox" id="empireInRuins" value="Empire in Ruins"> Include <a href="https://www.drivethrurpg.com/es/product/303942/warhammer-fantasy-role-play-empire-in-ruins-companion?affiliate_id=91369">"Empire in Ruins Companion"</a> Expansion</label><br>
<label><input type="checkbox" id="archivesOfEmpire3" value="Empire in Ruins"> Include <a href="https://www.drivethrurpg.com/es/product/388125/warhammer-fantasy-roleplay-archives-of-the-empire-3?affiliate_id=91369">"Archives of the Empire 3"</a> Expansion (Replace Hedgecraft Spells)</label><br>
<label><input type="checkbox" id="seaOfClaws" value="Sea of Claws"> Include <a href="https://www.drivethrurpg.com/es/product/388101/warhammer-fantasy-roleplay-sea-of-claws?affiliate_id=91369">"Sea of Claws"</a> Expansion</label>
</div>
<button type="button" onclick="generateGrimoire()">Generate Grimoire</button>
<p id="grimoire"></p> <!-- 'pre' to preserve formatting of the output -->
<p>For your book titles, mundane or magical, you can check my <a href="https://pacomiscelaneousstuff.blogspot.com/2020/02/wfrp4-random-book-generator.html">Book Generator</a>.</p>
<p id="Acknowledgements">Code: Francisco Muñoz 2024.
<br>Based on the Grimoires entry on page 238, and the spell lists of the <a href="https://www.drivethrurpg.com/product/248284/Warhammer-Fantasy-Roleplay-Fourth-Edition-Rulebook?affiliate_id=91369">Warhammer Fantasy Roleplay Fourth Edition Rulebook</a>.
<br>Based on the spell lists of <a href="https://www.drivethrurpg.com/es/product/388109/warhammer-fantasy-roleplay-winds-of-magic?affiliate_id=91369">Winds Of Magic</a>.
<br>Based on the spell lists of <a href="https://www.drivethrurpg.com/es/product/354584/warhammer-fantasy-role-play-sullasara-s-spells-of-unrivalled-utility?affiliate_id=91369">Sullasara’s Spells of Unrivaled Utility</a>.
<br>Based on the spell lists of <a href="https://www.drivethrurpg.com/es/product/305317/warhammer-fantasy-role-play-blood-and-bramble?affiliate_id=91369">Blood and Bramble</a>.
<br>Based on the spell lists of <a href="https://www.drivethrurpg.com/es/product/293881/warhammer-fantasy-roleplay-enemy-in-shadows-companion?affiliate_id=91369">Enemy in Shadows Companion</a>.
<br>Based on the spell lists of <a href="https://www.drivethrurpg.com/es/product/303922/warhammer-fantasy-role-play-death-on-the-reik-companion?affiliate_id=91369">Death in the Reik Companion</a>.
<br>Based on the spell lists of <a href="https://www.drivethrurpg.com/es/product/303926/warhammer-fantasy-role-play-power-behind-the-throne-companion?affiliate_id=91369">Power Behind the Throne Companion</a>.
<br>Based on the spell lists of <a href="https://www.drivethrurpg.com/es/product/303942/warhammer-fantasy-role-play-empire-in-ruins-companion?affiliate_id=91369">Empire in Ruins Companion</a>
<br>Based on the spell lists of <a href="https://www.drivethrurpg.com/es/product/388125/warhammer-fantasy-roleplay-archives-of-the-empire-3?affiliate_id=91369">Archives of the Empire 3</a>
<br>Based on the spell lists of <a href="https://www.drivethrurpg.com/es/product/388101/warhammer-fantasy-roleplay-sea-of-claws?affiliate_id=91369">Sea of Claws</a>
<br>Inspiration: <a href="http://www.windsofchaos.com/wp-content/uploads/encroachment/html/generator-random-treasure-01.html">Encroatchment of Chaos, Treasure Generator by Dave Graffam</a>.
<br>Inspiration: <a href="http://orteil.dashnet.org/randomgen/?gen=https://pastebin.com/raw/JcxC8pMx">WFRP 4e Equipment Generator</a>.
<br>Inspiration: <a href="https://ratujmywfrp2pl.files.wordpress.com/2010/01/treasure-tables.pdf">Dan White's WFRP RANDOM TREASURE GENERATION</a>.
<br>Inspiration: <a href="http://www.goatmansgoblet.com/2020/08/warhammer-fantasy-apothecary.html">Goatman's Goblet: WFRP The Apothecary (Trappings/Randomizers)</a>.
<br>Game: Games Workshop and Cubicle 7
<br>Other random generators: <a href="https://randroll.com/archive/warhammer-fantasy-roleplay-generators-guide/">https://randroll.com/archive/warhammer-fantasy-roleplay-generators-guide/</a></p>
</body>
</html>