Read the weapon block from the cache template item_weapon

Range, speed, damage list and swing anims now come from
engine.parsers.objects.ItemTemplate.getWeapon(templateID). Non-weapons and
missing templates get an empty block, matching the legacy zero defaults.

Offline parity (scripts/p15b.py, 811 WEAPON rows vs COBJECTS/ITEM): 0
differences in speed, range, projectile, idle anim, damage list or either
anim list. No duplicate damage types exist, so sum vs first is moot; first
entry is used as before. 26 weapons (ammo, lutes, no-stats crossbows) have an
empty damage list, same as the DB. No value changes. No comparator removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MagicBotandClaude Opus 5.5 committed 2026-10-19 14:17:24 -04:00
1 parent 441a935bd9
commit 6b2f000434
5 files changed
+48 -33

No files matched your search

+9 -8
View File
@@ -693,6 +693,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
// make sure weapon exists
boolean noWeapon = false;
ItemTemplate weaponTemplate = null;
engine.parsers.objects.ItemTemplate.Damage damage;
if (weapon == null)
noWeapon = true;
@@ -751,9 +752,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} else {
if (mainHand)
abstractCharacter.rangeHandOne = weapon.template.item_weapon_max_range * (1 + (abstractCharacter.statStrBase / 600));
abstractCharacter.rangeHandOne = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * (1 + (abstractCharacter.statStrBase / 600));
else
abstractCharacter.rangeHandTwo = weapon.template.item_weapon_max_range * (1 + (abstractCharacter.statStrBase / 600));
abstractCharacter.rangeHandTwo = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_max_range * (1 + (abstractCharacter.statStrBase / 600));
if (abstractCharacter.bonuses != null) {
float range_bonus = 1 + abstractCharacter.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None);
@@ -773,10 +774,10 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
// mastDam = CharacterSkill.getQuickMastery(this, wb.getMastery());
else
mastDam = masteryPercentage;
int[] damages = (int[]) weaponTemplate.item_weapon_damage.values().toArray()[0];
damage = engine.parsers.objects.ItemTemplate.getWeapon(weapon.templateID).weapon_damage.get(0);
min = damages[0];
max = damages[1];
min = damage.damage_min;
max = damage.damage_max;
strBased = engine.parsers.objects.ItemTemplate._items.get(weapon.templateID).item_primary_attr == AttributeType.Strength;
}
@@ -827,7 +828,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
//calculate speed
if (weaponTemplate != null)
speed = weaponTemplate.item_weapon_wepspeed;
speed = engine.parsers.objects.ItemTemplate.getWeapon(weaponTemplate.template_id).weapon_wepspeed;
else
speed = 20f; //unarmed attack speed
if (weapon != null)
@@ -1508,9 +1509,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
}
float range = 8;
if ((this).charItemManager.equipped.get(EquipSlotType.RHELD) != null) {
range = ((Mob) this).charItemManager.equipped.get(EquipSlotType.RHELD).template.item_weapon_max_range;
range = engine.parsers.objects.ItemTemplate.getWeapon(((Mob) this).charItemManager.equipped.get(EquipSlotType.RHELD).templateID).weapon_max_range;
} else if (((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD) != null) {
range = ((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD).template.item_weapon_max_range;
range = engine.parsers.objects.ItemTemplate.getWeapon(((Mob) this).charItemManager.equipped.get(EquipSlotType.LHELD).templateID).weapon_max_range;
} else {
// Unarmed: use the rune natural attack range when it has one (e.g. Gasser 150), not clamped.