From 81d4ab7b996dbe64a79af54632326cd7f8bece4e Mon Sep 17 00:00:00 2001 From: MagicBot Date: Mon, 19 Oct 2026 14:29:01 -0400 Subject: [PATCH] Read item skill used and mastery from the cache template CombatManager shield checks, weapon skill/mastery lookups in AbstractCharacter, armor defense and PlayerCharacter.validEquip read getItemSkillUsed/getItemSkillMasteryUsed. Offline parity (p15d.py, 7586 rows): 0 mastery differences; skill used differs only where the legacy loader blanked it. The cache keeps "Cloth" (226 ARMOR templates), which the legacy loader turned into "". Cloth is a placeholder in Skills.cfg that no character has, so getArmorDefense now checks for it explicitly and still returns the flat defense rating. No weapon uses Cloth and no power equip prereq names it, so the other sites behave the same. Value changes: - 195340 Fortified Dragon Plate Helm of the Lion: skill used is the unresolved hash "2624663" instead of "". Defense is still the flat rating (no such skill), but players wearing it now hit the "armor equipped without the necessary skill" error log. Co-Authored-By: Claude Opus 5.5 --- src/engine/gameManager/CombatManager.java | 8 ++++---- src/engine/objects/AbstractCharacter.java | 13 +++++++------ src/engine/objects/PlayerCharacter.java | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 05ec8844..909e1322 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -93,25 +93,25 @@ public enum CombatManager { return; } - if (mainWeapon == null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) { + if (mainWeapon == null && offWeapon != null && !offWeapon.template.cacheTemplate.getItemSkillUsed().equals("Block")) { //swing left hand only processAttack(attacker, target, mbEnums.EquipSlotType.LHELD); return; } - if (mainWeapon == null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) { + if (mainWeapon == null && offWeapon != null && offWeapon.template.cacheTemplate.getItemSkillUsed().equals("Block")) { //no weapon equipped with a shield, punch with one hand processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); return; } - if (mainWeapon != null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) { + if (mainWeapon != null && offWeapon != null && offWeapon.template.cacheTemplate.getItemSkillUsed().equals("Block")) { //one weapon equipped with a shield, swing with one hand processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); return; } - if (mainWeapon != null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) { + if (mainWeapon != null && offWeapon != null && !offWeapon.template.cacheTemplate.getItemSkillUsed().equals("Block")) { //two weapons equipped, swing both hands processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) diff --git a/src/engine/objects/AbstractCharacter.java b/src/engine/objects/AbstractCharacter.java index 8344eba7..349868cf 100644 --- a/src/engine/objects/AbstractCharacter.java +++ b/src/engine/objects/AbstractCharacter.java @@ -766,8 +766,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject { } - skillPercentage = getModifiedAmount(abstractCharacter.skills.get(weapon.template.item_skill_used)); - masteryPercentage = getModifiedAmount(abstractCharacter.skills.get(weaponTemplate.item_skill_mastery_used)); + skillPercentage = getModifiedAmount(abstractCharacter.skills.get(weapon.template.cacheTemplate.getItemSkillUsed())); + masteryPercentage = getModifiedAmount(abstractCharacter.skills.get(weaponTemplate.cacheTemplate.getItemSkillMasteryUsed())); if (masteryPercentage == 0f) mastDam = 0f; @@ -1001,10 +1001,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject { if (!armor.template.cacheTemplate.getItemType().equals(ItemType.ARMOR)) return 0; - if (armor.template.item_skill_used.isEmpty()) + // "Cloth" is a placeholder in Skills.cfg (token 0) that no character learns + if (armor.template.cacheTemplate.getItemSkillUsed().isEmpty() || armor.template.cacheTemplate.getItemSkillUsed().equals("Cloth")) return engine.parsers.objects.ItemTemplate._items.get(armor.templateID).item_defense_rating; - CharacterSkill armorSkill = abstractCharacter.skills.get(armor.template.item_skill_used); + CharacterSkill armorSkill = abstractCharacter.skills.get(armor.template.cacheTemplate.getItemSkillUsed()); if (abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) && armorSkill == null) { Logger.error("Player " + abstractCharacter.getObjectUUID() @@ -1054,8 +1055,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject { skill = abstractCharacter.skills.get("Unarmed Combat"); mastery = abstractCharacter.skills.get("Unarmed Combat Mastery"); } else { - skill = abstractCharacter.skills.get(weapon.template.item_skill_used); - mastery = abstractCharacter.skills.get(weaponTemplate.item_skill_mastery_used); + skill = abstractCharacter.skills.get(weapon.template.cacheTemplate.getItemSkillUsed()); + mastery = abstractCharacter.skills.get(weaponTemplate.cacheTemplate.getItemSkillMasteryUsed()); } if (skill != null) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 9dae97f7..fe7499b9 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -2820,11 +2820,11 @@ public class PlayerCharacter extends AbstractCharacter { if (ib != null) { if ((item.template.cacheTemplate.getItemType().equals(ItemType.WEAPON)) - && (item.template.item_skill_used.equals(type) || ib.item_skill_mastery_used.equals(type))) + && (item.template.cacheTemplate.getItemSkillUsed().equals(type) || ib.cacheTemplate.getItemSkillMasteryUsed().equals(type))) return true; return (item.template.cacheTemplate.getItemType().equals(ItemType.ARMOR)) - && (item.template.item_skill_used.equals(type)); + && (item.template.cacheTemplate.getItemSkillUsed().equals(type)); } return false;