diff --git a/src/engine/objects/Kit.java b/src/engine/objects/Kit.java index f4b0e540..e3b48075 100644 --- a/src/engine/objects/Kit.java +++ b/src/engine/objects/Kit.java @@ -1,3 +1,4 @@ + // • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ @@ -11,58 +12,65 @@ package engine.objects; import engine.gameManager.DbManager; import engine.mbEnums; +import engine.mbEnums.EquipSlotType; import engine.mbEnums.ItemContainerType; import engine.mbEnums.OwnerType; +import engine.parsers.objects.ItemTemplate; +import engine.parsers.objects.RuneTemplate; +import engine.parsers.objects.wpak.StartingKitTemplate; import org.pmw.tinylog.Logger; import java.net.UnknownHostException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.EnumMap; import java.util.HashMap; +import java.util.Map; public class Kit extends AbstractGameObject { public static HashMap NoobGearIDS = new HashMap<>(); public static HashMap> RaceClassIDMap = new HashMap<>(); - private final int raceBaseClassID; + + // Keyed like the client's kit map (0x620250): race name, sex and class name, not rune ids + private static final HashMap> _kitsByRaceClass = new HashMap<>(); + private final byte kitNumber; - private final int legs; - private final int chest; - private final int feet; - private final int offhand; - private final int weapon; + private final EnumMap items = new EnumMap<>(EquipSlotType.class); - - /** - * No Table ID Constructor - */ - public Kit(int raceBaseClassID, byte kitNumber, int legs, int chest, - int feet, int offhand, int weapon) { + public Kit(StartingKitTemplate template) { super(); - this.raceBaseClassID = raceBaseClassID; - this.kitNumber = kitNumber; - this.legs = legs; - this.chest = chest; - this.feet = feet; - this.offhand = offhand; - this.weapon = weapon; - } - /** - * Normal Constructor - */ - public Kit(int raceBaseClassID, byte kitNumber, int legs, int chest, - int feet, int offhand, int weapon, int newUUID) { - super(newUUID); - this.raceBaseClassID = raceBaseClassID; - this.kitNumber = kitNumber; - this.legs = legs; - this.chest = chest; - this.feet = feet; - this.offhand = offhand; - this.weapon = weapon; + int itemID; + ItemTemplate itemTemplate; + EquipSlotType slot; + + this.kitNumber = (byte) template.kit_number; + + // The cfg lists the off-hand column before the weapon; fill from the end so the weapon takes RHELD + for (int i = template.item_ids.size() - 1; i >= 0; i--) { + itemID = template.item_ids.get(i); + Kit.NoobGearIDS.put(itemID, true); + itemTemplate = ItemTemplate._items.get(itemID); + + if (itemTemplate == null) { + Logger.warn("Kit " + kitKey(template.race, template.sex.name(), template.base_class) + " #" + this.kitNumber + + ": no item template " + itemID); + continue; + } + + slot = freeSlot(itemTemplate); + + if (slot == null) { + Logger.warn("Kit " + kitKey(template.race, template.sex.name(), template.base_class) + " #" + this.kitNumber + + ": no free slot for item " + itemID); + continue; + } + + this.items.put(slot, itemID); + } } /** @@ -71,34 +79,54 @@ public class Kit extends AbstractGameObject { public Kit(ResultSet rs) throws SQLException, UnknownHostException { super(rs); - this.raceBaseClassID = rs.getInt("RaceBaseClassesID"); + int raceBaseClassID = rs.getInt("RaceBaseClassesID"); this.kitNumber = rs.getByte("kitNumber"); - this.legs = rs.getInt("legs"); - this.chest = rs.getInt("chest"); - this.feet = rs.getInt("feet"); - this.offhand = rs.getInt("offhand"); - this.weapon = rs.getInt("weapon"); - if (Kit.RaceClassIDMap.containsKey(this.raceBaseClassID)) { - Kit.RaceClassIDMap.get(this.raceBaseClassID).add(this); + putColumn(EquipSlotType.LEGS, rs.getInt("legs")); + putColumn(EquipSlotType.CHEST, rs.getInt("chest")); + putColumn(EquipSlotType.FEET, rs.getInt("feet")); + putColumn(EquipSlotType.LHELD, rs.getInt("offhand")); + putColumn(EquipSlotType.RHELD, rs.getInt("weapon")); + + if (Kit.RaceClassIDMap.containsKey(raceBaseClassID)) { + Kit.RaceClassIDMap.get(raceBaseClassID).add(this); } else { ArrayList tempList = new ArrayList<>(); tempList.add(this); - Kit.RaceClassIDMap.put(this.raceBaseClassID, tempList); + Kit.RaceClassIDMap.put(raceBaseClassID, tempList); + } + } + public static void LoadAllKits() { + + Kit kit; + String key; + + for (StartingKitTemplate template : StartingKitTemplate._kits) { + kit = new Kit(template); + key = kitKey(template.race, template.sex.name(), template.base_class); + _kitsByRaceClass.computeIfAbsent(key, k -> new ArrayList<>()).add(kit); } - if (this.legs != 0) - Kit.NoobGearIDS.put(this.legs, true); - if (this.chest != 0) - Kit.NoobGearIDS.put(this.chest, true); - if (this.feet != 0) - Kit.NoobGearIDS.put(this.feet, true); - if (this.offhand != 0) - Kit.NoobGearIDS.put(this.offhand, true); - if (this.weapon != 0) - Kit.NoobGearIDS.put(this.weapon, true); + Logger.info("Loaded " + StartingKitTemplate._kits.size() + " kits for " + _kitsByRaceClass.size() + " race/sex/class"); + } + public static Kit getKit(int raceRuneID, int baseClassRuneID, int kitNumber) { + + RuneTemplate raceRune = RuneTemplate._runes.get(raceRuneID); + RuneTemplate classRune = RuneTemplate._runes.get(baseClassRuneID); + mbEnums.RaceType raceType = mbEnums.RaceType.getRaceTypebyRuneID(raceRuneID); + ArrayList kits; + + if (raceRune == null || classRune == null || raceType == null) + return null; + + kits = _kitsByRaceClass.get(kitKey(raceRune.obj_name, raceType.getCharacterSex().name(), classRune.obj_name)); + + if (kits == null || kitNumber < 0 || kitNumber >= kits.size()) + return null; + + return kits.get(kitNumber); } public static boolean IsNoobGear(int itemID) { @@ -107,9 +135,9 @@ public class Kit extends AbstractGameObject { } - /* - * Getters - */ + private static String kitKey(String race, String sex, String baseClass) { + return race + " " + sex + " " + baseClass; + } private static boolean kitItemCreator(PlayerCharacter pc, int templateID, mbEnums.EquipSlotType slot) { @@ -131,293 +159,31 @@ public class Kit extends AbstractGameObject { return true; } - public static int GetKitIDByRaceClass(final int raceID, final int classID) { - switch (raceID) { - case 2000: - switch (classID) { - case 2500: - return 2; - case 2501: - return 3; - case 2502: - return 4; - case 2503: - return 5; - } - case 2001: + private EquipSlotType freeSlot(ItemTemplate itemTemplate) { - switch (classID) { - case 2500: - return 6; - case 2501: - return 7; - case 2502: - return 8; - case 2503: - return 9; - } - case 2002: - switch (classID) { - case 2500: - return 10; - case 2501: - return 11; - case 2502: - return 12; + for (EquipSlotType slot : itemTemplate.item_eq_slots_or) + if (!this.items.containsKey(slot)) + return slot; - } - case 2003: - switch (classID) { - case 2500: - return 13; - case 2501: - return 14; - case 2502: - return 15; - } - case 2004: - - switch (classID) { - case 2500: - return 16; - case 2501: - return 17; - } - case 2005: - switch (classID) { - case 2500: - return 18; - case 2501: - return 19; - } - case 2006: - - switch (classID) { - case 2500: - return 20; - case 2501: - return 21; - - } - case 2008: - - switch (classID) { - case 2500: - return 22; - case 2501: - return 23; - case 2502: - return 24; - case 2503: - return 25; - } - - case 2009: - - switch (classID) { - case 2500: - return 26; - case 2501: - return 27; - case 2502: - return 28; - case 2503: - return 29; - } - case 2010: - - switch (classID) { - case 2500: - return 30; - } - - case 2011: - - switch (classID) { - case 2500: - return 31; - case 2501: - return 32; - case 2502: - return 33; - case 2503: - return 34; - } - - case 2012: - - switch (classID) { - case 2500: - return 35; - case 2501: - return 36; - case 2502: - return 37; - case 2503: - return 38; - } - - case 2013: - - switch (classID) { - case 2500: - return 39; - case 2501: - return 40; - case 2502: - return 41; - case 2503: - return 42; - } - - case 2014: - - switch (classID) { - case 2500: - return 43; - case 2501: - return 44; - case 2502: - return 45; - case 2503: - return 46; - } - - case 2015: - - switch (classID) { - case 2500: - return 47; - case 2502: - return 48; - case 2503: - return 49; - - } - - case 2016: - - switch (classID) { - case 2500: - return 50; - case 2502: - return 51; - case 2503: - return 52; - - } - - case 2017: - - switch (classID) { - case 2500: - return 53; - case 2501: - return 54; - - } - - case 2025: - - switch (classID) { - case 2500: - return 55; - case 2501: - return 56; - case 2502: - return 57; - case 2503: - return 58; - } - - case 2026: - - switch (classID) { - case 2500: - return 59; - case 2501: - return 60; - case 2502: - return 61; - case 2503: - return 62; - } - - case 2027: - - switch (classID) { - case 2500: - return 63; - } - - case 2028: - - switch (classID) { - case 2500: - return 64; - - case 2502: - return 65; - case 2503: - return 66; - } - - case 2029: - - switch (classID) { - case 2500: - return 67; - - case 2502: - return 68; - case 2503: - return 69; - } - - - } - return -1; + return null; } - public int getRaceBaseClassID() { - return raceBaseClassID; + private void putColumn(EquipSlotType slot, int itemID) { + + if (itemID == 0) + return; + + this.items.put(slot, itemID); + Kit.NoobGearIDS.put(itemID, true); } public byte getKitNumber() { return kitNumber; } - public int getLegs() { - return legs; - } - - public int getChest() { - return chest; - } - - public int getFeet() { - return feet; - } - - public int getOffhand() { - return offhand; - } - - public int getWeapon() { - return weapon; - } - public void equipPCwithKit(PlayerCharacter pc) { - if (weapon != 0) - kitItemCreator(pc, weapon, mbEnums.EquipSlotType.RHELD); - if (offhand != 0) - kitItemCreator(pc, offhand, mbEnums.EquipSlotType.LHELD); - if (chest != 0) - kitItemCreator(pc, chest, mbEnums.EquipSlotType.CHEST); - if (legs != 0) - kitItemCreator(pc, legs, mbEnums.EquipSlotType.LEGS); - if (feet != 0) - kitItemCreator(pc, feet, mbEnums.EquipSlotType.FEET); + for (Map.Entry entry : this.items.entrySet()) + kitItemCreator(pc, entry.getValue(), entry.getKey()); } @Override diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index d97c1605..7539d715 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -1100,18 +1100,7 @@ public class PlayerCharacter extends AbstractCharacter { int kitID = msg.getKit(); - // get the correctKit - int raceClassID = Kit.GetKitIDByRaceClass(raceID, baseClassID); - ArrayList allKits = Kit.RaceClassIDMap.get(raceClassID); - - Kit kit = null; - - for (Kit k : allKits) { - if (k.getKitNumber() == kitID) { - kit = k; - break; - } - } + Kit kit = Kit.getKit(raceID, baseClassID, kitID); if (kit == null) { return refuseCreation(a, clientConnection, "Unable to find matching kitID: " + kitID); diff --git a/src/engine/server/login/LoginServer.java b/src/engine/server/login/LoginServer.java index c582ebbf..55a5b291 100644 --- a/src/engine/server/login/LoginServer.java +++ b/src/engine/server/login/LoginServer.java @@ -390,7 +390,7 @@ public class LoginServer { Blueprint.loadAllBlueprints(); Logger.info("Loading Kits"); - DbManager.KitQueries.GET_ALL_KITS(); + Kit.LoadAllKits(); Logger.info("Initializing Race data"); mbEnums.RaceType.initRaceTypeTables(); diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index dee3c224..c5b5a880 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -466,7 +466,7 @@ public class WorldServer { RealmMap.loadRealmImageMap(); Logger.info("Loading Kits"); - DbManager.KitQueries.GET_ALL_KITS(); + Kit.LoadAllKits(); Logger.info("Loading World Grid"); WorldGrid.InitializeGridObjects();