amar-rpg 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +675 -0
- data/README.md +155 -0
- data/amar-tui.rb +8195 -0
- data/cli_enc_output.rb +87 -0
- data/cli_enc_output_new.rb +433 -0
- data/cli_enc_output_new_3tier.rb +198 -0
- data/cli_enc_output_new_compact.rb +238 -0
- data/cli_name_gen.rb +21 -0
- data/cli_npc_output.rb +279 -0
- data/cli_npc_output_new.rb +700 -0
- data/cli_town_output.rb +39 -0
- data/cli_weather_output.rb +36 -0
- data/includes/class_enc.rb +341 -0
- data/includes/class_enc_new.rb +512 -0
- data/includes/class_monster_new.rb +551 -0
- data/includes/class_npc.rb +1378 -0
- data/includes/class_npc_new.rb +1187 -0
- data/includes/class_npc_new.rb.backup +706 -0
- data/includes/class_npc_new_skills.rb +153 -0
- data/includes/class_town.rb +237 -0
- data/includes/d6s.rb +40 -0
- data/includes/equipment_tables.rb +120 -0
- data/includes/functions.rb +67 -0
- data/includes/includes.rb +30 -0
- data/includes/randomizer.rb +15 -0
- data/includes/spell_catalog.rb +441 -0
- data/includes/tables/armour.rb +13 -0
- data/includes/tables/chartype.rb +4412 -0
- data/includes/tables/chartype_new.rb +765 -0
- data/includes/tables/chartype_new_full.rb +2713 -0
- data/includes/tables/enc_specific.rb +168 -0
- data/includes/tables/enc_type.rb +17 -0
- data/includes/tables/encounters.rb +99 -0
- data/includes/tables/magick.rb +169 -0
- data/includes/tables/melee.rb +36 -0
- data/includes/tables/missile.rb +17 -0
- data/includes/tables/monster_stats_new.rb +264 -0
- data/includes/tables/month.rb +18 -0
- data/includes/tables/names.rb +21 -0
- data/includes/tables/personality.rb +12 -0
- data/includes/tables/race_templates.rb +318 -0
- data/includes/tables/religions.rb +266 -0
- data/includes/tables/spells_new.rb +496 -0
- data/includes/tables/tier_system.rb +104 -0
- data/includes/tables/town.rb +71 -0
- data/includes/tables/weather.rb +41 -0
- data/includes/town_relations.rb +127 -0
- data/includes/weather.rb +108 -0
- data/includes/weather2latex.rb +114 -0
- data/lib/rcurses.rb +33 -0
- metadata +157 -0
@@ -0,0 +1,496 @@
|
|
1
|
+
# New Spell System for Amar RPG
|
2
|
+
# Spells are owned "cards" that can be transferred
|
3
|
+
|
4
|
+
$SpellDatabase = {
|
5
|
+
# Fire Domain Spells
|
6
|
+
"Spark" => {
|
7
|
+
"domain" => "Fire",
|
8
|
+
"encumbrance" => 1,
|
9
|
+
"cooldown" => 1,
|
10
|
+
"casting_time" => "1 round",
|
11
|
+
"active_passive" => "Active",
|
12
|
+
"restrictions" => "None",
|
13
|
+
"dr" => [5],
|
14
|
+
"cost" => {"Mental Fortitude" => 1},
|
15
|
+
"distance" => "10m",
|
16
|
+
"duration" => "Instant",
|
17
|
+
"aoe" => "Single target",
|
18
|
+
"effects" => "1d6 fire damage",
|
19
|
+
"transfer_req" => {"receiving" => "Fire Attunement 1", "giving" => "Ritual 1 day"}
|
20
|
+
},
|
21
|
+
|
22
|
+
"Fireball" => {
|
23
|
+
"domain" => "Fire",
|
24
|
+
"encumbrance" => 5,
|
25
|
+
"cooldown" => 6,
|
26
|
+
"casting_time" => "2 rounds",
|
27
|
+
"active_passive" => "Active",
|
28
|
+
"restrictions" => "None",
|
29
|
+
"dr" => [10],
|
30
|
+
"cost" => {"Mental Fortitude" => 3},
|
31
|
+
"distance" => "50m",
|
32
|
+
"duration" => "Instant",
|
33
|
+
"aoe" => "3m radius",
|
34
|
+
"effects" => "3d6 fire damage to all in area",
|
35
|
+
"transfer_req" => {"receiving" => "Fire Attunement 3", "giving" => "Ritual 3 days"}
|
36
|
+
},
|
37
|
+
|
38
|
+
"Wall of Fire" => {
|
39
|
+
"domain" => "Fire",
|
40
|
+
"encumbrance" => 8,
|
41
|
+
"cooldown" => 24,
|
42
|
+
"casting_time" => "3 rounds",
|
43
|
+
"active_passive" => "Active",
|
44
|
+
"restrictions" => "None",
|
45
|
+
"dr" => [15],
|
46
|
+
"cost" => {"Mental Fortitude" => 5},
|
47
|
+
"distance" => "30m",
|
48
|
+
"duration" => "10 minutes",
|
49
|
+
"aoe" => "10m x 3m wall",
|
50
|
+
"effects" => "2d6 damage to those passing through",
|
51
|
+
"transfer_req" => {"receiving" => "Fire Attunement 5", "giving" => "Ritual 1 week"}
|
52
|
+
},
|
53
|
+
|
54
|
+
# Water Domain Spells
|
55
|
+
"Water Breathing" => {
|
56
|
+
"domain" => "Water",
|
57
|
+
"encumbrance" => 3,
|
58
|
+
"cooldown" => 2,
|
59
|
+
"casting_time" => "1 round",
|
60
|
+
"active_passive" => "Active",
|
61
|
+
"restrictions" => "Must be near water",
|
62
|
+
"dr" => [8],
|
63
|
+
"cost" => {"Mental Fortitude" => 2},
|
64
|
+
"distance" => "Touch",
|
65
|
+
"duration" => "1 hour",
|
66
|
+
"aoe" => "Single target",
|
67
|
+
"effects" => "Target can breathe underwater",
|
68
|
+
"transfer_req" => {"receiving" => "Water Attunement 2", "giving" => "Ritual 2 days"}
|
69
|
+
},
|
70
|
+
|
71
|
+
"Ice Bolt" => {
|
72
|
+
"domain" => "Water",
|
73
|
+
"encumbrance" => 4,
|
74
|
+
"cooldown" => 3,
|
75
|
+
"casting_time" => "1 round",
|
76
|
+
"active_passive" => "Active",
|
77
|
+
"restrictions" => "None",
|
78
|
+
"dr" => [9],
|
79
|
+
"cost" => {"Mental Fortitude" => 2},
|
80
|
+
"distance" => "30m",
|
81
|
+
"duration" => "Instant",
|
82
|
+
"aoe" => "Single target",
|
83
|
+
"effects" => "2d6 cold damage + slow for 1 round",
|
84
|
+
"transfer_req" => {"receiving" => "Water Attunement 3", "giving" => "Ritual 2 days"}
|
85
|
+
},
|
86
|
+
|
87
|
+
"Fog Cloud" => {
|
88
|
+
"domain" => "Water",
|
89
|
+
"encumbrance" => 4,
|
90
|
+
"cooldown" => 4,
|
91
|
+
"casting_time" => "2 rounds",
|
92
|
+
"active_passive" => "Active",
|
93
|
+
"restrictions" => "None",
|
94
|
+
"dr" => [10],
|
95
|
+
"cost" => {"Mental Fortitude" => 3},
|
96
|
+
"distance" => "50m",
|
97
|
+
"duration" => "10 min",
|
98
|
+
"aoe" => "20m radius",
|
99
|
+
"effects" => "Dense fog, visibility 2m",
|
100
|
+
"transfer_req" => {"receiving" => "Water Attunement 3", "giving" => "Ritual 3 days"}
|
101
|
+
},
|
102
|
+
|
103
|
+
"Water Walk" => {
|
104
|
+
"domain" => "Water",
|
105
|
+
"encumbrance" => 2,
|
106
|
+
"cooldown" => 2,
|
107
|
+
"casting_time" => "1 round",
|
108
|
+
"active_passive" => "Active",
|
109
|
+
"restrictions" => "None",
|
110
|
+
"dr" => [7],
|
111
|
+
"cost" => {"Mental Fortitude" => 2},
|
112
|
+
"distance" => "Touch",
|
113
|
+
"duration" => "30 min",
|
114
|
+
"aoe" => "Single target",
|
115
|
+
"effects" => "Walk on water surface",
|
116
|
+
"transfer_req" => {"receiving" => "Water Attunement 2", "giving" => "Ritual 2 days"}
|
117
|
+
},
|
118
|
+
|
119
|
+
"Purify Water" => {
|
120
|
+
"domain" => "Water",
|
121
|
+
"encumbrance" => 1,
|
122
|
+
"cooldown" => 1,
|
123
|
+
"casting_time" => "3 rounds",
|
124
|
+
"active_passive" => "Active",
|
125
|
+
"restrictions" => "Water only",
|
126
|
+
"dr" => [5],
|
127
|
+
"cost" => {"Mental Fortitude" => 1},
|
128
|
+
"distance" => "Touch",
|
129
|
+
"duration" => "Permanent",
|
130
|
+
"aoe" => "10 liters",
|
131
|
+
"effects" => "Removes toxins",
|
132
|
+
"transfer_req" => {"receiving" => "Water Attunement 1", "giving" => "Ritual 1 day"}
|
133
|
+
},
|
134
|
+
|
135
|
+
"Control Water" => {
|
136
|
+
"domain" => "Water",
|
137
|
+
"encumbrance" => 8,
|
138
|
+
"cooldown" => 12,
|
139
|
+
"casting_time" => "5 rounds",
|
140
|
+
"active_passive" => "Active",
|
141
|
+
"restrictions" => "Natural water",
|
142
|
+
"dr" => [14],
|
143
|
+
"cost" => {"Mental Fortitude" => 5},
|
144
|
+
"distance" => "100m",
|
145
|
+
"duration" => "Conc",
|
146
|
+
"aoe" => "50m radius",
|
147
|
+
"effects" => "Raise/lower 3m",
|
148
|
+
"transfer_req" => {"receiving" => "Water Attunement 5", "giving" => "Ritual 1 week"}
|
149
|
+
},
|
150
|
+
|
151
|
+
"Frost Shield" => {
|
152
|
+
"domain" => "Water",
|
153
|
+
"encumbrance" => 5,
|
154
|
+
"cooldown" => 6,
|
155
|
+
"casting_time" => "1 round",
|
156
|
+
"active_passive" => "Active",
|
157
|
+
"restrictions" => "None",
|
158
|
+
"dr" => [11],
|
159
|
+
"cost" => {"Mental Fortitude" => 3},
|
160
|
+
"distance" => "Self",
|
161
|
+
"duration" => "5 min",
|
162
|
+
"aoe" => "Self",
|
163
|
+
"effects" => "+3 AP vs physical",
|
164
|
+
"transfer_req" => {"receiving" => "Water Attunement 3", "giving" => "Ritual 4 days"}
|
165
|
+
},
|
166
|
+
|
167
|
+
# Air Domain Spells
|
168
|
+
"Levitate" => {
|
169
|
+
"domain" => "Air",
|
170
|
+
"encumbrance" => 4,
|
171
|
+
"cooldown" => 4,
|
172
|
+
"casting_time" => "2 rounds",
|
173
|
+
"active_passive" => "Active",
|
174
|
+
"restrictions" => "None",
|
175
|
+
"dr" => [10],
|
176
|
+
"cost" => {"Mental Fortitude" => 3},
|
177
|
+
"distance" => "Self",
|
178
|
+
"duration" => "10 minutes",
|
179
|
+
"aoe" => "Self",
|
180
|
+
"effects" => "Float up to 10m high, move at walking speed",
|
181
|
+
"transfer_req" => {"receiving" => "Air Attunement 3", "giving" => "Ritual 3 days"}
|
182
|
+
},
|
183
|
+
|
184
|
+
"Lightning Bolt" => {
|
185
|
+
"domain" => "Air",
|
186
|
+
"encumbrance" => 6,
|
187
|
+
"cooldown" => 8,
|
188
|
+
"casting_time" => "1 round",
|
189
|
+
"active_passive" => "Active",
|
190
|
+
"restrictions" => "Cannot use in metal armor",
|
191
|
+
"dr" => [12],
|
192
|
+
"cost" => {"Mental Fortitude" => 4},
|
193
|
+
"distance" => "100m line",
|
194
|
+
"duration" => "Instant",
|
195
|
+
"aoe" => "Line 100m x 1m",
|
196
|
+
"effects" => "4d6 electrical damage to all in line",
|
197
|
+
"transfer_req" => {"receiving" => "Air Attunement 4", "giving" => "Ritual 4 days"}
|
198
|
+
},
|
199
|
+
|
200
|
+
# Earth Domain Spells
|
201
|
+
"Stone Skin" => {
|
202
|
+
"domain" => "Earth",
|
203
|
+
"encumbrance" => 5,
|
204
|
+
"cooldown" => 12,
|
205
|
+
"casting_time" => "3 rounds",
|
206
|
+
"active_passive" => "Active",
|
207
|
+
"restrictions" => "Must be on ground",
|
208
|
+
"dr" => [11],
|
209
|
+
"cost" => {"Mental Fortitude" => 3},
|
210
|
+
"distance" => "Touch",
|
211
|
+
"duration" => "1 hour",
|
212
|
+
"aoe" => "Single target",
|
213
|
+
"effects" => "+3 armor points",
|
214
|
+
"transfer_req" => {"receiving" => "Earth Attunement 3", "giving" => "Ritual 3 days"}
|
215
|
+
},
|
216
|
+
|
217
|
+
# Life Domain Spells
|
218
|
+
"Heal Wounds" => {
|
219
|
+
"domain" => "Life",
|
220
|
+
"encumbrance" => 3,
|
221
|
+
"cooldown" => 2,
|
222
|
+
"casting_time" => "2 rounds",
|
223
|
+
"active_passive" => "Active",
|
224
|
+
"restrictions" => "None",
|
225
|
+
"dr" => [8],
|
226
|
+
"cost" => {"Mental Fortitude" => 2},
|
227
|
+
"distance" => "Touch",
|
228
|
+
"duration" => "Instant",
|
229
|
+
"aoe" => "Single target",
|
230
|
+
"effects" => "Restore 2d6 BP",
|
231
|
+
"transfer_req" => {"receiving" => "Life Attunement 2", "giving" => "Ritual 2 days"}
|
232
|
+
},
|
233
|
+
|
234
|
+
"Regeneration" => {
|
235
|
+
"domain" => "Life",
|
236
|
+
"encumbrance" => 7,
|
237
|
+
"cooldown" => 24,
|
238
|
+
"casting_time" => "5 rounds",
|
239
|
+
"active_passive" => "Active",
|
240
|
+
"restrictions" => "Target must be alive",
|
241
|
+
"dr" => [15],
|
242
|
+
"cost" => {"Mental Fortitude" => 5},
|
243
|
+
"distance" => "Touch",
|
244
|
+
"duration" => "1 day",
|
245
|
+
"aoe" => "Single target",
|
246
|
+
"effects" => "Restore 1 BP per hour",
|
247
|
+
"transfer_req" => {"receiving" => "Life Attunement 5", "giving" => "Ritual 1 week"}
|
248
|
+
},
|
249
|
+
|
250
|
+
# Mind Domain Spells
|
251
|
+
"Detect Thoughts" => {
|
252
|
+
"domain" => "Mind",
|
253
|
+
"encumbrance" => 4,
|
254
|
+
"cooldown" => 4,
|
255
|
+
"casting_time" => "1 round",
|
256
|
+
"active_passive" => "Active",
|
257
|
+
"restrictions" => "Target must be intelligent",
|
258
|
+
"dr" => [10],
|
259
|
+
"cost" => {"Mental Fortitude" => 3},
|
260
|
+
"distance" => "10m",
|
261
|
+
"duration" => "Concentration",
|
262
|
+
"aoe" => "Single target",
|
263
|
+
"effects" => "Read surface thoughts",
|
264
|
+
"transfer_req" => {"receiving" => "Mind Attunement 3", "giving" => "Ritual 3 days"}
|
265
|
+
},
|
266
|
+
|
267
|
+
"Illusion" => {
|
268
|
+
"domain" => "Mind",
|
269
|
+
"encumbrance" => 5,
|
270
|
+
"cooldown" => 6,
|
271
|
+
"casting_time" => "2 rounds",
|
272
|
+
"active_passive" => "Active",
|
273
|
+
"restrictions" => "None",
|
274
|
+
"dr" => [11],
|
275
|
+
"cost" => {"Mental Fortitude" => 3},
|
276
|
+
"distance" => "30m",
|
277
|
+
"duration" => "10 minutes",
|
278
|
+
"aoe" => "3m x 3m area",
|
279
|
+
"effects" => "Create visual and auditory illusion",
|
280
|
+
"transfer_req" => {"receiving" => "Mind Attunement 3", "giving" => "Ritual 3 days"}
|
281
|
+
},
|
282
|
+
|
283
|
+
# Death Domain Spells
|
284
|
+
"Drain Life" => {
|
285
|
+
"domain" => "Death",
|
286
|
+
"encumbrance" => 6,
|
287
|
+
"cooldown" => 8,
|
288
|
+
"casting_time" => "2 rounds",
|
289
|
+
"active_passive" => "Active",
|
290
|
+
"restrictions" => "Target must be living",
|
291
|
+
"dr" => [12],
|
292
|
+
"cost" => {"Mental Fortitude" => 4},
|
293
|
+
"distance" => "Touch",
|
294
|
+
"duration" => "Instant",
|
295
|
+
"aoe" => "Single target",
|
296
|
+
"effects" => "Deal 2d6 damage, heal self for half",
|
297
|
+
"transfer_req" => {"receiving" => "Death Attunement 4", "giving" => "Ritual 4 days"}
|
298
|
+
},
|
299
|
+
|
300
|
+
"Animate Dead" => {
|
301
|
+
"domain" => "Death",
|
302
|
+
"encumbrance" => 10,
|
303
|
+
"cooldown" => 48,
|
304
|
+
"casting_time" => "10 rounds",
|
305
|
+
"active_passive" => "Active",
|
306
|
+
"restrictions" => "Requires corpse",
|
307
|
+
"dr" => [18],
|
308
|
+
"cost" => {"Mental Fortitude" => 8, "Corpse" => 1},
|
309
|
+
"distance" => "Touch",
|
310
|
+
"duration" => "Until destroyed",
|
311
|
+
"aoe" => "Single corpse",
|
312
|
+
"effects" => "Raise undead servant",
|
313
|
+
"transfer_req" => {"receiving" => "Death Attunement 6", "giving" => "Ritual 2 weeks"}
|
314
|
+
},
|
315
|
+
|
316
|
+
# Body Domain Spells
|
317
|
+
"Enhance Strength" => {
|
318
|
+
"domain" => "Body",
|
319
|
+
"encumbrance" => 3,
|
320
|
+
"cooldown" => 4,
|
321
|
+
"casting_time" => "1 round",
|
322
|
+
"active_passive" => "Active",
|
323
|
+
"restrictions" => "None",
|
324
|
+
"dr" => [8],
|
325
|
+
"cost" => {"Mental Fortitude" => 2},
|
326
|
+
"distance" => "Touch",
|
327
|
+
"duration" => "10 minutes",
|
328
|
+
"aoe" => "Single target",
|
329
|
+
"effects" => "+3 to Strength attribute",
|
330
|
+
"transfer_req" => {"receiving" => "Body Attunement 2", "giving" => "Ritual 2 days"}
|
331
|
+
},
|
332
|
+
|
333
|
+
# Self Domain Spells
|
334
|
+
"Mirror Image" => {
|
335
|
+
"domain" => "Self",
|
336
|
+
"encumbrance" => 5,
|
337
|
+
"cooldown" => 6,
|
338
|
+
"casting_time" => "1 round",
|
339
|
+
"active_passive" => "Active",
|
340
|
+
"restrictions" => "None",
|
341
|
+
"dr" => [10],
|
342
|
+
"cost" => {"Mental Fortitude" => 3},
|
343
|
+
"distance" => "Self",
|
344
|
+
"duration" => "5 minutes",
|
345
|
+
"aoe" => "Self",
|
346
|
+
"effects" => "Create 3 illusory duplicates",
|
347
|
+
"transfer_req" => {"receiving" => "Self Attunement 3", "giving" => "Ritual 3 days"}
|
348
|
+
},
|
349
|
+
|
350
|
+
"Teleport" => {
|
351
|
+
"domain" => "Self",
|
352
|
+
"encumbrance" => 8,
|
353
|
+
"cooldown" => 24,
|
354
|
+
"casting_time" => "5 rounds",
|
355
|
+
"active_passive" => "Active",
|
356
|
+
"restrictions" => "Must know destination",
|
357
|
+
"dr" => [16],
|
358
|
+
"cost" => {"Mental Fortitude" => 6},
|
359
|
+
"distance" => "1km",
|
360
|
+
"duration" => "Instant",
|
361
|
+
"aoe" => "Self + carried items",
|
362
|
+
"effects" => "Instantly transport to known location",
|
363
|
+
"transfer_req" => {"receiving" => "Self Attunement 5", "giving" => "Ritual 1 week"}
|
364
|
+
}
|
365
|
+
}
|
366
|
+
|
367
|
+
# Spell generation function for NPCs
|
368
|
+
def generate_spell_cards(npc_type, level, casting_level)
|
369
|
+
spells = []
|
370
|
+
|
371
|
+
# Determine domains based on character type
|
372
|
+
domains = case npc_type
|
373
|
+
when "Mage"
|
374
|
+
["Fire", "Air", "Mind", "Self"]
|
375
|
+
when "Priest"
|
376
|
+
["Life", "Body", "Mind"]
|
377
|
+
when "Ranger"
|
378
|
+
["Earth", "Life", "Body"]
|
379
|
+
when "Noble"
|
380
|
+
["Mind", "Self"]
|
381
|
+
when /Wizard \((.*?)\)/
|
382
|
+
# Extract domain from wizard type (e.g., "Wizard (water)" -> "Water")
|
383
|
+
wizard_type = $1
|
384
|
+
wizard_domain = case wizard_type
|
385
|
+
when "prot.", "protection"
|
386
|
+
"Self" # Protection wizards focus on Self domain
|
387
|
+
else
|
388
|
+
wizard_type.capitalize
|
389
|
+
end
|
390
|
+
[wizard_domain, wizard_domain] # Primary domain focus
|
391
|
+
else
|
392
|
+
["Fire", "Water", "Air", "Earth"].sample(2)
|
393
|
+
end
|
394
|
+
|
395
|
+
# Calculate number of spells based on level and casting ability
|
396
|
+
# Higher level casters should have accumulated many spells over their career
|
397
|
+
base_spells = case level
|
398
|
+
when 1..2 then rand(1..2)
|
399
|
+
when 3..4 then rand(2..4)
|
400
|
+
when 5 then rand(4..6)
|
401
|
+
when 6 then rand(6..10)
|
402
|
+
else rand(8..12)
|
403
|
+
end
|
404
|
+
|
405
|
+
# Add bonus spells for high casting level
|
406
|
+
casting_bonus = (casting_level / 2).to_i
|
407
|
+
spell_count = base_spells + casting_bonus
|
408
|
+
spell_count = 1 if spell_count < 1
|
409
|
+
spell_count = 15 if spell_count > 15 # Cap at 15 to avoid overwhelming the sheet
|
410
|
+
|
411
|
+
# Generate spell cards
|
412
|
+
selected_spells = []
|
413
|
+
attempts = 0
|
414
|
+
|
415
|
+
while selected_spells.length < spell_count && attempts < 20
|
416
|
+
attempts += 1
|
417
|
+
domain = domains.sample
|
418
|
+
domain_spells = $SpellDatabase.select { |_, v| v["domain"] == domain }
|
419
|
+
|
420
|
+
if domain_spells.any?
|
421
|
+
available_spells = domain_spells.keys - selected_spells
|
422
|
+
if available_spells.any?
|
423
|
+
spell_name = available_spells.sample
|
424
|
+
selected_spells << spell_name
|
425
|
+
|
426
|
+
spell_data = $SpellDatabase[spell_name].dup
|
427
|
+
spell_data["name"] = spell_name
|
428
|
+
|
429
|
+
# Add ownership tracking
|
430
|
+
spell_data["owner_id"] = rand(100000)
|
431
|
+
spell_data["transfer_history"] = []
|
432
|
+
|
433
|
+
spells << spell_data
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
spells
|
439
|
+
end
|
440
|
+
|
441
|
+
# Spell transfer mechanics
|
442
|
+
class SpellTransfer
|
443
|
+
def self.can_transfer?(spell, giver, receiver)
|
444
|
+
# Check giving requirements
|
445
|
+
return false unless meets_giving_requirements?(spell, giver)
|
446
|
+
|
447
|
+
# Check receiving requirements
|
448
|
+
return false unless meets_receiving_requirements?(spell, receiver)
|
449
|
+
|
450
|
+
true
|
451
|
+
end
|
452
|
+
|
453
|
+
def self.transfer(spell, giver, receiver)
|
454
|
+
return false unless can_transfer?(spell, giver, receiver)
|
455
|
+
|
456
|
+
# Remove from giver
|
457
|
+
giver.spells.delete(spell)
|
458
|
+
|
459
|
+
# Add to receiver
|
460
|
+
spell["transfer_history"] << {
|
461
|
+
"from" => giver.name,
|
462
|
+
"to" => receiver.name,
|
463
|
+
"date" => Time.now
|
464
|
+
}
|
465
|
+
receiver.spells << spell
|
466
|
+
|
467
|
+
true
|
468
|
+
end
|
469
|
+
|
470
|
+
private
|
471
|
+
|
472
|
+
def self.meets_giving_requirements?(spell, giver)
|
473
|
+
# Check if giver owns the spell
|
474
|
+
return false unless giver.spells.include?(spell)
|
475
|
+
|
476
|
+
# Check ritual requirements (simplified for now)
|
477
|
+
true
|
478
|
+
end
|
479
|
+
|
480
|
+
def self.meets_receiving_requirements?(spell, receiver)
|
481
|
+
# Check attunement requirements
|
482
|
+
req = spell["transfer_req"]["receiving"]
|
483
|
+
|
484
|
+
if req.include?("Attunement")
|
485
|
+
parts = req.split(" ")
|
486
|
+
domain = parts[0]
|
487
|
+
required_level = parts[-1].to_i
|
488
|
+
|
489
|
+
# Check receiver's attunement level
|
490
|
+
receiver_attunement = receiver.get_skill("SPIRIT", "Attunement", domain)
|
491
|
+
return false if receiver_attunement < required_level
|
492
|
+
end
|
493
|
+
|
494
|
+
true
|
495
|
+
end
|
496
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# New 3-Tier System Structure for Amar RPG
|
2
|
+
# Characteristics > Attributes > Skills
|
3
|
+
|
4
|
+
$TierSystem = {
|
5
|
+
"BODY" => {
|
6
|
+
"Strength" => {
|
7
|
+
"skills" => ["Carrying", "Weight lifting", "Wield weapon"],
|
8
|
+
"base" => 3
|
9
|
+
},
|
10
|
+
"Endurance" => {
|
11
|
+
"skills" => ["Fortitude", "Combat Tenacity", "Running", "Poison Resistance"],
|
12
|
+
"base" => 3
|
13
|
+
},
|
14
|
+
"Athletics" => {
|
15
|
+
"skills" => ["Hide", "Move Quietly", "Climb", "Swim", "Ride", "Jump", "Balance", "Tumble"],
|
16
|
+
"base" => 3
|
17
|
+
},
|
18
|
+
"Melee Combat" => {
|
19
|
+
"skills" => [], # Will be populated from existing melee weapons table
|
20
|
+
"base" => 2
|
21
|
+
},
|
22
|
+
"Missile Combat" => {
|
23
|
+
"skills" => [], # Will be populated from existing missile weapons table
|
24
|
+
"base" => 2
|
25
|
+
},
|
26
|
+
"Sleight" => {
|
27
|
+
"skills" => ["Pick pockets", "Stage Magic", "Disarm Traps"],
|
28
|
+
"base" => 2
|
29
|
+
}
|
30
|
+
},
|
31
|
+
"MIND" => {
|
32
|
+
"Intelligence" => {
|
33
|
+
"skills" => ["Innovation", "Problem Solving"],
|
34
|
+
"base" => 3
|
35
|
+
},
|
36
|
+
"Nature Knowledge" => {
|
37
|
+
"skills" => ["Medical lore", "Plant Lore", "Animal Lore", "Animal Handling", "Magick Rituals", "Alchemy"],
|
38
|
+
"base" => 2
|
39
|
+
},
|
40
|
+
"Social Knowledge" => {
|
41
|
+
"skills" => ["Social lore", "Spoken Language", "Literacy", "Mythology", "Legend Lore"],
|
42
|
+
"base" => 2
|
43
|
+
},
|
44
|
+
"Practical Knowledge" => {
|
45
|
+
"skills" => ["Survival Lore", "Set traps", "Ambush"],
|
46
|
+
"base" => 2
|
47
|
+
},
|
48
|
+
"Awareness" => {
|
49
|
+
"skills" => ["Reaction speed", "Tracking", "Detect Traps", "Sense Emotions", "Sense Ambush", "Sense of Direction", "Sense Magick", "Listening"],
|
50
|
+
"base" => 3
|
51
|
+
},
|
52
|
+
"Willpower" => {
|
53
|
+
"skills" => ["Pain Tolerance", "Courage", "Hold Breath", "Mental Fortitude"],
|
54
|
+
"base" => 2
|
55
|
+
}
|
56
|
+
},
|
57
|
+
"SPIRIT" => {
|
58
|
+
"Casting" => {
|
59
|
+
"skills" => ["Range", "Duration", "Area of Effect", "Weight", "Number of targets"],
|
60
|
+
"base" => 0
|
61
|
+
},
|
62
|
+
"Attunement" => {
|
63
|
+
"skills" => ["Fire", "Water", "Air", "Earth", "Life", "Death", "Mind", "Body", "Self"],
|
64
|
+
"base" => 0
|
65
|
+
},
|
66
|
+
"Innate" => {
|
67
|
+
"skills" => ["Flying", "Camouflage", "Shape Shifting"],
|
68
|
+
"base" => 0
|
69
|
+
},
|
70
|
+
"Worship" => {
|
71
|
+
"skills" => [], # Will be populated with gods/entities
|
72
|
+
"base" => 0
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
# Mark requirements for advancement
|
78
|
+
$MarkRequirements = {
|
79
|
+
"marks_per_level" => 5, # Marks needed = 5 * next_level
|
80
|
+
"training_marks" => {
|
81
|
+
"BODY" => {
|
82
|
+
"with_teacher" => 2,
|
83
|
+
"without_teacher" => 1
|
84
|
+
},
|
85
|
+
"MIND" => {
|
86
|
+
"with_teacher" => 2,
|
87
|
+
"without_teacher" => 0.5
|
88
|
+
},
|
89
|
+
"SPIRIT" => {
|
90
|
+
"with_teacher" => 2,
|
91
|
+
"without_teacher" => 0.5
|
92
|
+
}
|
93
|
+
},
|
94
|
+
"conversion_rate" => 3, # 3 marks in lower tier = 1 mark in higher tier
|
95
|
+
"use_mark" => 1, # 1 mark per skill use requiring roll
|
96
|
+
"consecutive_use_bonus" => 2 # 5 consecutive uses = 2 marks
|
97
|
+
}
|
98
|
+
|
99
|
+
# Modifier calculations for new system
|
100
|
+
$NewModifiers = {
|
101
|
+
"BP" => lambda { |size, fortitude| size * 2 + fortitude / 3 },
|
102
|
+
"DB" => lambda { |size, wield_weapon| (size + wield_weapon) / 3 },
|
103
|
+
"MD" => lambda { |mental_fortitude, attunement_self| (mental_fortitude + attunement_self) / 3 }
|
104
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# The town table - all the various house types
|
2
|
+
|
3
|
+
$Town = Array.new
|
4
|
+
|
5
|
+
$Town[0] = [ "Type", "shop?", "%", "min", "Seniors", "Adults", "Young"]
|
6
|
+
$Town[1] = [ "Unhoused residents", 0, 1, 1, 1, 3, 1]
|
7
|
+
$Town[2] = [ "Stronghold", 0, 1, 1, 3, 6, 4]
|
8
|
+
$Town[3] = [ "Soldier/Guards", 0, 3, 1, 0, 4, 0]
|
9
|
+
$Town[4] = [ "Stable", 1, 2, 1, 2, 2, 2]
|
10
|
+
$Town[5] = [ "Inn", 0, 6, 1, 2, 2, 2]
|
11
|
+
$Town[6] = [ "Farm/Fishery", 1, 6, 3, 2, 2, 2]
|
12
|
+
$Town[7] = [ "General store", 1, 2, 1, 2, 2, 2]
|
13
|
+
$Town[8] = [ "Blacksmith", 1, 2, 1, 2, 2, 2]
|
14
|
+
$Town[9] = [ "Butcher", 1, 2, 1, 2, 2, 2]
|
15
|
+
$Town[10] = [ "Temple", 0, 5, 1, 2, 2, 2]
|
16
|
+
$Town[11] = [ "Horse trader", 1, 3, 0, 2, 2, 2]
|
17
|
+
$Town[12] = [ "Mill", 0, 2, 0, 2, 2, 2]
|
18
|
+
$Town[13] = [ "Baker", 1, 2, 0, 2, 2, 2]
|
19
|
+
$Town[14] = [ "Merchant", 1, 3, 0, 2, 2, 2]
|
20
|
+
$Town[15] = [ "Barber", 1, 2, 0, 2, 2, 2]
|
21
|
+
$Town[16] = [ "Leatherworker", 1, 3, 0, 2, 2, 2]
|
22
|
+
$Town[17] = [ "Grocery store", 1, 4, 0, 2, 2, 2]
|
23
|
+
$Town[18] = [ "Dyer/Tanner", 1, 2, 0, 2, 2, 2]
|
24
|
+
$Town[19] = [ "Mason", 1, 2, 0, 2, 2, 2]
|
25
|
+
$Town[20] = [ "Tailor", 1, 2, 0, 2, 2, 2]
|
26
|
+
$Town[21] = [ "Weapon smith", 1, 2, 0, 2, 2, 2]
|
27
|
+
$Town[22] = [ "Armourer", 1, 2, 0, 2, 2, 2]
|
28
|
+
$Town[23] = [ "Carpenter", 1, 3, 0, 2, 2, 2]
|
29
|
+
$Town[24] = [ "Cartwright", 1, 3, 0, 2, 2, 2]
|
30
|
+
$Town[25] = [ "Potter", 1, 2, 0, 2, 2, 2]
|
31
|
+
$Town[26] = [ "Worker", 0, 6, 1, 2, 2, 2]
|
32
|
+
$Town[27] = [ "Boatwright", 1, 2, 0, 2, 2, 2]
|
33
|
+
$Town[28] = [ "Noble", 0, 4, 0, 2, 2, 2]
|
34
|
+
$Town[29] = [ "Laundry", 1, 2, 0, 2, 2, 2]
|
35
|
+
$Town[30] = [ "Storage", 1, 3, 0, 2, 2, 2]
|
36
|
+
$Town[31] = [ "Slum", 0, 7, 0, 2, 2, 2]
|
37
|
+
$Town[32] = [ "Carpet maker", 1, 2, 0, 2, 2, 2]
|
38
|
+
$Town[33] = [ "Rope-/Netmaker", 1, 2, 0, 2, 2, 2]
|
39
|
+
$Town[34] = [ "Doctor", 1, 2, 0, 2, 2, 2]
|
40
|
+
$Town[35] = [ "Brothel", 1, 2, 0, 2, 2, 2]
|
41
|
+
$Town[36] = [ "Sailmaker", 1, 2, 0, 2, 2, 2]
|
42
|
+
$Town[37] = [ "Bowyer/Fletcher", 1, 2, 0, 2, 2, 2]
|
43
|
+
$Town[38] = [ "Weaver/spinner", 1, 2, 0, 2, 2, 2]
|
44
|
+
$Town[39] = [ "Veterinarian", 1, 2, 0, 2, 2, 2]
|
45
|
+
$Town[40] = [ "Animal trainer", 1, 2, 0, 2, 2, 2]
|
46
|
+
$Town[41] = [ "Furrier", 1, 2, 0, 2, 2, 2]
|
47
|
+
$Town[42] = [ "Brewer", 1, 2, 0, 2, 2, 2]
|
48
|
+
$Town[43] = [ "Cobbler", 1, 2, 0, 2, 2, 2]
|
49
|
+
$Town[44] = [ "Builder", 0, 2, 0, 2, 2, 2]
|
50
|
+
$Town[45] = [ "Farm worker", 0, 3, 0, 2, 2, 2]
|
51
|
+
$Town[46] = [ "Woodcarver/Engraver",1, 2, 0, 2, 2, 2]
|
52
|
+
$Town[47] = [ "Pawnshop", 1, 2, 0, 2, 2, 2]
|
53
|
+
$Town[48] = [ "Shoe maker", 1, 2, 0, 2, 2, 2]
|
54
|
+
$Town[49] = [ "Outfitter", 1, 2, 0, 2, 2, 2]
|
55
|
+
$Town[50] = [ "Public bath", 1, 2, 0, 2, 2, 2]
|
56
|
+
$Town[51] = [ "Alchemist", 1, 2, 0, 2, 2, 2]
|
57
|
+
$Town[52] = [ "Artist", 1, 3, 0, 2, 2, 2]
|
58
|
+
$Town[53] = [ "Diplomat", 0, 2, 0, 2, 2, 2]
|
59
|
+
$Town[54] = [ "Silver/goldsmith", 1, 2, 0, 2, 2, 2]
|
60
|
+
$Town[55] = [ "Jeweller", 1, 2, 0, 2, 2, 2]
|
61
|
+
$Town[56] = [ "Winery", 1, 2, 0, 2, 2, 2]
|
62
|
+
$Town[57] = [ "Destiller", 1, 1, 0, 2, 2, 2]
|
63
|
+
$Town[58] = [ "Teacher", 1, 3, 0, 2, 2, 2]
|
64
|
+
$Town[59] = [ "Scribe", 1, 2, 0, 2, 2, 2]
|
65
|
+
$Town[60] = [ "Tinker", 1, 2, 0, 2, 2, 2]
|
66
|
+
$Town[61] = [ "Illuminator", 1, 2, 0, 2, 2, 2]
|
67
|
+
$Town[62] = [ "Glassblower", 1, 2, 0, 2, 2, 2]
|
68
|
+
$Town[63] = [ "Artist/Cartographer",1, 2, 0, 2, 2, 2]
|
69
|
+
$Town[64] = [ "Perfumer", 1, 1, 0, 2, 2, 2]
|
70
|
+
$Town[65] = [ "Farm", 1, 100, 3, 2, 2, 2]
|
71
|
+
|