From 7c12d5bde0d372d65e714aed1db0d31162888c70 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Thu, 22 Oct 2026 08:19:38 -0400 Subject: [PATCH] Load power granted trains from item_power_action instead of static_power_powergrant Amount = power_arguments[0] of each power type's first action, keyed by SBStringHash(power_type). Parity (scripts/p28.py): 69 of the 70 DB runes match; Wizard 2521 WIZ-064 Conjure Familiar goes from 1 to 20 (decided JSON). The JSON adds grants on 2189 runes: mob and guard races (2100+), Archon 2018 (ARCHON-001..005 40, CSR-UNINVIS 30), and NPC trainer/guard talents (252569-252655, 253002). Only Archon is a player race; the talents are not player runes. The DB loader stays until 2.11. Co-Authored-By: Claude Opus 5.5 --- src/engine/objects/PowerGrantedTrains.java | 32 +++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/PowerGrantedTrains.java b/src/engine/objects/PowerGrantedTrains.java index 91920930..e4d7dda9 100644 --- a/src/engine/objects/PowerGrantedTrains.java +++ b/src/engine/objects/PowerGrantedTrains.java @@ -10,7 +10,9 @@ package engine.objects; import engine.gameManager.DbManager; +import engine.parsers.objects.RuneTemplate; import engine.server.MBServerStatics; +import engine.util.Hasher; import org.pmw.tinylog.Logger; import java.sql.Connection; @@ -18,6 +20,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -35,6 +38,10 @@ public class PowerGrantedTrains { runeGrants.put(rs.getInt("runeID"), rs.getShort("grantAmount")); } + public PowerGrantedTrains(int token) { + this.token = token; + } + /* * Getters */ @@ -44,7 +51,7 @@ public class PowerGrantedTrains { return (short) 0; if (PowerGrantedTrains.grantedPowers == null) - fillGrantedPowers(); + loadGrantedPowers(); if (PowerGrantedTrains.grantedPowers.containsKey(token)) { PowerGrantedTrains pg = PowerGrantedTrains.grantedPowers.get(token); @@ -87,6 +94,29 @@ public class PowerGrantedTrains { return (short) 0; } + // Trains are power_arguments[0] of the first action; only mob race runes carry more than one. + public static void loadGrantedPowers() { + + ConcurrentHashMap powerGrants = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); + int token; + int grantCount = 0; + + for (RuneTemplate rune : RuneTemplate._runes.values()) + for (Map.Entry> powerAction : rune.item_power_action.entrySet()) { + + if (powerAction.getValue().isEmpty()) + continue; + + token = Hasher.SBStringHash(powerAction.getKey()); + powerGrants.computeIfAbsent(token, PowerGrantedTrains::new) + .addRuneGrant(rune.template_id, (short) powerAction.getValue().get(0)[0]); + grantCount++; + } + + PowerGrantedTrains.grantedPowers = powerGrants; + Logger.info("Loaded " + grantCount + " power train grants for " + powerGrants.size() + " powers"); + } + public static void fillGrantedPowers() { PowerGrantedTrains.grantedPowers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);