amar-rpg 2.0.1 → 2.1.0
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 +4 -4
- data/amar-tui.rb +1 -1
- data/cli_npc_output_new.rb +44 -44
- data/includes/class_npc_new.rb +41 -7
- data/includes/spell_catalog.rb +12 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 536b86190b86f88e7cf0fbcb996b3777d763db1355cf7d00c5888ace8215cae5
|
4
|
+
data.tar.gz: 2e5b19fc161bc0075360119726e8ae7ff6afcdf845569400276e4015fea4b536
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15600fb55d0b19e8b27cdde1714f33d94fb9a2129b41017241a158c3d4346a3b1418bcd6361905394c6b0daaca433b32395a65469ebbf0207ff37f3f73c23b57
|
7
|
+
data.tar.gz: ded060cb9604355162869df99af628daa0e51f4bba38178d092579ce9776e5807d3d488e11280f993db53fd1978e2132e59a1a6d46b3459db84ff61e6ddbc36f
|
data/amar-tui.rb
CHANGED
data/cli_npc_output_new.rb
CHANGED
@@ -231,8 +231,9 @@ def npc_output_new(n, cli, custom_width = nil)
|
|
231
231
|
end
|
232
232
|
|
233
233
|
# Check if we have original weapon data and display it
|
234
|
-
|
235
|
-
|
234
|
+
# DISABLED: Old weapon format only shows 2-3 weapons, new format shows all skills
|
235
|
+
if false && n.respond_to?(:melee1) && !n.melee1.to_s.empty?
|
236
|
+
# Display ORIGINAL weapon format (DEPRECATED)
|
236
237
|
f += "─" * width + "\n"
|
237
238
|
f += "#{@weapon_color}WEAPON SKILL INI OFF DEF DAM HP RANGE#{@reset}\n"
|
238
239
|
|
@@ -273,68 +274,67 @@ def npc_output_new(n, cli, custom_width = nil)
|
|
273
274
|
f += "\n"
|
274
275
|
end
|
275
276
|
else
|
276
|
-
#
|
277
|
-
melee_weapons = n.tiers["BODY"]["Melee Combat"]["skills"].select { |_, v| v > 0 }
|
278
|
-
missile_weapons = n.tiers["BODY"]["Missile Combat"]["skills"].select { |_, v| v > 0 }
|
279
|
-
|
277
|
+
# 3-tier weapon display - show ALL weapon skills
|
278
|
+
melee_weapons = n.tiers["BODY"]["Melee Combat"]["skills"].select { |_, v| v > 0 } rescue {}
|
279
|
+
missile_weapons = n.tiers["BODY"]["Missile Combat"]["skills"].select { |_, v| v > 0 } rescue {}
|
280
|
+
|
280
281
|
if melee_weapons.any? || missile_weapons.any?
|
281
282
|
f += "─" * width + "\n"
|
282
|
-
f += "#{@weapon_color}
|
283
|
-
|
284
|
-
# Headers
|
285
|
-
melee_header = "Melee Weapon".ljust(15) + "Skill Init Off Def Damage"
|
286
|
-
missile_header = "Missile Weapon".ljust(15) + "Skill Range Damage"
|
287
|
-
f += "#{melee_header.ljust(60)} │ #{missile_header}\n"
|
288
|
-
f += "─" * 61 + "┼" + "─" * 58 + "\n"
|
289
|
-
|
290
|
-
# Format weapons with calculated totals
|
291
|
-
melee_lines = []
|
292
|
-
missile_lines = []
|
293
|
-
|
283
|
+
f += "#{@weapon_color}WEAPON SKILL INI OFF DEF DAM HP RANGE#{@reset}\n"
|
284
|
+
|
294
285
|
body_char = n.get_characteristic("BODY")
|
295
|
-
|
286
|
+
|
296
287
|
# Calculate Dodge bonus for defense (Dodge/5 rounded down)
|
297
288
|
dodge_total = n.get_skill_total("BODY", "Athletics", "Dodge") || 0
|
298
289
|
dodge_bonus = (dodge_total / 5).to_i
|
299
|
-
|
300
|
-
|
290
|
+
|
291
|
+
# Get reaction speed for initiative
|
292
|
+
reaction_speed = n.get_skill_total("MIND", "Awareness", "Reaction speed") || 0
|
293
|
+
|
294
|
+
# Display melee weapons
|
295
|
+
melee_weapons.sort_by { |_, skill| -skill }.each do |weapon, skill|
|
301
296
|
wpn_stats = get_weapon_stats(weapon)
|
302
297
|
attr = n.get_attribute("BODY", "Melee Combat") || 0
|
303
298
|
skill_total = body_char + attr + skill
|
304
|
-
|
305
|
-
# Calculate weapon totals with correct initiative formula
|
306
|
-
# Initiative = Weapon Init + Reaction Speed skill total
|
307
|
-
reaction_speed = n.get_skill_total("MIND", "Awareness", "Reaction speed") || 0
|
299
|
+
|
308
300
|
init = reaction_speed + (wpn_stats[:init] || 0)
|
309
301
|
off = skill_total + (wpn_stats[:off] || 0)
|
310
|
-
defense = skill_total + (wpn_stats[:def] || 0) + dodge_bonus
|
302
|
+
defense = skill_total + (wpn_stats[:def] || 0) + dodge_bonus
|
311
303
|
dmg_mod = wpn_stats[:dmg].to_s =~ /special/ ? 0 : (wpn_stats[:dmg].to_s.to_i || 0)
|
312
304
|
dmg = (n.DB || 0) + dmg_mod
|
313
|
-
|
314
|
-
|
315
|
-
|
305
|
+
hp = wpn_stats[:hp] || 0
|
306
|
+
|
307
|
+
f += "#{weapon.ljust(19)}"
|
308
|
+
f += "#{skill_total.to_s.ljust(9)}"
|
309
|
+
f += "#{init.to_s.ljust(8)}"
|
310
|
+
f += "#{off.to_s.ljust(7)}"
|
311
|
+
f += "#{defense.to_s.ljust(7)}"
|
312
|
+
f += "#{dmg.to_s.ljust(7)}"
|
313
|
+
f += "#{hp.to_s.ljust(6)}"
|
314
|
+
f += "\n"
|
316
315
|
end
|
317
|
-
|
318
|
-
|
316
|
+
|
317
|
+
# Display missile weapons
|
318
|
+
missile_weapons.sort_by { |_, skill| -skill }.each do |weapon, skill|
|
319
319
|
wpn_stats = get_missile_stats(weapon)
|
320
320
|
attr = n.get_attribute("BODY", "Missile Combat") || 0
|
321
321
|
skill_total = body_char + attr + skill
|
322
|
-
|
322
|
+
|
323
|
+
off = skill_total + (wpn_stats[:off] || 0)
|
323
324
|
range = wpn_stats[:range] || "30m"
|
324
325
|
dmg_mod = wpn_stats[:dmg].to_s =~ /special/ ? 0 : (wpn_stats[:dmg].to_s.to_i || 0)
|
325
326
|
dmg = (n.DB || 0) + dmg_mod
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
f += "#{melee_lines[i].ljust(60)} │ #{missile_lines[i]}\n"
|
327
|
+
hp = wpn_stats[:hp] || 0
|
328
|
+
|
329
|
+
f += "#{weapon.ljust(19)}"
|
330
|
+
f += "#{skill_total.to_s.ljust(9)}"
|
331
|
+
f += "#{' '.ljust(8)}" # No init for missile
|
332
|
+
f += "#{off.to_s.ljust(7)}"
|
333
|
+
f += "#{' '.ljust(7)}" # No def for missile
|
334
|
+
f += "#{dmg.to_s.ljust(7)}"
|
335
|
+
f += "#{hp.to_s.ljust(6)}"
|
336
|
+
f += "#{range}"
|
337
|
+
f += "\n"
|
338
338
|
end
|
339
339
|
end
|
340
340
|
end # Close the original/3-tier weapon display if/else block
|
data/includes/class_npc_new.rb
CHANGED
@@ -406,10 +406,22 @@ class NpcNew
|
|
406
406
|
else 0.5
|
407
407
|
end
|
408
408
|
|
409
|
-
# Use
|
410
|
-
|
411
|
-
|
412
|
-
|
409
|
+
# Use scaling that produces desired total skill progression
|
410
|
+
# Target totals: L1: 4-5, L2: 6-7, L3: 8-9, L4: 10-11, L5: 12-13, L6: 14+
|
411
|
+
# Typical warrior has BODY 1-2, Melee Combat 2-3, Weapon skill 2-3 at mid-levels
|
412
|
+
level_multiplier = case npc_level
|
413
|
+
when 1 then 0.7
|
414
|
+
when 2 then 0.95
|
415
|
+
when 3 then 1.2
|
416
|
+
when 4 then 1.45
|
417
|
+
when 5 then 1.7
|
418
|
+
when 6 then 1.95
|
419
|
+
else 2.2
|
420
|
+
end
|
421
|
+
|
422
|
+
level = (base * level_multiplier * growth_rate).to_i
|
423
|
+
|
424
|
+
# Add variation ONLY if base > 0
|
413
425
|
if base > 0
|
414
426
|
variation = rand(3) - 1 # -1, 0, or 1
|
415
427
|
level += variation
|
@@ -449,20 +461,42 @@ class NpcNew
|
|
449
461
|
end
|
450
462
|
|
451
463
|
def add_weapon_skills(template)
|
452
|
-
# Add melee weapon skills
|
464
|
+
# Add melee weapon skills with primary weapon specialization
|
453
465
|
if template["melee_weapons"]
|
454
466
|
@tiers["BODY"]["Melee Combat"]["skills"] ||= {}
|
455
|
-
|
467
|
+
|
468
|
+
# Find primary weapon (highest base value)
|
469
|
+
primary_weapon = template["melee_weapons"].max_by { |_, v| v }
|
470
|
+
|
471
|
+
template["melee_weapons"].each_with_index do |(weapon, skill_level), index|
|
456
472
|
base_level = calculate_tier_level(skill_level, @level, 0.6)
|
473
|
+
|
474
|
+
# Boost primary weapon by 1-2 points for specialization
|
475
|
+
if weapon == primary_weapon[0] && skill_level >= 4
|
476
|
+
boost = rand(2) + 1 # +1 or +2
|
477
|
+
base_level += boost
|
478
|
+
end
|
479
|
+
|
457
480
|
@tiers["BODY"]["Melee Combat"]["skills"][weapon] = base_level
|
458
481
|
end
|
459
482
|
end
|
460
|
-
|
483
|
+
|
461
484
|
# Add missile weapon skills
|
462
485
|
if template["missile_weapons"]
|
463
486
|
@tiers["BODY"]["Missile Combat"]["skills"] ||= {}
|
487
|
+
|
488
|
+
# Find primary missile weapon
|
489
|
+
primary_missile = template["missile_weapons"].max_by { |_, v| v }
|
490
|
+
|
464
491
|
template["missile_weapons"].each do |weapon, skill_level|
|
465
492
|
base_level = calculate_tier_level(skill_level, @level, 0.6)
|
493
|
+
|
494
|
+
# Boost primary missile weapon
|
495
|
+
if weapon == primary_missile[0] && skill_level >= 3
|
496
|
+
boost = rand(2) + 1 # +1 or +2
|
497
|
+
base_level += boost
|
498
|
+
end
|
499
|
+
|
466
500
|
@tiers["BODY"]["Missile Combat"]["skills"][weapon] = base_level
|
467
501
|
end
|
468
502
|
end
|
data/includes/spell_catalog.rb
CHANGED
@@ -369,11 +369,13 @@ def assign_spells_to_npc(npc)
|
|
369
369
|
|
370
370
|
max_spells = case magic_skill
|
371
371
|
when 0..5 then 0 # No spells for beginners
|
372
|
-
when 6..
|
373
|
-
when 11
|
374
|
-
when
|
375
|
-
when
|
376
|
-
|
372
|
+
when 6..8 then 2 # 2 spells for novices
|
373
|
+
when 9..11 then 4 # 4 spells for apprentices
|
374
|
+
when 12..14 then 6 # 6 spells for competent
|
375
|
+
when 15..17 then 8 # 8 spells for skilled
|
376
|
+
when 18..20 then 10 # 10 spells for experts
|
377
|
+
when 21..25 then 12 # 12 spells for masters
|
378
|
+
else 15 # 15 spells for legendary
|
377
379
|
end
|
378
380
|
|
379
381
|
# Get character's strongest magical domains
|
@@ -388,6 +390,7 @@ def assign_spells_to_npc(npc)
|
|
388
390
|
can_cast = true
|
389
391
|
spell_data[:skill_path].each do |skill_part|
|
390
392
|
# Simplified check - character should have some relevant skills
|
393
|
+
# Also check abbreviated names (e.g., "Prot." for "Protection")
|
391
394
|
case skill_part
|
392
395
|
when "Fire" then can_cast &&= (all_magic_skills["Fire"] || 0) > 0
|
393
396
|
when "Water" then can_cast &&= (all_magic_skills["Water"] || 0) > 0
|
@@ -395,11 +398,13 @@ def assign_spells_to_npc(npc)
|
|
395
398
|
when "Earth" then can_cast &&= (all_magic_skills["Earth"] || 0) > 0
|
396
399
|
when "Mind" then can_cast &&= (all_magic_skills["Mind"] || 0) > 0
|
397
400
|
when "Nature" then can_cast &&= (all_magic_skills["Nature"] || 0) > 0
|
398
|
-
when "Protection" then can_cast &&= (all_magic_skills["Protection"] || 0) > 0
|
399
|
-
when "Illusion" then can_cast &&= (all_magic_skills["Illusion"] || 0) > 0
|
401
|
+
when "Protection" then can_cast &&= ((all_magic_skills["Protection"] || 0) > 0 || (all_magic_skills["Prot."] || 0) > 0)
|
402
|
+
when "Illusion" then can_cast &&= ((all_magic_skills["Illusion"] || 0) > 0 || (all_magic_skills["Ill."] || 0) > 0)
|
400
403
|
when "Shadow" then can_cast &&= (all_magic_skills["Shadow"] || 0) > 0
|
401
404
|
when "Self" then can_cast &&= (all_magic_skills["Self"] || 0) > 0
|
402
405
|
when "Life" then can_cast &&= (all_magic_skills["Life"] || 0) > 0
|
406
|
+
when "Time" then can_cast &&= (all_magic_skills["Time"] || 0) > 0
|
407
|
+
when "Death" then can_cast &&= (all_magic_skills["Death"] || 0) > 0
|
403
408
|
end
|
404
409
|
end
|
405
410
|
can_cast
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amar-rpg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
@@ -123,7 +123,7 @@ metadata:
|
|
123
123
|
post_install_message: |2+
|
124
124
|
|
125
125
|
===========================================
|
126
|
-
AMAR RPG Tools v2.0
|
126
|
+
AMAR RPG Tools v2.1.0 has been installed!
|
127
127
|
===========================================
|
128
128
|
|
129
129
|
To start the application:
|