Move the vendor mod table off the legacy item template

LOAD_TEMPLATE_MODTABLES now returns a templateID -> modTable map that
ForgeManager owns (vendorModTables). ForgeManager.forgeItem, WorkOrder
validation and the ManageNPCMsg forge item list read it through
ForgeManager.getVendorModTable(), and ItemTemplate.modTable is removed.

Values are unchanged: static_vendor_items has 5089 rows, one per
templateID, all present in static_item_templates, modTable 0-30.
Templates not in the table still read 0. The old loader stopped at the
first templateID missing from ItemTemplate.templates; there are none.
No comparator added or removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MagicBotandClaude Opus 5.5 committed 2026-10-20 07:37:54 -04:00
1 parent 2b4c1a73d1
commit 70ea9b3bc9
6 files changed
+27 -20

No files matched your search

+7 -7
View File
@@ -201,23 +201,23 @@ public class dbItemHandler extends dbHandlerBase {
}
}
public void LOAD_TEMPLATE_MODTABLES() {
public HashMap<Integer, Integer> LOAD_TEMPLATE_MODTABLES() {
HashMap<Integer, Integer> modTables = new HashMap<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_vendor_items`;");
ResultSet rs = preparedStatement.executeQuery()) {
while (rs.next()) {
int templateID = rs.getInt("templateID");
int modTable = rs.getInt("modTable");
ItemTemplate template = ItemTemplate.templates.get(templateID);
template.modTable = modTable;
}
while (rs.next())
modTables.put(rs.getInt("templateID"), rs.getInt("modTable"));
} catch (Exception e) {
Logger.error(e);
}
Logger.info("read: " + modTables.size());
return modTables;
}
public Item GET_ITEM(final int itemUUID) {
+12 -5
View File
@@ -49,6 +49,9 @@ public enum ForgeManager implements Runnable {
public static final ConcurrentHashMap<NPC, ConcurrentHashMap.KeySetView<WorkOrder, Boolean>> vendorWorkOrderLookup = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<Item, WorkOrder> itemWorkOrderLookup = new ConcurrentHashMap<>();
// Server-only data from static_vendor_items; the client templates have no mod table.
public static HashMap<Integer, Integer> vendorModTables = new HashMap<>();
public static void start() {
Thread forgeManager;
@@ -248,8 +251,8 @@ public enum ForgeManager implements Runnable {
// Create new virtual item from specified template
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
Item forgedItem = new Item(workOrder.templateID);
int modTable = getVendorModTable(workOrder.templateID);
// forgedItem gets a negative id; a virtual item which is not persisted
@@ -264,13 +267,13 @@ public enum ForgeManager implements Runnable {
// Assign a prefix and suffix to this item if random rolled
if (workOrder.prefixToken == 0 && workOrder.vendor.getItemModTable().contains((template.modTable)))
forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, template.modTable);
if (workOrder.prefixToken == 0 && workOrder.vendor.getItemModTable().contains(modTable))
forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, modTable);
else
forgedItem.prefixToken = workOrder.prefixToken;
if (workOrder.suffixToken == 0 && workOrder.vendor.getItemModTable().contains((template.modTable)))
forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, template.modTable);
if (workOrder.suffixToken == 0 && workOrder.vendor.getItemModTable().contains(modTable))
forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, modTable);
else
forgedItem.suffixToken = workOrder.suffixToken;
@@ -364,6 +367,10 @@ public enum ForgeManager implements Runnable {
DbManager.WarehouseQueries.WRITE_WORKORDER(workOrder);
}
public static int getVendorModTable(int templateID) {
return vendorModTables.getOrDefault(templateID, 0);
}
public static int calcRandomMod(NPC vendor, mbEnums.ItemModType itemModType, int modTable) {
// Random prefix or suffix token based on item.template.modtable
+1 -1
View File
@@ -136,7 +136,7 @@ public class WorkOrder implements Delayed {
return 30; //30: That person cannot carry that item
if ((workOrder.prefixToken != 0 || workOrder.suffixToken != 0) &&
!workOrder.vendor.getItemModTable().contains((template.modTable)))
!workOrder.vendor.getItemModTable().contains(ForgeManager.getVendorModTable(workOrder.templateID)))
return 59; //59: This hireling does not have this formula
if (!Warehouse.calcCostOverrun(workOrder).isEmpty())
+5 -4
View File
@@ -421,16 +421,17 @@ public class ManageNPCMsg extends ClientNetMsg {
for (int templateID : rollableSet) {
ItemTemplate template = ItemTemplate.templates.get(templateID);
int modTable = ForgeManager.getVendorModTable(templateID);
writer.put((byte) 1);
writer.putInt(0);
writer.putInt(templateID); //itemID
writer.putInt(template.cacheTemplate.getItemValue());
writer.putInt(600);
writer.put((byte) 1);
writer.put((byte) template.modTable);
writer.put((byte) template.modTable);
writer.put((byte) template.modTable);
writer.put((byte) template.modTable);//EffectItemType
writer.put((byte) modTable);
writer.put((byte) modTable);
writer.put((byte) modTable);
writer.put((byte) modTable);//EffectItemType
}
ArrayList<Item> cooking = NPCManager.getAllCookingForVendor(npc);
-1
View File
@@ -101,7 +101,6 @@ public class ItemTemplate {
// engine.parsers.objects.RuneTemplate keeps the full list.
public final HashMap<String, int[]> item_power_action = new HashMap<>();
public final HashMap<mbEnums.ResourceType, Integer> item_resource_cost = new HashMap<>();
public int modTable;
public int deed_type;
public int deed_furniture_id;
public int deed_target_id;
+2 -2
View File
@@ -307,8 +307,8 @@ public class WorldServer {
Logger.info("Loading Item Templates");
DbManager.ItemQueries.LOAD_ITEM_TEMPLATES();
Logger.info("Back fill template modTables");
DbManager.ItemQueries.LOAD_TEMPLATE_MODTABLES();
Logger.info("Loading vendor modTables");
ForgeManager.vendorModTables = DbManager.ItemQueries.LOAD_TEMPLATE_MODTABLES();
Logger.info("Loading Deed Templates");
DeedTemplate._deeds = DeedParser.parseDeedFolder();