diff --git a/src/engine/db/handlers/dbItemBaseHandler.java b/src/engine/db/handlers/dbItemBaseHandler.java index 62e249d8..bf12b434 100644 --- a/src/engine/db/handlers/dbItemBaseHandler.java +++ b/src/engine/db/handlers/dbItemBaseHandler.java @@ -10,7 +10,6 @@ package engine.db.handlers; import engine.gameManager.DbManager; -import engine.objects.BootySetEntry; import engine.objects.ItemBase; import org.pmw.tinylog.Logger; @@ -136,41 +135,4 @@ public class dbItemBaseHandler extends dbHandlerBase { return runeSets; } - public HashMap> LOAD_BOOTY_FOR_MOBS() { - - HashMap> bootySets = new HashMap<>(); - BootySetEntry bootySetEntry; - int bootySetID; - int recordsRead = 0; - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_bootySet")) { - - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) { - - recordsRead++; - - bootySetID = rs.getInt("bootySet"); - bootySetEntry = new BootySetEntry(rs); - - if (bootySets.get(bootySetID) == null) { - ArrayList bootyList = new ArrayList<>(); - bootyList.add(bootySetEntry); - bootySets.put(bootySetID, bootyList); - } else { - ArrayList bootyList = bootySets.get(bootySetID); - bootyList.add(bootySetEntry); - bootySets.put(bootySetID, bootyList); - } - } - } catch (SQLException e) { - Logger.error(e); - return bootySets; - } - - Logger.info("read: " + recordsRead + " cached: " + bootySets.size()); - return bootySets; - } } diff --git a/src/engine/db/handlers/dbLootHandler.java b/src/engine/db/handlers/dbLootHandler.java new file mode 100644 index 00000000..f44dfb3e --- /dev/null +++ b/src/engine/db/handlers/dbLootHandler.java @@ -0,0 +1,240 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + + +package engine.db.handlers; + +import engine.gameManager.DbManager; +import engine.loot.*; +import engine.objects.Item; +import org.pmw.tinylog.Logger; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; + +public class dbLootHandler extends dbHandlerBase { + + public dbLootHandler() { + + } + + public HashMap> LOAD_GEN_ITEM_TABLES() { + + HashMap> genTables = new HashMap<>(); + GenTableEntry genTableEntry; + + int genTableID; + int recordsRead = 0; + + try (Connection connection = DbManager.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_loot_gen`")) { + + ResultSet rs = preparedStatement.executeQuery(); + + while (rs.next()) { + + recordsRead++; + + genTableID = rs.getInt("genTable"); + genTableEntry = new GenTableEntry(rs); + + if (genTables.get(genTableID) == null) { + ArrayList genItemList = new ArrayList<>(); + genItemList.add(genTableEntry); + genTables.put(genTableID, genItemList); + } else { + ArrayList genItemList = genTables.get(genTableID); + genItemList.add(genTableEntry); + genTables.put(genTableID, genItemList); + } + } + } catch (SQLException e) { + Logger.error(e); + return genTables; + } + + Logger.info("read: " + recordsRead + " cached: " + genTables.size()); + return genTables; + } + + public HashMap> LOAD_ITEM_TABLES() { + + HashMap> itemTables = new HashMap<>(); + ItemTableEntry itemTableEntry; + + int itemTableID; + int recordsRead = 0; + + try (Connection connection = DbManager.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_loot_item`")) { + + ResultSet rs = preparedStatement.executeQuery(); + + while (rs.next()) { + + recordsRead++; + + itemTableID = rs.getInt("itemTable"); + itemTableEntry = new ItemTableEntry(rs); + + if (itemTables.get(itemTableID) == null) { + ArrayList itemTableList = new ArrayList<>(); + itemTableList.add(itemTableEntry); + itemTables.put(itemTableID, itemTableList); + } else { + ArrayList itemTableList = itemTables.get(itemTableID); + itemTableList.add(itemTableEntry); + itemTables.put(itemTableID, itemTableList); + } + } + } catch (SQLException e) { + Logger.error(e); + return itemTables; + } + + Logger.info("read: " + recordsRead + " cached: " + itemTables.size()); + return itemTables; + } + + public HashMap> LOAD_MOD_TABLES() { + + HashMap> modTables = new HashMap<>(); + ModTableEntry modTableEntry; + + int modTableID; + int recordsRead = 0; + + try (Connection connection = DbManager.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_loot_mod`")) { + + ResultSet rs = preparedStatement.executeQuery(); + + while (rs.next()) { + + recordsRead++; + + modTableID = rs.getInt("modTable"); + modTableEntry = new ModTableEntry(rs); + + if (modTables.get(modTableID) == null) { + ArrayList modTableList = new ArrayList<>(); + modTableList.add(modTableEntry); + modTables.put(modTableID, modTableList); + } else { + ArrayList modTableList = modTables.get(modTableID); + modTableList.add(modTableEntry); + modTables.put(modTableID, modTableList); + } + } + } catch (SQLException e) { + Logger.error(e); + return modTables; + } + + Logger.info("read: " + recordsRead + " cached: " + modTables.size()); + return modTables; + } + + public HashMap> LOAD_MOD_TYPE_TABLES() { + + HashMap> modTypeTables = new HashMap<>(); + ModTypeTableEntry modTypeTableEntry; + + int modTableID; + int recordsRead = 0; + + try (Connection connection = DbManager.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_loot_modtype`")) { + + ResultSet rs = preparedStatement.executeQuery(); + + while (rs.next()) { + + recordsRead++; + + modTableID = rs.getInt("modType"); + modTypeTableEntry = new ModTypeTableEntry(rs); + + if (modTypeTables.get(modTableID) == null) { + ArrayList modTypeTableList = new ArrayList<>(); + modTypeTableList.add(modTypeTableEntry); + modTypeTables.put(modTableID, modTypeTableList); + } else { + ArrayList modTypeTableList = modTypeTables.get(modTableID); + modTypeTableList.add(modTypeTableEntry); + modTypeTables.put(modTableID, modTypeTableList); + } + } + } catch (SQLException e) { + Logger.error(e); + return modTypeTables; + } + + Logger.info("read: " + recordsRead + " cached: " + modTypeTables.size()); + return modTypeTables; + } + + public HashMap> LOAD_BOOTY_TABLES() { + + HashMap> bootySets = new HashMap<>(); + BootySetEntry bootySetEntry; + int bootySetID; + int recordsRead = 0; + + try (Connection connection = DbManager.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_bootySet")) { + + ResultSet rs = preparedStatement.executeQuery(); + + while (rs.next()) { + + recordsRead++; + + bootySetID = rs.getInt("bootySet"); + bootySetEntry = new BootySetEntry(rs); + + if (bootySets.get(bootySetID) == null) { + ArrayList bootyList = new ArrayList<>(); + bootyList.add(bootySetEntry); + bootySets.put(bootySetID, bootyList); + } else { + ArrayList bootyList = bootySets.get(bootySetID); + bootyList.add(bootySetEntry); + bootySets.put(bootySetID, bootyList); + } + } + } catch (SQLException e) { + Logger.error(e); + return bootySets; + } + + Logger.info("read: " + recordsRead + " cached: " + bootySets.size()); + return bootySets; + } + + public void LOAD_ENCHANT_VALUES() { + + try (Connection connection = DbManager.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement("SELECT `IDString`, `minMod` FROM `static_power_effectmod` WHERE `modType` = ?")) { + + preparedStatement.setString(1, "Value"); + ResultSet rs = preparedStatement.executeQuery(); + + while (rs.next()) + Item.addEnchantValue(rs.getString("IDString"), rs.getInt("minMod")); + + } catch (SQLException e) { + Logger.error(e); + } + } + +} diff --git a/src/engine/db/handlers/dbLootTableHandler.java b/src/engine/db/handlers/dbLootTableHandler.java deleted file mode 100644 index 02854cb9..00000000 --- a/src/engine/db/handlers/dbLootTableHandler.java +++ /dev/null @@ -1,215 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2022 -// www.magicbane.com - - -package engine.db.handlers; - -import engine.gameManager.DbManager; -import engine.loot.LootManager; -import engine.objects.Item; -import engine.objects.LootTable; -import org.pmw.tinylog.Logger; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -public class dbLootTableHandler extends dbHandlerBase { - - public dbLootTableHandler() { - - } - - public void populateLootGroups() { - - int recordsRead = 0; - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT `groupID`, `minRoll`, `maxRoll`, `lootTableID`, `pModTableID`, `sModTableID` FROM `static_lootgroups`")) { - - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) { - recordsRead++; - LootTable lootTable = LootTable.getLootGroup(rs.getInt("groupID")); - lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("lootTableID"), rs.getInt("pModTableID"), rs.getInt("sModTableID"), ""); - } - - } catch (SQLException e) { - Logger.error(e); - } - - Logger.info("read: " + recordsRead + " cached: " + LootTable.getLootGroups().size()); - } - - public void populateLootTables() { - - int recordsRead = 0; - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT `lootTable`, `minRoll`, `maxRoll`, `itemBaseUUID`, `minSpawn`, `maxSpawn` FROM `static_loottables`")) { - - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) { - recordsRead++; - LootTable lootTable = LootTable.getLootTable(rs.getInt("lootTable")); - lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("itemBaseUUID"), rs.getInt("minSpawn"), rs.getInt("maxSpawn"), ""); - } - - } catch (SQLException e) { - Logger.error(e); - } - - Logger.info("read: " + recordsRead + " cached: " + LootTable.getLootTables().size()); - } - - public void populateModTables() { - - int recordsRead = 0; - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT `modTable`,`minRoll`,`maxRoll`,`value`,`action` FROM `static_modtables`")) { - - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) { - recordsRead++; - LootTable lootTable = LootTable.getModTable(rs.getInt("modTable")); - lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("value"), 0, 0, rs.getString("action")); - } - - } catch (SQLException e) { - Logger.error(e); - } - - Logger.info("read: " + recordsRead + " cached: " + LootTable.getModTables().size()); - } - - public void populateModGroups() { - - int recordsRead = 0; - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT `modGroup`,`minRoll`,`maxRoll`,`subTableID` FROM `static_modgroups`")) { - - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) { - recordsRead++; - LootTable lootTable = LootTable.getModGroup(rs.getInt("modGroup")); - lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("subTableID"), 0, 0, ""); - } - - } catch (SQLException e) { - Logger.error(e); - } - - Logger.info("read: " + recordsRead + " cached: " + LootTable.getModGroups().size()); - } - - public void LOAD_ENCHANT_VALUES() { - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT `IDString`, `minMod` FROM `static_power_effectmod` WHERE `modType` = ?")) { - - preparedStatement.setString(1, "Value"); - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) - Item.addEnchantValue(rs.getString("IDString"), rs.getInt("minMod")); - - } catch (SQLException e) { - Logger.error(e); - } - } - - public void LOAD_ALL_LOOTGROUPS() { - - int recordsRead = 0; - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_lootgroups")) { - - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) { - LootManager.GenTableRow row = new LootManager.GenTableRow(rs); - LootManager.AddGenTableRow(rs.getInt("groupID"), row); - } - - } catch (SQLException e) { - Logger.error(e); - } - - Logger.info("read: " + recordsRead); - } - - public void LOAD_ALL_LOOTTABLES() { - - int recordsRead = 0; - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_loottables")) { - - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) { - recordsRead++; - LootManager.ItemTableRow row = new LootManager.ItemTableRow(rs); - LootManager.AddItemTableRow(rs.getInt("lootTable"), row); - } - - } catch (SQLException e) { - Logger.error(e); - } - - Logger.info("read: " + recordsRead); - } - - public void LOAD_ALL_MODGROUPS() { - int recordsRead = 0; - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_modgroups")) { - - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) { - recordsRead++; - LootManager.ModTypeTableRow mttr = new LootManager.ModTypeTableRow(rs); - LootManager.AddModTypeTableRow(rs.getInt("modGroup"), mttr); - } - - } catch (SQLException e) { - Logger.error(e); - } - Logger.info("read: " + recordsRead); - } - - public void LOAD_ALL_MODTABLES() { - int recordsRead = 0; - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_modtables")) { - - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) { - recordsRead++; - LootManager.ModTableRow mtr = new LootManager.ModTableRow(rs); - LootManager.AddModTableRow(rs.getInt("modTable"), mtr); - } - - } catch (SQLException e) { - Logger.error(e); - } - Logger.info("read: " + recordsRead); - } -} diff --git a/src/engine/devcmd/cmds/GetMobBaseLoot.java b/src/engine/devcmd/cmds/GetMobBaseLoot.java deleted file mode 100644 index edd450a6..00000000 --- a/src/engine/devcmd/cmds/GetMobBaseLoot.java +++ /dev/null @@ -1,58 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2022 -// www.magicbane.com - - -package engine.devcmd.cmds; - -import engine.Enum.GameObjectType; -import engine.devcmd.AbstractDevCmd; -import engine.objects.AbstractGameObject; -import engine.objects.Mob; -import engine.objects.MobLootBase; -import engine.objects.PlayerCharacter; - -/** - * @author Eighty - */ -public class GetMobBaseLoot extends AbstractDevCmd { - - public GetMobBaseLoot() { - super("mobbaseloot"); - } - - @Override - protected void _doCmd(PlayerCharacter pc, String[] words, - AbstractGameObject target) { - if (target.getObjectType() != GameObjectType.Mob) { - this.throwbackError(pc, "Must be targeting a Valid Mob For this Command."); - return; - } - - - Mob mob = (Mob) target; - for (MobLootBase mlb : MobLootBase.MobLootSet.get(mob.getMobBase().getLoadID())) { - - this.throwbackInfo(pc, "LootTable11 = " + mlb.getLootTableID() + "\rn "); - this.throwbackInfo(pc, "Chance = " + mlb.getChance() + "\rn "); - - } - - - } - - @Override - protected String _getHelpString() { - return "Copies a Mob of type 'mobID' with optional new name"; - } - - @Override - protected String _getUsageString() { - return "' /mob mobID [name]'"; - } - -} diff --git a/src/engine/devcmd/cmds/MBDropCmd.java b/src/engine/devcmd/cmds/MBDropCmd.java deleted file mode 100644 index 5e5bfbe8..00000000 --- a/src/engine/devcmd/cmds/MBDropCmd.java +++ /dev/null @@ -1,132 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2022 -// www.magicbane.com - - -package engine.devcmd.cmds; - -import engine.devcmd.AbstractDevCmd; -import engine.objects.AbstractGameObject; -import engine.objects.ItemBase; -import engine.objects.LootTable; -import engine.objects.PlayerCharacter; - -/** - * @author Eighty - */ -public class MBDropCmd extends AbstractDevCmd { - - public MBDropCmd() { - super("mbdrop"); - } - - @Override - protected void _doCmd(PlayerCharacter pcSender, String[] args, - AbstractGameObject target) { - String newline = "\r\n "; - if (args.length != 1) { - this.sendUsage(pcSender); - this.sendHelp(pcSender); - return; - } - - String output = ""; - switch (args[0].toLowerCase()) { - case "clear": - - LootTable.contractCount = 0; - LootTable.dropCount = 0; - LootTable.glassCount = 0; - LootTable.runeCount = 0; - LootTable.rollCount = 0; - LootTable.resourceCount = 0; - - LootTable.contractDroppedMap.clear(); - LootTable.glassDroppedMap.clear(); - LootTable.itemsDroppedMap.clear(); - LootTable.resourceDroppedMap.clear(); - LootTable.runeDroppedMap.clear(); - break; - case "all": - output = LootTable.dropCount + " items - ITEM NAME : DROP COUNT" + newline; - for (ItemBase ib : LootTable.itemsDroppedMap.keySet()) { - - int dropCount = LootTable.itemsDroppedMap.get(ib); - output += ib.getName() + " : " + dropCount + newline; - - } - break; - case "resource": - output = LootTable.resourceCount + " Resources - ITEM NAME : DROP COUNT" + newline; - for (ItemBase ib : LootTable.resourceDroppedMap.keySet()) { - - int dropCount = LootTable.resourceDroppedMap.get(ib); - output += ib.getName() + " : " + dropCount + newline; - - } - - break; - case "rune": - - output = LootTable.runeCount + " Runes - ITEM NAME : DROP COUNT" + newline; - for (ItemBase ib : LootTable.runeDroppedMap.keySet()) { - - int dropCount = LootTable.runeDroppedMap.get(ib); - output += ib.getName() + " : " + dropCount + newline; - - } - break; - case "contract": - - output = LootTable.contractCount + " Contracts - ITEM NAME : DROP COUNT" + newline; - for (ItemBase ib : LootTable.contractDroppedMap.keySet()) { - - int dropCount = LootTable.contractDroppedMap.get(ib); - output += ib.getName() + " : " + dropCount + newline; - - - } - break; - - case "glass": - - output = LootTable.glassCount + " Glass - ITEM NAME : DROP COUNT" + newline; - for (ItemBase ib : LootTable.glassDroppedMap.keySet()) { - - int dropCount = LootTable.glassDroppedMap.get(ib); - output += ib.getName() + " : " + dropCount + newline; - } - break; - - case "chance": - float chance = (float) LootTable.dropCount / (float) LootTable.rollCount * 100; - output = LootTable.dropCount + " out of " + LootTable.rollCount + " items Dropped. chance = " + chance + '%'; - - break; - - default: - this.sendUsage(pcSender); - this.sendHelp(pcSender); - return; - } - - this.throwbackInfo(pcSender, output); - - - } - - @Override - protected String _getUsageString() { - return "' /mbdrop all/resource/rune/contract/glass/chance/clear"; - } - - @Override - protected String _getHelpString() { - return "Lists drops for server since a reboot. All lists all items and drops. chance is the overall chance items drop from mobs on server. (not including Equipment)"; - } - -} diff --git a/src/engine/devcmd/cmds/SimulateBootyCmd.java b/src/engine/devcmd/cmds/SimulateBootyCmd.java new file mode 100644 index 00000000..a6696881 --- /dev/null +++ b/src/engine/devcmd/cmds/SimulateBootyCmd.java @@ -0,0 +1,156 @@ +package engine.devcmd.cmds; + +import engine.devcmd.AbstractDevCmd; +import engine.gameManager.LootManager; +import engine.gameManager.NPCManager; +import engine.gameManager.ZoneManager; +import engine.loot.BootySetEntry; +import engine.objects.*; + +import java.util.ArrayList; +import java.util.concurrent.ThreadLocalRandom; + +public class SimulateBootyCmd extends AbstractDevCmd { + public SimulateBootyCmd() { + super("bootysim"); + } + + @Override + protected void _doCmd(PlayerCharacter playerCharacter, String[] words, + AbstractGameObject target) { + + if (playerCharacter == null) + return; + + String newline = "\r\n "; + + String output; + + output = "Booty Simulation:" + newline; + + Mob mob = (Mob) target; + output += "Name: " + mob.getName() + newline; + output += "Special Loot:" + newline; + + if (mob.bootySet != 0) { + for (BootySetEntry entry : NPCManager._bootySetMap.get(mob.bootySet)) { + ItemBase item = ItemBase.getItemBase(entry.itemBase); + if (item != null) { + output += "[" + entry.bootyType + "] " + item.getName() + " [Chance] " + entry.dropChance + newline; + } + } + } + + ArrayList GlassItems = new ArrayList(); + ArrayList Resources = new ArrayList(); + ArrayList Runes = new ArrayList(); + ArrayList Contracts = new ArrayList(); + ArrayList Offerings = new ArrayList(); + ArrayList OtherDrops = new ArrayList(); + ArrayList EquipmentDrops = new ArrayList(); + + int failures = 0; + int goldAmount = 0; + + for (int i = 0; i < 100; ++i) { + + try { + mob.loadInventory(); + for (Item lootItem : mob.getCharItemManager().getInventory()) { + switch (lootItem.getItemBase().getType()) { + case CONTRACT: //CONTRACT + Contracts.add(lootItem); + break; + case OFFERING: //OFFERING + Offerings.add(lootItem); + break; + case RESOURCE: //RESOURCE + Resources.add(lootItem); + break; + case RUNE: //RUNE + Runes.add(lootItem); + break; + case WEAPON: //WEAPON + if (lootItem.getItemBase().isGlass()) + GlassItems.add(lootItem); + else + OtherDrops.add(lootItem); + break; + case GOLD: + goldAmount += lootItem.getNumOfItems(); + break; + default: + OtherDrops.add(lootItem); + break; + } + } + } catch (Exception ex) { + failures++; + } + if (mob.getEquip() != null) { + for (MobEquipment me : mob.getEquip().values()) { + + if (me.getDropChance() == 0) + continue; + + float equipmentRoll = ThreadLocalRandom.current().nextInt(99) + 1; + float dropChance = me.getDropChance() * 100; + + if (equipmentRoll > (dropChance)) + continue; + + MobLoot ml = new MobLoot(mob, me.getItemBase(), false); + + if (ml != null) + EquipmentDrops.add(ml); + } + } + } + output += "MobBase BootySet: " + mob.getMobBase().bootySet + newline; + output += "Mob BootySet: " + mob.bootySet + newline; + output += "Tables Rolled On: " + newline; + + boolean hotZoneRan = false; + float dropRate = 1.0f; + + if (ZoneManager.inHotZone(mob.getLoc())) + dropRate = LootManager.HOTZONE_DROP_RATE; + else + dropRate = LootManager.NORMAL_DROP_RATE; + + for (BootySetEntry entry : NPCManager._bootySetMap.get(mob.getMobBase().bootySet)) { + + if (entry.bootyType.equals("GOLD")) + output += "NORMAL TABLE [" + entry.bootyType + "] " + entry.genTable + ": " + entry.dropChance + newline; + else + output += "NORMAL TABLE [" + entry.bootyType + "] " + entry.genTable + ": " + entry.dropChance * dropRate + newline; + + if (hotZoneRan == false && ZoneManager.inHotZone(mob.getLoc()) && LootManager._genTables.containsKey(entry.genTable + 1)) { + output += "HOTZONE TABLE [" + entry.bootyType + "] " + (entry.genTable + 1) + ": " + entry.dropChance * dropRate + newline; + hotZoneRan = true; + } + } + + output += "GLASS DROPS: " + GlassItems.size() + newline; + output += "RUNE DROPS: " + Runes.size() + newline; + output += "CONTRACTS DROPS: " + Contracts.size() + newline; + output += "RESOURCE DROPS: " + Resources.size() + newline; + output += "OFFERINGS DROPPED: " + Offerings.size() + newline; + output += "ENCHANTED ITEMS DROPPED: " + OtherDrops.size() + newline; + output += "TOTAL GOLD DROPPED: " + goldAmount + newline; + output += "EQUIPMENT DROPPED: " + EquipmentDrops.size() + newline; + output += "FAILED ROLLS: " + failures + newline; + + throwbackInfo(playerCharacter, output); + } + + @Override + protected String _getHelpString() { + return "Simulates loot drops"; + } + + @Override + protected String _getUsageString() { + return "'/bootysim targetID'"; + } +} diff --git a/src/engine/devcmd/cmds/simulateBootyCmd.java b/src/engine/devcmd/cmds/simulateBootyCmd.java deleted file mode 100644 index ac51788e..00000000 --- a/src/engine/devcmd/cmds/simulateBootyCmd.java +++ /dev/null @@ -1,168 +0,0 @@ -package engine.devcmd.cmds; - -import engine.Enum; -import engine.devcmd.AbstractDevCmd; -import engine.gameManager.BuildingManager; -import engine.gameManager.NPCManager; -import engine.objects.*; - -import java.util.ArrayList; - -public class simulateBootyCmd extends AbstractDevCmd { - public simulateBootyCmd() { - super("simulatebooty"); - } - - @Override - protected void _doCmd(PlayerCharacter pc, String[] words, - AbstractGameObject target) { - // Arg Count Check - if (words.length != 1) { - this.sendUsage(pc); - return; - } - if (pc == null) { - return; - } - - String newline = "\r\n "; - - try { - int targetID = Integer.parseInt(words[0]); - Building b = BuildingManager.getBuilding(targetID); - if (b == null) - throwbackError(pc, "Building with ID " + targetID - + " not found"); - else - target = b; - } catch (Exception e) { - } - - if (target == null) { - throwbackError(pc, "Target is unknown or of an invalid type." - + newline + "Type ID: 0x" - + pc.getLastTargetType().toString() - + " Table ID: " + pc.getLastTargetID()); - return; - } - - - Enum.GameObjectType objType = target.getObjectType(); - int objectUUID = target.getObjectUUID(); - String output; - - output = "Booty Simulation:" + newline; - - switch (objType) { - case Building: - - break; - case PlayerCharacter: - - break; - - case NPC: - - break; - - case Mob: - Mob mob = (Mob) target; - output += "Name: " + mob.getName() + newline; - int max = (int)(4.882 * mob.level + 127.0); - if(max > 320){ - max = 320; - } - int min = (int)(4.469 * mob.level - 3.469); - output += "Roll Range: " + min + " - " + max + newline; - output += "Special Loot:" + newline; - if (mob.bootySet != 0) { - for (BootySetEntry entry : NPCManager._bootySetMap.get(mob.bootySet)) { - ItemBase item = ItemBase.getItemBase(entry.itemBase); - if (item != null) { - output += "[" + entry.bootyType + "] " + item.getName() + " [Chance] " + entry.dropChance + newline; - } - } - } - ArrayList GlassItems = new ArrayList(); - ArrayList Resources = new ArrayList(); - ArrayList Runes = new ArrayList(); - ArrayList Contracts = new ArrayList(); - ArrayList Offerings = new ArrayList(); - ArrayList OtherDrops = new ArrayList(); - int failures = 0; - for (int i = 0; i < 100; ++i) { - - try { - mob.loadInventory(); - for (Item lootItem : mob.getCharItemManager().getInventory()) { - switch (lootItem.getItemBase().getType()) { - case CONTRACT: //CONTRACT - Contracts.add(lootItem); - break; - case OFFERING: //OFFERING - Offerings.add(lootItem); - break; - case RESOURCE: //RESOURCE - Resources.add(lootItem); - break; - case RUNE: //RUNE - Runes.add(lootItem); - break; - case WEAPON: //WEAPON - if (lootItem.getItemBase().isGlass()) { - GlassItems.add(lootItem); - } else { - OtherDrops.add(lootItem); - if (lootItem.getName().toLowerCase().contains("crimson") || lootItem.getName().toLowerCase().contains("vorgrim") || lootItem.getName().toLowerCase().contains("bell")) { - output += lootItem.getName() + newline; - } - } - break; - default: - OtherDrops.add(lootItem); - if (lootItem.getName().toLowerCase().contains("crimson") || lootItem.getName().toLowerCase().contains("vorgrim") || lootItem.getName().toLowerCase().contains("bell")) { - output += lootItem.getName() + newline; - } - break; - } - } - } catch (Exception ex) { - failures++; - } - } - int respawnTime = mob.getMobBase().getSpawnTime(); - if (mob.spawnTime > 0) { - respawnTime = mob.spawnTime; - } - output += "MobBase BootySet: " + mob.getMobBase().bootySet + newline; - output += "Mob BootySet: " + mob.bootySet + newline; - output += "Tables Rolled On: " + newline; - for (BootySetEntry entry : NPCManager._bootySetMap.get(mob.getMobBase().bootySet)) { - output += "[" + entry.bootyType + "] " + entry.lootTable + newline; - } - output += "Time Required To Gain Simulated Booty: " + respawnTime * 100 + " Seconds" + newline; - output += "GLASS DROPS: " + GlassItems.size() + newline; - output += "RUNE DROPS: " + Runes.size() + newline; - output += "CONTRACTS DROPS: " + Contracts.size() + newline; - for (Item contract : Contracts){ - output += contract.getName() + newline; - } - output += "RESOURCE DROPS: " + Resources.size() + newline; - output += "OFFERINGS DROPPED: " + Offerings.size() + newline; - output += "OTHER ITEMS DROPPED: " + OtherDrops.size() + newline; - output += "FAILED ROLLS: " + failures + newline; - break; - } - throwbackInfo(pc, output); - } - - @Override - protected String _getHelpString() { - return "Gets information on an Object."; - } - - @Override - protected String _getUsageString() { - return "' /info targetID'"; - } -} diff --git a/src/engine/gameManager/ConfigManager.java b/src/engine/gameManager/ConfigManager.java index 6cf0eeda..345158f8 100644 --- a/src/engine/gameManager/ConfigManager.java +++ b/src/engine/gameManager/ConfigManager.java @@ -70,8 +70,10 @@ public enum ConfigManager { //drop rates MB_NORMAL_EXP_RATE, MB_NORMAL_DROP_RATE, + MB_NORMAL_GOLD_RATE, MB_HOTZONE_EXP_RATE, MB_HOTZONE_DROP_RATE, + MB_HOTZONE_GOLD_RATE, MB_HOTZONE_DURATION, MB_HOTZONE_MIN_LEVEL, @@ -107,7 +109,6 @@ public enum ConfigManager { // Called at bootstrap: ensures that all config values are loaded. - public static boolean init() { Logger.info("Loading config from environment..."); diff --git a/src/engine/gameManager/DbManager.java b/src/engine/gameManager/DbManager.java index a2e2522f..25792846 100644 --- a/src/engine/gameManager/DbManager.java +++ b/src/engine/gameManager/DbManager.java @@ -49,7 +49,7 @@ public enum DbManager { public static final dbItemHandler ItemQueries = new dbItemHandler(); public static final dbItemBaseHandler ItemBaseQueries = new dbItemBaseHandler(); public static final dbKitHandler KitQueries = new dbKitHandler(); - public static final dbLootTableHandler LootQueries = new dbLootTableHandler(); + public static final dbLootHandler LootQueries = new dbLootHandler(); public static final dbMenuHandler MenuQueries = new dbMenuHandler(); public static final dbMineHandler MineQueries = new dbMineHandler(); public static final dbMobHandler MobQueries = new dbMobHandler(); diff --git a/src/engine/gameManager/DevCmdManager.java b/src/engine/gameManager/DevCmdManager.java index d9a37b29..47ae6cda 100644 --- a/src/engine/gameManager/DevCmdManager.java +++ b/src/engine/gameManager/DevCmdManager.java @@ -57,7 +57,7 @@ public enum DevCmdManager { DevCmdManager.registerDevCmd(new PrintLocationCmd()); DevCmdManager.registerDevCmd(new InfoCmd()); DevCmdManager.registerDevCmd(new aiInfoCmd()); - DevCmdManager.registerDevCmd(new simulateBootyCmd()); + DevCmdManager.registerDevCmd(new SimulateBootyCmd()); DevCmdManager.registerDevCmd(new GetHeightCmd()); // Tester @@ -128,8 +128,6 @@ public enum DevCmdManager { DevCmdManager.registerDevCmd(new SetForceRenameCityCmd()); DevCmdManager.registerDevCmd(new GotoObj()); DevCmdManager.registerDevCmd(new convertLoc()); - DevCmdManager.registerDevCmd(new GetMobBaseLoot()); - DevCmdManager.registerDevCmd(new MBDropCmd()); DevCmdManager.registerDevCmd(new AuditHeightMapCmd()); DevCmdManager.registerDevCmd(new UnloadFurnitureCmd()); DevCmdManager.registerDevCmd(new SetNpcEquipSetCmd()); diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java new file mode 100644 index 00000000..56b19d59 --- /dev/null +++ b/src/engine/gameManager/LootManager.java @@ -0,0 +1,370 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + +package engine.gameManager; + +import engine.Enum; +import engine.loot.*; +import engine.net.DispatchMessage; +import engine.net.client.msg.chat.ChatSystemMsg; +import engine.objects.*; +import org.pmw.tinylog.Logger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Class contains static methods for data from Magicbane's loot tables + */ +public enum LootManager { + + LOOTMANAGER; + + // Newer tables + + public static HashMap> _genTables = new HashMap<>(); + public static HashMap> _itemTables = new HashMap<>(); + public static HashMap> _modTables = new HashMap<>(); + public static HashMap> _modTypeTables = new HashMap<>(); + + // Drop Rates + + public static float NORMAL_DROP_RATE; + public static float NORMAL_EXP_RATE; + public static float NORMAL_GOLD_RATE; + public static float HOTZONE_DROP_RATE; + public static float HOTZONE_EXP_RATE; + public static float HOTZONE_GOLD_RATE; + + // Bootstrap routine to initialize the Loot Manager + + public static void init() { + + // Load loot tables from database. + + _genTables = DbManager.LootQueries.LOAD_GEN_ITEM_TABLES(); + _itemTables = DbManager.LootQueries.LOAD_ITEM_TABLES(); + _modTables = DbManager.LootQueries.LOAD_MOD_TABLES(); + _modTypeTables = DbManager.LootQueries.LOAD_MOD_TYPE_TABLES(); + + // Cache drop rate values from Config manager. + + NORMAL_DROP_RATE = Float.parseFloat(ConfigManager.MB_NORMAL_DROP_RATE.getValue()); + NORMAL_EXP_RATE = Float.parseFloat(ConfigManager.MB_NORMAL_EXP_RATE.getValue()); + NORMAL_GOLD_RATE = Float.parseFloat(ConfigManager.MB_NORMAL_GOLD_RATE.getValue()); + HOTZONE_DROP_RATE = Float.parseFloat(ConfigManager.MB_HOTZONE_DROP_RATE.getValue()); + HOTZONE_EXP_RATE = Float.parseFloat(ConfigManager.MB_HOTZONE_EXP_RATE.getValue()); + HOTZONE_GOLD_RATE = Float.parseFloat(ConfigManager.MB_HOTZONE_GOLD_RATE.getValue()); + + } + + public static void GenerateMobLoot(Mob mob, boolean fromDeath) { + + //determine if mob is in hotzone + + boolean inHotzone = ZoneManager.inHotZone(mob.getLoc()); + + //iterate the booty sets + + if (mob.getMobBase().bootySet != 0 && NPCManager._bootySetMap.containsKey(mob.getMobBase().bootySet) == true) + RunBootySet(NPCManager._bootySetMap.get(mob.getMobBase().bootySet), mob, inHotzone, fromDeath); + + if (mob.bootySet != 0 && NPCManager._bootySetMap.containsKey(mob.bootySet) == true) + RunBootySet(NPCManager._bootySetMap.get(mob.bootySet), mob, inHotzone, fromDeath); + + //lastly, check mobs inventory for godly or disc runes to send a server announcement + + if (!fromDeath) + for (Item it : mob.getInventory()) { + + ItemBase ib = it.getItemBase(); + + if (ib.isDiscRune() || ib.getName().toLowerCase().contains("of the gods")) { + ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?"); + chatMsg.setMessageType(10); + chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); + DispatchMessage.dispatchMsgToAll(chatMsg); + } + } + + } + + private static void RunBootySet(ArrayList entries, Mob mob, boolean inHotzone, boolean fromDeath) { + + boolean hotzoneWasRan = false; + float dropRate = LootManager.NORMAL_DROP_RATE; + + if (fromDeath) { + GenerateEquipmentDrop(mob); + return; + } + + // Iterate all entries in this bootySet and process accordingly + + for (BootySetEntry bse : entries) { + switch (bse.bootyType) { + case "GOLD": + GenerateGoldDrop(mob, bse, inHotzone); + break; + case "LOOT": + + if (inHotzone == true) + dropRate = LootManager.HOTZONE_DROP_RATE; + else + dropRate = LootManager.NORMAL_DROP_RATE; + + if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate)) + GenerateLootDrop(mob, bse.genTable, false); //generate normal loot drop + + // Generate hotzone loot if in hotzone + // Only one bite at the hotzone apple per bootyset. + + if (inHotzone == true && hotzoneWasRan == false) + if (_genTables.containsKey(bse.genTable + 1) && ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate)) { + GenerateLootDrop(mob, bse.genTable + 1, true); //generate loot drop from hotzone table + hotzoneWasRan = true; + } + + break; + case "ITEM": + GenerateInventoryDrop(mob, bse); + break; + } + } + } + + public static MobLoot getGenTableItem(int genTableID, Mob mob, Boolean inHotzone) { + + if (mob == null || _genTables.containsKey(genTableID) == false) + return null; + + MobLoot outItem; + + int genRoll = new Random().nextInt(99) + 1; + + GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll); + + if (selectedRow == null) + return null; + + int itemTableId = selectedRow.itemTableID; + + if (_itemTables.containsKey(itemTableId) == false) + return null; + + //gets the 1-320 roll for this mob + + int itemTableRoll = TableRoll(mob.level, inHotzone); + + ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, itemTableRoll); + + if (tableRow == null) + return null; + + int itemUUID = tableRow.cacheID; + + if (itemUUID == 0) + return null; + + if (ItemBase.getItemBase(itemUUID).getType().ordinal() == Enum.ItemType.RESOURCE.ordinal()) { + int amount = ThreadLocalRandom.current().nextInt(tableRow.maxSpawn - tableRow.minSpawn) + tableRow.minSpawn; + return new MobLoot(mob, ItemBase.getItemBase(itemUUID), amount, false); + } + + outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); + Enum.ItemType outType = outItem.getItemBase().getType(); + + if (outType.ordinal() == Enum.ItemType.WEAPON.ordinal() || outType.ordinal() == Enum.ItemType.ARMOR.ordinal() || outType.ordinal() == Enum.ItemType.JEWELRY.ordinal()) { + if (outItem.getItemBase().isGlass() == false) { + + try { + outItem = GeneratePrefix(mob, outItem, genTableID, genRoll, inHotzone); + } catch (Exception e) { + Logger.error("Failed to GeneratePrefix for item: " + outItem.getName()); + } + + try { + outItem = GenerateSuffix(mob, outItem, genTableID, genRoll, inHotzone); + } catch (Exception e) { + Logger.error("Failed to GenerateSuffix for item: " + outItem.getName()); + } + } + } + + if (outItem.getPrefix() != null && outItem.getPrefix().isEmpty() == false) + outItem.setIsID(false); + + if (outItem.getSuffix() != null && outItem.getSuffix().isEmpty() == false) + outItem.setIsID(false); + + return outItem; + } + + private static MobLoot GeneratePrefix(Mob mob, MobLoot inItem, int genTableID, int genRoll, Boolean inHotzone) { + + GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll); + + if (selectedRow == null) + return inItem; + + int prefixroll = ThreadLocalRandom.current().nextInt(1, 100 + 1); + + ModTypeTableEntry prefixTable = ModTypeTableEntry.rollTable(selectedRow.pModTable, prefixroll); + + if (prefixTable == null) + return inItem; + + ModTableEntry prefixMod = ModTableEntry.rollTable(prefixTable.modTableID, TableRoll(mob.level, inHotzone)); + + if (prefixMod == null) + return inItem; + + if (prefixMod.action.length() > 0) { + inItem.setPrefix(prefixMod.action); + inItem.addPermanentEnchantment(prefixMod.action, 0, prefixMod.level, true); + } + + return inItem; + } + + private static MobLoot GenerateSuffix(Mob mob, MobLoot inItem, int genTableID, int genRoll, Boolean inHotzone) { + + GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll); + + if (selectedRow == null) + return inItem; + + int suffixRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1); + + ModTypeTableEntry suffixTable = ModTypeTableEntry.rollTable(selectedRow.sModTable, suffixRoll); + + if (suffixTable == null) + return inItem; + + ModTableEntry suffixMod = ModTableEntry.rollTable(suffixTable.modTableID, TableRoll(mob.level, inHotzone)); + + if (suffixMod == null) + return inItem; + + if (suffixMod.action.length() > 0) { + inItem.setPrefix(suffixMod.action); + inItem.addPermanentEnchantment(suffixMod.action, 0, suffixMod.level, true); + } + + return inItem; + } + + public static int TableRoll(int mobLevel, Boolean inHotzone) { + + if (mobLevel > 65) + mobLevel = 65; + + int max = (int) (4.882 * mobLevel + 127.0); + + if (max > 319) + max = 319; + + int min = (int) (4.469 * mobLevel - 3.469); + + if (min < 70) + min = 70; + + if (inHotzone) + min += mobLevel; + + int roll = ThreadLocalRandom.current().nextInt(max - min) + min; + + return roll; + } + + public static void GenerateGoldDrop(Mob mob, BootySetEntry bse, Boolean inHotzone) { + + int chanceRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1); + + //early exit, failed to hit minimum chance roll + + if (chanceRoll > bse.dropChance) + return; + + //determine and add gold to mob inventory + + int high = bse.highGold; + int low = bse.lowGold; + int gold = ThreadLocalRandom.current().nextInt(high - low) + low; + + if (inHotzone == true) + gold = (int) (gold * HOTZONE_GOLD_RATE); + else + gold = (int) (gold * NORMAL_GOLD_RATE); + + if (gold > 0) { + MobLoot goldAmount = new MobLoot(mob, gold); + mob.getCharItemManager().addItemToInventory(goldAmount); + } + + } + + public static void GenerateLootDrop(Mob mob, int tableID, Boolean inHotzone) { + + try { + + MobLoot toAdd = getGenTableItem(tableID, mob, inHotzone); + + if (toAdd != null) + mob.getCharItemManager().addItemToInventory(toAdd); + + } catch (Exception e) { + //TODO chase down loot generation error, affects roughly 2% of drops + int i = 0; + } + } + + public static void GenerateEquipmentDrop(Mob mob) { + + //do equipment here + + if (mob.getEquip() != null) + for (MobEquipment me : mob.getEquip().values()) { + + if (me.getDropChance() == 0) + continue; + + float equipmentRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1); + float dropChance = me.getDropChance() * 100; + + if (equipmentRoll > dropChance) + continue; + + MobLoot ml = new MobLoot(mob, me.getItemBase(), false); + + if (ml != null) { + ml.setIsID(true); + ml.setDurabilityCurrent((short) (ml.getDurabilityCurrent() - ThreadLocalRandom.current().nextInt(5) + 1)); + mob.getCharItemManager().addItemToInventory(ml); + } + } + } + + public static void GenerateInventoryDrop(Mob mob, BootySetEntry bse) { + + int chanceRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1); + + //early exit, failed to hit minimum chance roll + + if (chanceRoll > bse.dropChance) + return; + + MobLoot lootItem = new MobLoot(mob, ItemBase.getItemBase(bse.itemBase), true); + + if (lootItem != null) + mob.getCharItemManager().addItemToInventory(lootItem); + } + +} diff --git a/src/engine/gameManager/NPCManager.java b/src/engine/gameManager/NPCManager.java index 448aa587..176e4278 100644 --- a/src/engine/gameManager/NPCManager.java +++ b/src/engine/gameManager/NPCManager.java @@ -2,6 +2,7 @@ package engine.gameManager; import engine.Enum; import engine.InterestManagement.WorldGrid; +import engine.loot.BootySetEntry; import engine.net.Dispatch; import engine.net.DispatchMessage; import engine.net.client.msg.PetMsg; @@ -24,7 +25,7 @@ public enum NPCManager { } public static void LoadAllBootySets() { - _bootySetMap = DbManager.ItemBaseQueries.LOAD_BOOTY_FOR_MOBS(); + _bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES(); } public static void applyRuneSetEffects(Mob mob) { diff --git a/src/engine/objects/BootySetEntry.java b/src/engine/loot/BootySetEntry.java similarity index 92% rename from src/engine/objects/BootySetEntry.java rename to src/engine/loot/BootySetEntry.java index ff22bbaf..d909a413 100644 --- a/src/engine/objects/BootySetEntry.java +++ b/src/engine/loot/BootySetEntry.java @@ -7,7 +7,7 @@ // www.magicbane.com -package engine.objects; +package engine.loot; import java.sql.ResultSet; import java.sql.SQLException; @@ -18,7 +18,7 @@ public class BootySetEntry { public int lowGold; public int highGold; public int itemBase; - public int lootTable; + public int genTable; public float dropChance; /** @@ -30,7 +30,7 @@ public class BootySetEntry { this.lowGold = (rs.getInt("lowGold")); this.highGold = (rs.getInt("highGold")); this.itemBase = (rs.getInt("itemBase")); - this.lootTable = (rs.getInt("lootTable")); + this.genTable = (rs.getInt("genTable")); this.dropChance = (rs.getFloat("dropChance")); } diff --git a/src/engine/loot/GenTableEntry.java b/src/engine/loot/GenTableEntry.java new file mode 100644 index 00000000..b7b3c625 --- /dev/null +++ b/src/engine/loot/GenTableEntry.java @@ -0,0 +1,45 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + +package engine.loot; + +import engine.gameManager.LootManager; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class GenTableEntry { + public int minRoll; + public int maxRoll; + public int itemTableID; + public int pModTable; + public int sModTable; + + public GenTableEntry(ResultSet rs) throws SQLException { + this.minRoll = rs.getInt("minRoll"); + this.maxRoll = rs.getInt("maxRoll"); + this.itemTableID = rs.getInt("itemTableID"); + this.pModTable = rs.getInt("pModTableID"); + this.sModTable = rs.getInt("sModTableID"); + } + + public static GenTableEntry rollTable(int genTable, int roll) { + + GenTableEntry genTableEntry = null; + List genTableEntryList; + + genTableEntryList = LootManager._genTables.get(genTable); + + for (GenTableEntry iteration : genTableEntryList) + if (roll >= iteration.minRoll && roll <= iteration.maxRoll) + genTableEntry = iteration; + + return genTableEntry; + } +} diff --git a/src/engine/loot/ItemTableEntry.java b/src/engine/loot/ItemTableEntry.java new file mode 100644 index 00000000..9147f217 --- /dev/null +++ b/src/engine/loot/ItemTableEntry.java @@ -0,0 +1,45 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + +package engine.loot; + +import engine.gameManager.LootManager; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class ItemTableEntry { + public int minRoll; + public int maxRoll; + public int cacheID; + public int minSpawn; + public int maxSpawn; + + public ItemTableEntry(ResultSet rs) throws SQLException { + this.minRoll = rs.getInt("minRoll"); + this.maxRoll = rs.getInt("maxRoll"); + this.cacheID = rs.getInt("itemBaseUUID"); + this.minSpawn = rs.getInt("minSpawn"); + this.maxSpawn = rs.getInt("maxSpawn"); + } + + public static ItemTableEntry rollTable(int itemTable, int roll) { + + ItemTableEntry itemTableEntry = null; + List itemTableEntryList; + + itemTableEntryList = LootManager._itemTables.get(itemTable); + + for (ItemTableEntry iteration : itemTableEntryList) + if (roll >= iteration.minRoll && roll <= iteration.maxRoll) + itemTableEntry = iteration; + + return itemTableEntry; + } +} diff --git a/src/engine/loot/LootManager.java b/src/engine/loot/LootManager.java deleted file mode 100644 index b2de6c0a..00000000 --- a/src/engine/loot/LootManager.java +++ /dev/null @@ -1,446 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2022 -// www.magicbane.com - -package engine.loot; - -import engine.Enum; -import engine.gameManager.ConfigManager; -import engine.gameManager.DbManager; -import engine.gameManager.NPCManager; -import engine.gameManager.ZoneManager; -import engine.net.DispatchMessage; -import engine.net.client.msg.chat.ChatSystemMsg; -import engine.objects.*; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; - -/** - * Class contains static methods for data from Magicbane's loot tables - */ -public class LootManager { - - //new tables - private static final HashMap generalItemTables = new HashMap<>(); - private static final HashMap itemTables = new HashMap<>(); - private static final HashMap modTypeTables = new HashMap<>(); - private static final HashMap modTables = new HashMap<>(); - - private LootManager() { - } - - // Bootstrap routine to load loot data from database - public static void loadLootData() { - DbManager.LootQueries.LOAD_ALL_LOOTGROUPS(); - DbManager.LootQueries.LOAD_ALL_LOOTTABLES(); - DbManager.LootQueries.LOAD_ALL_MODGROUPS(); - DbManager.LootQueries.LOAD_ALL_MODTABLES(); - } - - public static void GenerateMobLoot(Mob mob, boolean fromDeath) { - //determine if mob is in hotzone - boolean inHotzone = ZoneManager.inHotZone(mob.getLoc()); - //get multiplier form config manager - float multiplier = Float.parseFloat(ConfigManager.MB_NORMAL_DROP_RATE.getValue()); - if (inHotzone) { - //if mob is inside hotzone, use the hotzone multiplier from the config instead - multiplier = Float.parseFloat(ConfigManager.MB_HOTZONE_DROP_RATE.getValue()); - } - //iterate the booty sets - if (mob.getMobBase().bootySet != 0 && NPCManager._bootySetMap.containsKey(mob.getMobBase().bootySet) == true) { - RunBootySet(NPCManager._bootySetMap.get(mob.getMobBase().bootySet), mob, multiplier, inHotzone, fromDeath); - } - if (mob.bootySet != 0 && NPCManager._bootySetMap.containsKey(mob.bootySet) == true) { - RunBootySet(NPCManager._bootySetMap.get(mob.bootySet), mob, multiplier, inHotzone, fromDeath); - } - //lastly, check mobs inventory for godly or disc runes to send a server announcement - if (!fromDeath) { - for (Item it : mob.getInventory()) { - ItemBase ib = it.getItemBase(); - if (ib.isDiscRune() || ib.getName().toLowerCase().contains("of the gods")) { - ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?"); - chatMsg.setMessageType(10); - chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); - DispatchMessage.dispatchMsgToAll(chatMsg); - } - - } - } - } - private static void RunBootySet(ArrayList entries, Mob mob, float multiplier, boolean inHotzone, boolean fromDeath) { - if (fromDeath) { - DropEquipment(mob,multiplier); - return; - } - for (BootySetEntry bse : entries) { - switch (bse.bootyType) { - case "GOLD": - GenerateGoldDrop(mob,bse,multiplier); - break; - case "LOOT": - GenerateNormalLootDrop(mob,bse,multiplier); - if (inHotzone && mob.level < 80) { - if (generalItemTables.containsKey(bse.lootTable + 1)) { - GenerateHotzoneLootDrop(mob, bse, multiplier); - } - } - if(mob.level > 80){ - RollForGlass(mob); - } - break; - case "ITEM": - GenerateItemLootDrop(mob,bse,multiplier); - break; - } - } - if(inHotzone){ - RollForGlass(mob); - } - } - public static MobLoot getGenTableItem(int genTableID, Mob mob) { - if (genTableID == 0 || mob == null || generalItemTables.containsKey(genTableID) == false) { - return null; - } - MobLoot outItem; - int genRoll = new Random().nextInt(100)+1; - GenTableRow selectedRow = generalItemTables.get(genTableID).getRowForRange(genRoll); - if (selectedRow == null) { - return null; - } - int itemTableId = selectedRow.itemTableID; - //gets the 1-320 roll for this mob - int roll2 = TableRoll(mob.level); - ItemTableRow tableRow = itemTables.get(itemTableId).getRowForRange(roll2); - if (tableRow == null) { - return null; - } - int itemUUID = tableRow.cacheID; - if (itemUUID == 0) { - return null; - } - if (ItemBase.getItemBase(itemUUID).getType().ordinal() == Enum.ItemType.RESOURCE.ordinal()) { - int amount = ThreadLocalRandom.current().nextInt(tableRow.maxSpawn - tableRow.minSpawn) + tableRow.minSpawn; - return new MobLoot(mob, ItemBase.getItemBase(itemUUID), amount, false); - } - outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); - Enum.ItemType outType = outItem.getItemBase().getType(); - if (outType.ordinal() == Enum.ItemType.WEAPON.ordinal() || outType.ordinal() == Enum.ItemType.ARMOR.ordinal() || outType.ordinal() == Enum.ItemType.JEWELRY.ordinal()) { - if (outItem.getItemBase().isGlass() == false) { - int prefixChanceRoll = ThreadLocalRandom.current().nextInt(100)+1; - double prefixChance = 2.057 * mob.level - 28.67; - if (prefixChanceRoll < prefixChance) { - ModTypeTable prefixTable = modTypeTables.get(selectedRow.pModTable); - - int prefixroll = ThreadLocalRandom.current().nextInt(100)+1; - if (modTables.get(prefixTable.getRowForRange(prefixroll).modTableID) != null) { - ModTable prefixModTable = modTables.get(prefixTable.getRowForRange(prefixroll).modTableID); - ModTableRow prefixMod = prefixModTable.getRowForRange(TableRoll(mob.level)); - if (prefixMod != null && prefixMod.action.length() > 0) { - outItem.setPrefix(prefixMod.action); - outItem.addPermanentEnchantment(prefixMod.action, 0, prefixMod.level, true); - } - } - } - int suffixChanceRoll = ThreadLocalRandom.current().nextInt(100)+1; - double suffixChance = 2.057 * mob.level - 28.67; - if (suffixChanceRoll < suffixChance) { - int suffixroll = ThreadLocalRandom.current().nextInt(100)+1; - ModTypeTable suffixTable = modTypeTables.get(selectedRow.sModTable); - if (modTables.get(suffixTable.getRowForRange(suffixroll).modTableID) != null) { - ModTable suffixModTable = modTables.get(suffixTable.getRowForRange(suffixroll).modTableID); - ModTableRow suffixMod = suffixModTable.getRowForRange(TableRoll(mob.level)); - if (suffixMod != null && suffixMod.action.length() > 0) { - outItem.setSuffix(suffixMod.action); - outItem.addPermanentEnchantment(suffixMod.action, 0, suffixMod.level, false); - } - } - } - } - } - return outItem; - } - private static int TableRoll(int mobLevel){ - if(mobLevel > 65){ - mobLevel = 65; - } - int max = (int)(4.882 * mobLevel + 127.0); - if(max > 321){ - max = 321; - } - int min = (int)(4.469 * mobLevel - 3.469); - int roll = ThreadLocalRandom.current().nextInt(max-min) + min; - return roll; - } - public static void GenerateGoldDrop(Mob mob, BootySetEntry bse, float multiplier){ - int chanceRoll = ThreadLocalRandom.current().nextInt(100) + 1; - if (chanceRoll > bse.dropChance) { - //early exit, failed to hit minimum chance roll OR booty was generated from mob's death - return; - } - //determine and add gold to mob inventory - int high = (int)(bse.highGold * multiplier); - int low = (int)(bse.lowGold * multiplier); - int gold = ThreadLocalRandom.current().nextInt(high - low) + low; - if (gold > 0) { - MobLoot goldAmount = new MobLoot(mob, (int) (gold * multiplier)); - mob.getCharItemManager().addItemToInventory(goldAmount); - } - } - public static void GenerateNormalLootDrop(Mob mob, BootySetEntry bse,float multiplier){ - try{ - int chanceRoll = ThreadLocalRandom.current().nextInt(100) + 1; - if (chanceRoll > bse.dropChance * multiplier) { - //early exit, failed to hit minimum chance roll - return; - } - //iterate the booty tables and add items to mob inventory - MobLoot toAdd = getGenTableItem(bse.lootTable, mob); - if (toAdd != null) { - if(toAdd.getPrefix() == null && toAdd.getSuffix() == null){ - toAdd.setIsID(true); - } - mob.getCharItemManager().addItemToInventory(toAdd); - } - } - catch(Exception e){ - //TODO chase down loot generation error, affects roughly 2% of drops - int i = 0; - } - } - public static void GenerateHotzoneLootDrop(Mob mob, BootySetEntry bse, float multiplier){ - int lootTableID = bse.lootTable + 1; - int chanceRoll = ThreadLocalRandom.current().nextInt(100) + 1; - if (chanceRoll > bse.dropChance * multiplier) { - //early exit, failed to hit minimum chance roll - return; - } - MobLoot toAdd = getGenTableItem(lootTableID, mob); - if (toAdd != null) { - if (toAdd.getPrefix() != null && toAdd.getPrefix().isEmpty() == true && toAdd.getSuffix() != null && toAdd.getSuffix().isEmpty() == true) { - toAdd.setIsID(true); - } - mob.getCharItemManager().addItemToInventory(toAdd); - } - } - public static void RollForGlass(Mob mob){ - int glassRoll = ThreadLocalRandom.current().nextInt(100) + 1; - if (glassRoll >= 99) { - int roll2 = TableRoll(mob.level); - if (itemTables.get(126).getRowForRange(roll2) == null) { - return; - } - ItemTableRow tableRow = itemTables.get(126).getRowForRange(roll2); - if (tableRow == null) { - return; - } - int itemUUID = tableRow.cacheID; - if (itemUUID == 0) { - return; - } - MobLoot toAddHZ = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); - if (toAddHZ != null) - mob.getCharItemManager().addItemToInventory(toAddHZ); - } - } - public static void DropEquipment(Mob mob, float multiplier){ - //do equipment here - if (mob.getEquip() != null) { - for (MobEquipment me : mob.getEquip().values()) { - if (me.getDropChance() == 0) - continue; - float equipmentRoll = ThreadLocalRandom.current().nextInt(101); - float dropChance = me.getDropChance() * 100; - if (equipmentRoll <= (dropChance * multiplier)) { - MobLoot ml = new MobLoot(mob, me.getItemBase(), false); - if (ml.getPrefix().isEmpty() == true && ml.getSuffix().isEmpty() == true) { - ml.setIsID(true); - } - mob.getCharItemManager().addItemToInventory(ml); - } - } - } - return; - } - public static void GenerateItemLootDrop(Mob mob, BootySetEntry bse, float multiplier){ - int chanceRoll = ThreadLocalRandom.current().nextInt(100) + 1; - if (chanceRoll > bse.dropChance * multiplier) { - //early exit, failed to hit minimum chance roll - return; - } - MobLoot disc = new MobLoot(mob, ItemBase.getItemBase(bse.itemBase), true); - if (disc != null) - mob.getCharItemManager().addItemToInventory(disc); - } - public static void AddGenTableRow(int tableID, GenTableRow row) { - if (!generalItemTables.containsKey(tableID)) { - //create the new table - GenTable gt = new GenTable(); - gt.rows.add(row); - generalItemTables.put(tableID, gt); - } else { - //add row to existing table - GenTable toAdd = generalItemTables.get(tableID); - toAdd.rows.add(row); - } - } - public static void AddItemTableRow(int tableID, ItemTableRow row) { - if (!itemTables.containsKey(tableID)) { - //create the new table - ItemTable it = new ItemTable(); - it.rows.add(row); - itemTables.put(tableID, it); - } else { - //add row to existing table - ItemTable toAdd = itemTables.get(tableID); - toAdd.rows.add(row); - } - } - public static void AddModTypeTableRow(int tableID, ModTypeTableRow row) { - if (!modTypeTables.containsKey(tableID)) { - //create the new table - ModTypeTable mtt = new ModTypeTable(); - mtt.rows.add(row); - modTypeTables.put(tableID, mtt); - } else { - //add row to existing table - ModTypeTable toAdd = modTypeTables.get(tableID); - toAdd.rows.add(row); - } - } - public static void AddModTableRow(int tableID, ModTableRow row) { - if (!modTables.containsKey(tableID)) { - //create the new table - ModTable mt = new ModTable(); - mt.rows.add(row); - modTables.put(tableID, mt); - } else { - //add row to existing table - ModTable toAdd = modTables.get(tableID); - toAdd.rows.add(row); - } - } - public static class GenTable { - public ArrayList rows = new ArrayList(); - - public GenTableRow getRowForRange(int roll) { - GenTableRow outRow = null; - for (GenTableRow iteration : this.rows) { - if (roll >= iteration.minRoll && roll <= iteration.maxRoll) { - outRow = iteration; - } - } - return outRow; - } - } - public static class ItemTable { - public ArrayList rows = new ArrayList(); - - public ItemTableRow getRowForRange(int roll) { - if (roll > 320) { - roll = 320; - } - ItemTableRow outRow = null; - for (ItemTableRow iteration : this.rows) { - if (roll >= iteration.minRoll && roll <= iteration.maxRoll) { - outRow = iteration; - } - } - return outRow; - } - } - public static class ModTypeTable { - public ArrayList rows = new ArrayList(); - - public ModTypeTableRow getRowForRange(int roll) { - ModTypeTableRow outRow = null; - for (ModTypeTableRow iteration : this.rows) { - if (roll >= iteration.minRoll && roll <= iteration.maxRoll) { - return iteration; - } - } - return outRow; - } - } - public static class ModTable { - public ArrayList rows = new ArrayList(); - - public ModTableRow getRowForRange(int roll) { - if (roll > 320) { - roll = 320; - } - ModTableRow outRow = null; - for (ModTableRow iteration : this.rows) { - if (roll >= iteration.minRoll && roll <= iteration.maxRoll) { - outRow = iteration; - } - } - return outRow; - } - } - public static class GenTableRow { - public int minRoll; - public int maxRoll; - public int itemTableID; - public int pModTable; - public int sModTable; - - public GenTableRow(ResultSet rs) throws SQLException { - this.minRoll = rs.getInt("minRoll"); - this.maxRoll = rs.getInt("maxRoll"); - this.itemTableID = rs.getInt("lootTableID"); - this.pModTable = rs.getInt("pModTableID"); - this.sModTable = rs.getInt("sModTableID"); - } - } - public static class ItemTableRow { - public int minRoll; - public int maxRoll; - public int cacheID; - public int minSpawn; - public int maxSpawn; - - public ItemTableRow(ResultSet rs) throws SQLException { - this.minRoll = rs.getInt("minRoll"); - this.maxRoll = rs.getInt("maxRoll"); - this.cacheID = rs.getInt("itemBaseUUID"); - this.minSpawn = rs.getInt("minSpawn"); - this.maxSpawn = rs.getInt("maxSpawn"); - - } - } - public static class ModTypeTableRow { - public int minRoll; - public int maxRoll; - public int modTableID; - - public ModTypeTableRow(ResultSet rs) throws SQLException { - this.minRoll = rs.getInt("minRoll"); - this.maxRoll = rs.getInt("maxRoll"); - this.modTableID = rs.getInt("subTableID"); - - } - } - public static class ModTableRow { - public int minRoll; - public int maxRoll; - public String action; - public int level; - - public ModTableRow(ResultSet rs) throws SQLException { - this.minRoll = rs.getInt("minRoll"); - this.maxRoll = rs.getInt("maxRoll"); - this.action = rs.getString("action"); - this.level = rs.getInt("level"); - - } - } -} \ No newline at end of file diff --git a/src/engine/loot/ModTableEntry.java b/src/engine/loot/ModTableEntry.java new file mode 100644 index 00000000..86697880 --- /dev/null +++ b/src/engine/loot/ModTableEntry.java @@ -0,0 +1,43 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + +package engine.loot; + +import engine.gameManager.LootManager; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class ModTableEntry { + public int minRoll; + public int maxRoll; + public String action; + public int level; + + public ModTableEntry(ResultSet rs) throws SQLException { + this.minRoll = rs.getInt("minRoll"); + this.maxRoll = rs.getInt("maxRoll"); + this.action = rs.getString("action"); + this.level = rs.getInt("level"); + } + + public static ModTableEntry rollTable(int modTablwe, int roll) { + + ModTableEntry modTableEntry = null; + List itemTableEntryList; + + itemTableEntryList = LootManager._modTables.get(modTablwe); + + for (ModTableEntry iteration : itemTableEntryList) + if (roll >= iteration.minRoll && roll <= iteration.maxRoll) + modTableEntry = iteration; + + return modTableEntry; + } +} diff --git a/src/engine/loot/ModTypeTableEntry.java b/src/engine/loot/ModTypeTableEntry.java new file mode 100644 index 00000000..8ed23ace --- /dev/null +++ b/src/engine/loot/ModTypeTableEntry.java @@ -0,0 +1,41 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + +package engine.loot; + +import engine.gameManager.LootManager; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class ModTypeTableEntry { + public int minRoll; + public int maxRoll; + public int modTableID; + + public ModTypeTableEntry(ResultSet rs) throws SQLException { + this.minRoll = rs.getInt("minRoll"); + this.maxRoll = rs.getInt("maxRoll"); + this.modTableID = rs.getInt("subTableID"); + } + + public static ModTypeTableEntry rollTable(int modTablwe, int roll) { + + ModTypeTableEntry modTypeTableEntry = null; + List modTypeTableEntryList; + + modTypeTableEntryList = LootManager._modTypeTables.get(modTablwe); + + for (ModTypeTableEntry iteration : modTypeTableEntryList) + if (roll >= iteration.minRoll && roll <= iteration.maxRoll) + modTypeTableEntry = iteration; + + return modTypeTableEntry; + } +} diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index f274f185..34e738b2 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -1243,6 +1243,12 @@ public class ClientMessagePump implements NetMsgHandler { cost = sell.getBaseValue(); + + //apply damaged value reduction + float durabilityCurrent = sell.getDurabilityCurrent(); + float durabilityMax = sell.getDurabilityMax(); + float damagedModifier = durabilityCurrent / durabilityMax; + cost *= damagedModifier; float bargain = player.getBargain(); float profit = npc.getBuyPercent(player) + bargain; diff --git a/src/engine/net/client/handlers/ObjectActionMsgHandler.java b/src/engine/net/client/handlers/ObjectActionMsgHandler.java index 0137b24d..510c6bd8 100644 --- a/src/engine/net/client/handlers/ObjectActionMsgHandler.java +++ b/src/engine/net/client/handlers/ObjectActionMsgHandler.java @@ -440,9 +440,8 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler { } break; } - - LootTable.CreateGamblerItem(item, player); - + // Garbage method removed until rewritten. + // LootTable.CreateGamblerItem(item, player); break; diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index ad365a3d..3d33c68d 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -10,7 +10,6 @@ package engine.objects; import engine.Enum.TargetColor; -import engine.gameManager.ConfigManager; import engine.gameManager.ZoneManager; import engine.math.Vector3fImmutable; import engine.server.MBServerStatics; @@ -18,6 +17,8 @@ import engine.server.MBServerStatics; import java.util.ArrayList; import java.util.TreeMap; +import static engine.gameManager.LootManager.LOOTMANAGER; + public class Experience { private static final TreeMap ExpToLevel; @@ -238,44 +239,44 @@ public class Experience { // called to determine current level based on xp public static int getLevel(int experience) { + int expKey = ExpToLevel.floorKey(experience); int level = ExpToLevel.get(expKey); - if (level > MBServerStatics.LEVELCAP) { + + if (level > MBServerStatics.LEVELCAP) level = MBServerStatics.LEVELCAP; - } + return level; } // Get the base xp for a level public static int getBaseExperience(int level) { - if (level < LevelToExp.length) { + + if (level < LevelToExp.length) return LevelToExp[level]; - } int fLevel = level - 1; int baseXP = fLevel * fLevel * fLevel; + return (int) ((fLevel < 40) ? (baseXP * 150) : (baseXP * (150 + (7.6799998 * (level - 40))))); } - // Get XP needed for the next level - public static int getExpForNextLevel(int experience, int currentLevel) { - return (getBaseExperience(currentLevel + 1) - experience); - } - // Max XP granted for killing a blue, yellow or orange mob public static float maxXPPerKill(int level) { + if (level < 1) level = 1; + if (level > 75) level = 75; + return MaxExpPerLevel[level]; - // return (LevelToExp[level + 1] - LevelToExp[level])/(11 + level/2); - // return ((((level * level)-level)*50)+16); } // Returns a penalty modifier depending on mob color public static double getConMod(AbstractCharacter pc, AbstractCharacter mob) { + switch (TargetColor.getCon(pc, mob)) { case Red: return 1.25; @@ -299,16 +300,16 @@ public class Experience { int highestLevel) { double penalty = 0.0; - int adjustedGroupSize = 0; - int totalLevels = 0; int level = currPlayer.getLevel(); // Group Size Penalty + if (players.size() > 2) penalty = (players.size() - 2) * 1.5; // Calculate Penalty For Highest level -> Current Player difference, != // check to prevent divide by zero error + if (highestLevel != level) penalty += ((highestLevel - level) * .5); @@ -318,6 +319,7 @@ public class Experience { // penalty += ((avgLevels - level) * .5); // Extra noob penalty + if ((highestLevel - level) > 25) penalty += (highestLevel - level - 25); @@ -325,7 +327,9 @@ public class Experience { } public static void doExperience(PlayerCharacter killer, AbstractCharacter mob, Group g) { + // Check for some failure conditions + if (killer == null || mob == null) return; @@ -341,10 +345,13 @@ public class Experience { // Check if leader is within range of kill and then get leadership // skill + Vector3fImmutable killLoc = mob.getLoc(); + if (killLoc.distanceSquared2D(g.getGroupLead().getLoc()) < (MBServerStatics.EXP_RANGE * MBServerStatics.EXP_RANGE)) { CharacterSkill leaderskill = g.getGroupLead().skills .get("Leadership"); + if (leaderskill != null) leadership = leaderskill.getNumTrains(); if (leadership > 90) @@ -352,13 +359,18 @@ public class Experience { } // Check every group member for distance to see if they get xp + for (PlayerCharacter pc : g.getMembers()) { if (pc.isAlive()) { // Skip if the player is dead. // Check within range + if (killLoc.distanceSquared2D(pc.getLoc()) < (MBServerStatics.EXP_RANGE * MBServerStatics.EXP_RANGE)) { + giveEXPTo.add(pc); + // Track highest level character + if (pc.getLevel() > highestLevel) highestLevel = pc.getLevel(); } @@ -366,34 +378,41 @@ public class Experience { } // Process every player in the group getting XP + for (PlayerCharacter playerCharacter : giveEXPTo) { if (playerCharacter.getLevel() >= MBServerStatics.LEVELCAP) continue; // Sets Max XP with server exp mod taken into account. - grantedExperience = (double) Float.parseFloat(ConfigManager.MB_NORMAL_EXP_RATE.getValue()) * maxXPPerKill(playerCharacter.getLevel()); + + grantedExperience = (double) LOOTMANAGER.NORMAL_EXP_RATE * maxXPPerKill(playerCharacter.getLevel()); // Adjust XP for Mob Level + grantedExperience *= getConMod(playerCharacter, mob); // Process XP for this member + penalty = getGroupMemberPenalty(leadership, playerCharacter, giveEXPTo, highestLevel); // Leadership Penalty Reduction + if (leadership > 0) penalty -= ((leadership) * 0.01) * penalty; // Modify for hotzone + if (grantedExperience != 0) if (ZoneManager.inHotZone(mob.getLoc())) - grantedExperience *= Float.parseFloat(ConfigManager.MB_HOTZONE_EXP_RATE.getValue()); + grantedExperience *= LOOTMANAGER.HOTZONE_EXP_RATE; // Check for 0 XP due to white mob, otherwise subtract penalty // xp - if (grantedExperience == 0) { + + if (grantedExperience == 0) grantedExperience = 1; - } else { + else { grantedExperience -= (penalty * 0.01) * grantedExperience; // Errant Penalty Calculation @@ -416,12 +435,12 @@ public class Experience { return; // Get XP and adjust for Mob Level with world xp modifier taken into account - grantedExperience = (double) Float.parseFloat(ConfigManager.MB_NORMAL_EXP_RATE.getValue()) * maxXPPerKill(killer.getLevel()); + grantedExperience = (double) LOOTMANAGER.NORMAL_EXP_RATE * maxXPPerKill(killer.getLevel()); grantedExperience *= getConMod(killer, mob); // Modify for hotzone if (ZoneManager.inHotZone(mob.getLoc())) - grantedExperience *= Float.parseFloat(ConfigManager.MB_HOTZONE_EXP_RATE.getValue()); + grantedExperience *= LOOTMANAGER.HOTZONE_EXP_RATE; // Errant penalty if (grantedExperience != 1) diff --git a/src/engine/objects/ItemFactory.java b/src/engine/objects/ItemFactory.java index 4e0cc8dd..34b06cb0 100644 --- a/src/engine/objects/ItemFactory.java +++ b/src/engine/objects/ItemFactory.java @@ -14,6 +14,8 @@ import engine.Enum.ItemContainerType; import engine.Enum.ItemType; import engine.Enum.OwnerType; import engine.gameManager.*; +import engine.loot.ModTableEntry; +import engine.loot.ModTypeTableEntry; import engine.net.ItemProductionManager; import engine.net.ItemQueue; import engine.net.client.ClientConnection; @@ -644,47 +646,44 @@ public class ItemFactory { } - public static Item randomRoll(NPC vendor, PlayerCharacter pc, int itemsToRoll, int itemID) { + public static Item randomRoll(NPC vendor, PlayerCharacter playerCharacter, int itemsToRoll, int itemBaseID) { byte itemModTable; int prefixMod = 0; int suffixMod = 0; - LootTable prefixLootTable; - LootTable suffixLootTable; - String suffix = ""; String prefix = ""; - MobLoot toRoll; + String suffix = ""; - ItemBase ib = ItemBase.getItemBase(itemID); + ModTableEntry prefixEntry = null; + ModTableEntry suffixEntry = null; + + ItemBase ib = ItemBase.getItemBase(itemBaseID); if (ib == null) return null; if (!vendor.getCharItemManager().hasRoomInventory(ib.getWeight())) { - if (pc != null) - ChatManager.chatSystemInfo(pc, vendor.getName() + " " + vendor.getContract().getName() + " Inventory is full."); - return null; - } - - float calculatedMobLevel; - calculatedMobLevel = vendor.getLevel(); - if (calculatedMobLevel < 16) - calculatedMobLevel = 16; + if (playerCharacter != null) + ChatManager.chatSystemInfo(playerCharacter, vendor.getName() + " " + vendor.getContract().getName() + " Inventory is full."); - if (calculatedMobLevel > 49) - calculatedMobLevel = 49; + return null; + } itemModTable = (byte) ib.getModTable(); if (!vendor.getItemModTable().contains(itemModTable)) { - if (pc != null) - ErrorPopupMsg.sendErrorPopup(pc, 59); + + if (playerCharacter != null) + ErrorPopupMsg.sendErrorPopup(playerCharacter, 59); + return null; } for (byte temp : vendor.getItemModTable()) { + if (itemModTable != temp) continue; + prefixMod = vendor.getModTypeTable().get(vendor.getItemModTable().indexOf(temp)); suffixMod = vendor.getModSuffixTable().get(vendor.getItemModTable().indexOf(temp)); } @@ -694,187 +693,43 @@ public class ItemFactory { return null; } - prefixLootTable = LootTable.getModGroup(prefixMod); - suffixLootTable = LootTable.getModGroup(suffixMod); - - if (prefixLootTable == null || suffixLootTable == null) - return null; - - int rollPrefix = ThreadLocalRandom.current().nextInt(100); - - if (rollPrefix < 80) { - int randomPrefix = ThreadLocalRandom.current().nextInt(100) + 1; - LootRow prefixLootRow = prefixLootTable.getLootRow(randomPrefix); - - if (prefixLootRow != null) { - LootTable prefixTypeTable = LootTable.getModTable(prefixLootRow.getValueOne()); - - int minRoll = (int) ((calculatedMobLevel - 5) * 5); - int maxRoll = (int) ((calculatedMobLevel + 15) * 5); - - if (minRoll < (int) prefixTypeTable.minRoll) - minRoll = (int) prefixTypeTable.minRoll; - - if (maxRoll < minRoll) - maxRoll = minRoll; - - if (maxRoll > prefixTypeTable.maxRoll) - maxRoll = (int) prefixTypeTable.maxRoll; - - if (maxRoll > 320) - maxRoll = 320; - - int randomPrefix1 = (int) ThreadLocalRandom.current().nextDouble(minRoll, maxRoll + 1); //Does not return Max, but does return min? - - if (randomPrefix1 < prefixTypeTable.minRoll) - randomPrefix1 = (int) prefixTypeTable.minRoll; - - if (randomPrefix1 > prefixTypeTable.maxRoll) - randomPrefix1 = (int) prefixTypeTable.maxRoll; - - LootRow prefixTypelootRow = prefixTypeTable.getLootRow(randomPrefix1); - - if (prefixTypelootRow == null) - prefixTypelootRow = prefixTypeTable.getLootRow((int) ((prefixTypeTable.maxRoll + prefixTypeTable.minRoll) * .05f)); - - if (prefixTypelootRow != null) { - prefix = prefixTypelootRow.getAction(); - } - } - } - - int rollSuffix = ThreadLocalRandom.current().nextInt(100); - - if (rollSuffix < 80) { - - int randomSuffix = ThreadLocalRandom.current().nextInt(100) + 1; - LootRow suffixLootRow = suffixLootTable.getLootRow(randomSuffix); - - if (suffixLootRow != null) { - - LootTable suffixTypeTable = LootTable.getModTable(suffixLootRow.getValueOne()); - - if (suffixTypeTable != null) { - int minRoll = (int) ((calculatedMobLevel - 5) * 5); - int maxRoll = (int) ((calculatedMobLevel + 15) * 5); + // Roll on the tables for this vendor - if (minRoll < (int) suffixTypeTable.minRoll) - minRoll = (int) suffixTypeTable.minRoll; + ModTypeTableEntry prefixTypeTable = ModTypeTableEntry.rollTable(prefixMod, ThreadLocalRandom.current().nextInt(1, 100 + 1)); + ModTypeTableEntry suffixTypeTable = ModTypeTableEntry.rollTable(suffixMod, ThreadLocalRandom.current().nextInt(1, 100 + 1)); - if (maxRoll < minRoll) - maxRoll = minRoll; + // Sanity check. - if (maxRoll > suffixTypeTable.maxRoll) - maxRoll = (int) suffixTypeTable.maxRoll; - - if (maxRoll > 320) - maxRoll = 320; + if (prefixTypeTable == null || suffixTypeTable == null) + return null; - int randomSuffix1 = (int) ThreadLocalRandom.current().nextDouble(minRoll, maxRoll + 1); //Does not return Max, but does return min? + int rollPrefix = ThreadLocalRandom.current().nextInt(1, 100 + 1); - if (randomSuffix1 < suffixTypeTable.minRoll) - randomSuffix1 = (int) suffixTypeTable.minRoll; + if (rollPrefix < 80) { - if (randomSuffix1 > suffixTypeTable.maxRoll) - randomSuffix1 = (int) suffixTypeTable.maxRoll; + int randomPrefix = LootManager.TableRoll(vendor.getLevel(), false); + prefixEntry = ModTableEntry.rollTable(prefixTypeTable.modTableID, randomPrefix); - LootRow suffixTypelootRow = suffixTypeTable.getLootRow(randomSuffix1); + if (prefixEntry != null) + prefix = prefixEntry.action; - if (suffixTypelootRow != null) { - suffix = suffixTypelootRow.getAction(); - } - } - } } - if (prefix.isEmpty() && suffix.isEmpty()) { - - rollPrefix = ThreadLocalRandom.current().nextInt(100); - - if (rollPrefix < 50) { - - int randomPrefix = ThreadLocalRandom.current().nextInt(100) + 1; - LootRow prefixLootRow = prefixLootTable.getLootRow(randomPrefix); - - if (prefixLootRow != null) { - - LootTable prefixTypeTable = LootTable.getModTable(prefixLootRow.getValueOne()); - - int minRoll = (int) ((calculatedMobLevel) * 5); - int maxRoll = (int) ((calculatedMobLevel + 15) * 5); - - if (minRoll < (int) prefixTypeTable.minRoll) - minRoll = (int) prefixTypeTable.minRoll; - - if (maxRoll < minRoll) - maxRoll = minRoll; - - if (maxRoll > prefixTypeTable.maxRoll) - maxRoll = (int) prefixTypeTable.maxRoll; - - if (maxRoll > 320) - maxRoll = 320; - - int randomPrefix1 = (int) ThreadLocalRandom.current().nextDouble(minRoll, maxRoll + 1); //Does not return Max, but does return min? - - if (randomPrefix1 < prefixTypeTable.minRoll) - randomPrefix1 = (int) prefixTypeTable.minRoll; - - if (randomPrefix1 > prefixTypeTable.maxRoll) - randomPrefix1 = (int) prefixTypeTable.maxRoll; - - LootRow prefixTypelootRow = prefixTypeTable.getLootRow(randomPrefix1); + int rollSuffix = ThreadLocalRandom.current().nextInt(1, 100 + 1); - if (prefixTypelootRow == null) - prefixTypelootRow = prefixTypeTable.getLootRow((int) ((prefixTypeTable.maxRoll + prefixTypeTable.minRoll) * .05f)); + // Always have at least one mod on a magic rolled item. + // Suffix will be our backup plan. - if (prefixTypelootRow != null) { - prefix = prefixTypelootRow.getAction(); - } - } - } else { - int randomSuffix = ThreadLocalRandom.current().nextInt(100) + 1; - LootRow suffixLootRow = suffixLootTable.getLootRow(randomSuffix); - - if (suffixLootRow != null) { - - LootTable suffixTypeTable = LootTable.getModTable(suffixLootRow.getValueOne()); - - if (suffixTypeTable != null) { - - int minRoll = (int) ((calculatedMobLevel) * 5); - int maxRoll = (int) ((calculatedMobLevel + 15) * 5); - - if (minRoll < (int) suffixTypeTable.minRoll) - minRoll = (int) suffixTypeTable.minRoll; - - if (maxRoll < minRoll) - maxRoll = minRoll; - - if (maxRoll > suffixTypeTable.maxRoll) - maxRoll = (int) suffixTypeTable.maxRoll; - - if (maxRoll > 320) - maxRoll = 320; + if (rollSuffix < 80 || prefixEntry == null) { - int randomSuffix1 = (int) ThreadLocalRandom.current().nextDouble(minRoll, maxRoll + 1); //Does not return Max, but does return min? + int randomSuffix = LootManager.TableRoll(vendor.getLevel(), false); + suffixEntry = ModTableEntry.rollTable(suffixTypeTable.modTableID, randomSuffix); - if (randomSuffix1 < suffixTypeTable.minRoll) - randomSuffix1 = (int) suffixTypeTable.minRoll; - - if (randomSuffix1 > suffixTypeTable.maxRoll) - randomSuffix1 = (int) suffixTypeTable.maxRoll; - - LootRow suffixTypelootRow = suffixTypeTable.getLootRow(randomSuffix1); - - if (suffixTypelootRow != null) - suffix = suffixTypelootRow.getAction(); - } - } - } + if (suffixEntry != null) + suffix = suffixEntry.action; } - toRoll = ItemFactory.produceRandomRoll(vendor, pc, prefix, suffix, itemID); + MobLoot toRoll = ItemFactory.produceRandomRoll(vendor, playerCharacter, prefix, suffix, itemBaseID); if (toRoll == null) return null; @@ -893,9 +748,10 @@ public class ItemFactory { } // No job is submitted, as object's upgradetime field - // is used to determin whether or not an object has - // compelted rolling. The game object exists previously - // to this, not when 'compelte' is pressed. + // is used to determine whether an object has + // completed rolling. The game object exists previously + // to this, not when 'complete' is pressed. + long upgradeTime = System.currentTimeMillis() + (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue())); DateTime dateTime = new DateTime(); @@ -904,14 +760,17 @@ public class ItemFactory { int playerID = 0; - if (pc != null) - playerID = pc.getObjectUUID(); + if (playerCharacter != null) + playerID = playerCharacter.getObjectUUID(); + DbManager.NPCQueries.ADD_TO_PRODUCTION_LIST(toRoll.getObjectUUID(), vendor.getObjectUUID(), toRoll.getItemBaseID(), dateTime, prefix, suffix, toRoll.getCustomName(), true, playerID); + ProducedItem pi = new ProducedItem(toRoll.getObjectUUID(), vendor.getObjectUUID(), toRoll.getItemBaseID(), dateTime, true, prefix, suffix, toRoll.getCustomName(), playerID); pi.setProducedItemID(toRoll.getObjectUUID()); pi.setAmount(itemsToRoll); ItemQueue produced = ItemQueue.borrow(pi, (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()))); ItemProductionManager.send(produced); + return toRoll; } diff --git a/src/engine/objects/LootRow.java b/src/engine/objects/LootRow.java deleted file mode 100644 index 4e99ae3d..00000000 --- a/src/engine/objects/LootRow.java +++ /dev/null @@ -1,63 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2022 -// www.magicbane.com - - -package engine.objects; - -public class LootRow { - - private int valueOne; - private int valueTwo; - private int valueThree; - private String action; - - - /** - * Generic Constructor - */ - public LootRow(int valueOne, int valueTwo, int valueThree, String action) { - this.valueOne = valueOne; - this.valueTwo = valueTwo; - this.valueThree = valueThree; - this.action = action; - - } - - public int getValueOne() { - return this.valueOne; - } - - public void setValueOne(int value) { - this.valueOne = value; - } - - public int getValueTwo() { - return this.valueTwo; - } - - public void setValueTwo(int value) { - this.valueTwo = value; - } - - public int getValueThree() { - return this.valueThree; - } - - public void setValueThree(int value) { - this.valueThree = value; - } - - public String getAction() { - return this.action; - } - - public void setAction(String value) { - this.action = value; - } - -} diff --git a/src/engine/objects/LootTable.java b/src/engine/objects/LootTable.java deleted file mode 100644 index 74e86e8f..00000000 --- a/src/engine/objects/LootTable.java +++ /dev/null @@ -1,1250 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2022 -// www.magicbane.com - - -package engine.objects; - -import engine.Enum.ItemContainerType; -import engine.Enum.ItemType; -import engine.Enum.OwnerType; -import engine.gameManager.ConfigManager; -import engine.gameManager.DbManager; -import engine.gameManager.NPCManager; -import engine.gameManager.ZoneManager; -import engine.server.MBServerStatics; -import org.pmw.tinylog.Logger; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ThreadLocalRandom; - -public class LootTable { - - private static final ConcurrentHashMap lootGroups = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); - private static final ConcurrentHashMap lootTables = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); - private static final ConcurrentHashMap modTables = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); - private static final ConcurrentHashMap modGroups = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); - private static final ConcurrentHashMap statRuneChances = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); - private static final int oneDrop = 95; - private static final int twoDrop = 100; - private static final int noDropHotZone = 79; - private static final int oneDropHotZone = 98; - public static boolean initialized = false; - public static HashMap itemsDroppedMap = new HashMap<>(); - public static HashMap resourceDroppedMap = new HashMap<>(); - public static HashMap runeDroppedMap = new HashMap<>(); - public static HashMap contractDroppedMap = new HashMap<>(); - public static HashMap glassDroppedMap = new HashMap<>(); - public static int rollCount = 0; - public static int dropCount = 0; - public static int runeCount = 0; - public static int contractCount = 0; - public static int resourceCount = 0; - public static int glassCount = 0; - private final ConcurrentHashMap lootTable = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); - public float minRoll = 320; - public float maxRoll = 1; - public int lootTableID = 0; - - - /** - * Generic Constructor - */ - public LootTable(int lootTableID) { - this.lootTableID = lootTableID; - } - - public static LootTable getLootGroup(int UUID) { - - if (lootGroups.containsKey(UUID)) - return lootGroups.get(UUID); - - LootTable lootGroup = new LootTable(UUID); - lootGroups.put(UUID, lootGroup); - return lootGroup; - } - - public static LootTable getLootTable(int UUID) { - - if (lootTables.containsKey(UUID)) - return lootTables.get(UUID); - - LootTable lootTable = new LootTable(UUID); - lootTables.put(UUID, lootTable); - return lootTable; - } - - /** - * @return the lootGroups - */ - public static ConcurrentHashMap getLootGroups() { - return lootGroups; - } - - /** - * @return the lootTables - */ - public static ConcurrentHashMap getLootTables() { - return lootTables; - } - - /** - * @return the modTables - */ - public static ConcurrentHashMap getModTables() { - return modTables; - } - - /** - * @return the modGroups - */ - public static ConcurrentHashMap getModGroups() { - return modGroups; - } - - public static LootTable getModGroup(int UUID) { - if (modGroups.containsKey(UUID)) - return modGroups.get(UUID); - LootTable modTable = new LootTable(UUID); - modGroups.put(UUID, modTable); - return modTable; - } - - public static LootTable getModTable(int UUID) { - if (modTables.containsKey(UUID)) - return modTables.get(UUID); - LootTable modTypeTable = new LootTable(UUID); - modTables.put(UUID, modTypeTable); - return modTypeTable; - } - - //call this on server startup to populate the tables - public static void populateLootTables() { - DbManager.LootQueries.populateLootGroups(); - DbManager.LootQueries.populateLootTables(); - DbManager.LootQueries.populateModTables(); - DbManager.LootQueries.populateModGroups(); - - //preset chances for rune drops - populateStatRuneChances(); - } - - //Returns a list of random loot for a mob based on level, lootTable and hotzone - public static ArrayList getMobLoot(Mob mobile, int mobLevel, int lootTable, boolean hotzone) { - - ArrayList mobLoot; - int calculatedLootTable; - int randomRoll; - - mobLoot = new ArrayList<>(); - - // Setup default loot table if none exists - - calculatedLootTable = lootTable; - - LootTable.rollCount++; - - if (MobLootBase.MobLootSet.get(mobile.getMobBase().getLoadID()).isEmpty()) { - - randomRoll = ThreadLocalRandom.current().nextInt(100); - - if (randomRoll > 90) - if (randomRoll > LootTable.oneDropHotZone) - addMobLoot(mobile, mobLoot, mobLevel, calculatedLootTable, 1, true); - else - addMobLoot(mobile, mobLoot, mobLevel, calculatedLootTable, 1, true); - } else { - for (MobLootBase mlb : MobLootBase.MobLootSet.get(mobile.getMobBase().getLoadID())) { - - float chance = mlb.getChance() * .01f; - - chance *= Float.parseFloat(ConfigManager.MB_NORMAL_DROP_RATE.getValue()); - - calculatedLootTable = mlb.getLootTableID(); - - if (ThreadLocalRandom.current().nextFloat() > chance) - continue; - - addMobLoot(mobile, mobLoot, mobLevel, calculatedLootTable, 1, false); - - } - } - - //calculatedLootTable = lootTable; - - if (calculatedLootTable <= 1) - calculatedLootTable = 1300; // GENERIC WORLD - - //handle hotzone random loot - - if (hotzone) { - - LootTable.rollCount++; - - if (!MobLootBase.MobLootSet.get(mobile.getMobBase().getLoadID()).isEmpty()) - for (MobLootBase mlb : MobLootBase.MobLootSet.get(mobile.getMobBase().getLoadID())) { - if (!LootTable.lootGroups.containsKey(mlb.getLootTableID() + 1)) - continue; - calculatedLootTable = mlb.getLootTableID(); - break; - } - - randomRoll = ThreadLocalRandom.current().nextInt(100); - - if (randomRoll > 90) - if (randomRoll > LootTable.oneDropHotZone) - addMobLoot(mobile, mobLoot, mobLevel, calculatedLootTable + 1, 1, true); - else - addMobLoot(mobile, mobLoot, mobLevel, calculatedLootTable + 1, 1, true); - } - - //handle mob specific special loot - - ArrayList bootyLoot = getBootyLoot(mobile); - mobLoot.addAll(bootyLoot); - - return mobLoot; - } - - public static ArrayList getMobLootDeath(Mob mobile, int mobLevel, int lootTable) { - ArrayList mobLoot = new ArrayList<>(); - - if (mobile == null) - return mobLoot; - - //handle hotzone random loot - boolean hotzone = ZoneManager.inHotZone(mobile.getLoc()); - if (hotzone) { - - if (MobLootBase.MobLootSet.get(mobile.getMobBase().getLoadID()).isEmpty()) { - lootTable += 1; - - if (lootTable <= 1) - lootTable = 1301; // GENERIC WORLD - int roll = ThreadLocalRandom.current().nextInt(100); - if (roll > 90) - if (roll > LootTable.oneDropHotZone) - addMobLoot(mobile, mobLoot, mobLevel, lootTable, 1, true); - else - addMobLoot(mobile, mobLoot, mobLevel, lootTable, 1, true); - } else { - for (MobLootBase mlb : MobLootBase.MobLootSet.get(mobile.getMobBase().getLoadID())) { - lootTable = mlb.getLootTableID() + 1; - if (!LootTable.lootGroups.containsKey(lootTable)) - continue; - - int roll = ThreadLocalRandom.current().nextInt(100); - if (roll > 90) - if (roll > LootTable.oneDropHotZone) - addMobLoot(mobile, mobLoot, mobLevel, (lootTable), 1, true); - else - addMobLoot(mobile, mobLoot, mobLevel, (lootTable), 1, true); - - break; - } - } - - - if (mobLoot.isEmpty()) { - - LootTable.rollCount++; //add another rollCount here. - int resourceRoll = ThreadLocalRandom.current().nextInt(100); - if (resourceRoll <= 5) - addMobLootResources(mobile, mobLoot, mobLevel, (lootTable), 1, true); - } - - } - - - //handle mob specific booty on death - - ArrayList bootyLoot = getBootyLoot(mobile); - mobLoot.addAll(bootyLoot); - - return mobLoot; - } - - private static ArrayList getBootyLoot(Mob mob) { - - ArrayList bootySetList; - ArrayList mobLootList = new ArrayList<>(); - - if (mob.bootySet == 0) - return mobLootList; - - bootySetList = NPCManager._bootySetMap.get(mob.bootySet); - - for (BootySetEntry bootyEntry : bootySetList) - if (ThreadLocalRandom.current().nextInt(100) < bootyEntry.dropChance) { - ItemBase itemBase = ItemBase.getItemBase(bootyEntry.itemBase); - - if (itemBase != null) { - MobLoot mobLoot = new MobLoot(mob, itemBase, true); - mobLootList.add(mobLoot); - } - } - return mobLootList; - } - - //called by getMobLoot to add the actual loot - private static void addMobLoot(Mob mob, ArrayList loot, int mobLevel, int lootTableID, int cnt, boolean hotzone) { - - // Member variable declaration - float calculatedMobLevel; - int minSpawn; - int maxSpawn; - int spawnQuanity = 0; - int prefixValue = 0; - int suffixValue = 0; - int subTableID; - String modifierPrefix = ""; - String modifierSuffix = ""; - - // Lookup Table Variables - LootTable lootTable; - LootRow lootRow; - LootTable lootGroup; - LootRow groupRow = null; - LootTable modTable; - LootTable modGroup; - LootRow modRow = null; - - // Used for actual generation of items - - int itemBaseUUID; - ItemBase itemBase = null; - MobLoot mobLoot; - - if (!LootTable.lootGroups.containsKey(lootTableID)) - return; - - lootGroup = LootTable.lootGroups.get(lootTableID); - - calculatedMobLevel = mobLevel; - - if (calculatedMobLevel > 49) - calculatedMobLevel = 49; - - - int randomRoll = 0; - for (int i = 0; i < cnt; i++) { - - Random random = new Random(); - - randomRoll = random.nextInt(100) + 1; //random roll between 1 and 100 - groupRow = lootGroup.getLootRow(randomRoll); - - if (groupRow == null) - return; - - //get loot table for this group - if (!LootTable.lootTables.containsKey(groupRow.getValueOne())) - return; - - lootTable = LootTable.lootTables.get(groupRow.getValueOne()); - - int minRoll = (int) ((calculatedMobLevel - 5) * 5); - int maxRoll = (int) ((calculatedMobLevel + 15) * 5); - - if (minRoll < (int) lootTable.minRoll) - minRoll = (int) lootTable.minRoll; - - if (maxRoll < minRoll) - maxRoll = minRoll; - - if (maxRoll > lootTable.maxRoll) - maxRoll = (int) lootTable.maxRoll; - - if (maxRoll > 320) - maxRoll = 320; - - randomRoll = (int) ThreadLocalRandom.current().nextDouble(minRoll, maxRoll + 1); //Does not return Max, but does return min? - - lootRow = lootTable.getLootRow(randomRoll); //get the item row from the bell's curve of level +-15 - - if (lootRow == null) - continue; //no item found for roll - - itemBaseUUID = lootRow.getValueOne(); - - if (lootRow.getValueOne() == 0) - continue; - - //handle quantities > 1 for resource drops - - minSpawn = lootRow.getValueTwo(); - maxSpawn = lootRow.getValueThree(); - - // spawnQuantity between min spawn (inclusive) and max spawn (inclusive) - if (maxSpawn > 1) - spawnQuanity = ThreadLocalRandom.current().nextInt((maxSpawn + 1 - minSpawn)) + minSpawn; - - //get modifierPrefix - - calculatedMobLevel = mobLevel; - - if (calculatedMobLevel < 16) - calculatedMobLevel = 16; - - if (calculatedMobLevel > 49) - calculatedMobLevel = 49; - - int chanceMod = ThreadLocalRandom.current().nextInt(100) + 1; - - if (chanceMod < 25) { - modGroup = LootTable.modGroups.get(groupRow.getValueTwo()); - - if (modGroup != null) { - - for (int a = 0; a < 10; a++) { - randomRoll = ThreadLocalRandom.current().nextInt(100) + 1; - modRow = modGroup.getLootRow(randomRoll); - if (modRow != null) - break; - } - - if (modRow != null) { - subTableID = modRow.getValueOne(); - - if (LootTable.modTables.containsKey(subTableID)) { - - modTable = LootTable.modTables.get(subTableID); - - randomRoll = gaussianLevel((int) calculatedMobLevel); - - if (randomRoll < modTable.minRoll) - randomRoll = (int) modTable.minRoll; - - if (randomRoll > modTable.maxRoll) - randomRoll = (int) modTable.maxRoll; - - modRow = modTable.getLootRow(randomRoll); - - if (modRow != null) { - prefixValue = modRow.getValueOne(); - modifierPrefix = modRow.getAction(); - } - } - } - } - } else if (chanceMod < 50) { - modGroup = LootTable.modGroups.get(groupRow.getValueThree()); - - if (modGroup != null) { - - for (int a = 0; a < 10; a++) { - randomRoll = ThreadLocalRandom.current().nextInt(100) + 1; - modRow = modGroup.getLootRow(randomRoll); - if (modRow != null) - break; - } - - if (modRow != null) { - - subTableID = modRow.getValueOne(); - - if (LootTable.modTables.containsKey(subTableID)) { - - modTable = LootTable.modTables.get(subTableID); - randomRoll = gaussianLevel((int) calculatedMobLevel); - - if (randomRoll < modTable.minRoll) - randomRoll = (int) modTable.minRoll; - - if (randomRoll > modTable.maxRoll) - randomRoll = (int) modTable.maxRoll; - - modRow = modTable.getLootRow(randomRoll); - - if (modRow == null) - modRow = modTable.getLootRow((int) ((modTable.minRoll + modTable.maxRoll) * .05f)); - - - if (modRow != null) { - suffixValue = modRow.getValueOne(); - modifierSuffix = modRow.getAction(); - } - } - } - } - } else { - modGroup = LootTable.modGroups.get(groupRow.getValueTwo()); - - if (modGroup != null) { - - - for (int a = 0; a < 10; a++) { - randomRoll = ThreadLocalRandom.current().nextInt(100) + 1; - modRow = modGroup.getLootRow(randomRoll); - if (modRow != null) - break; - } - - - if (modRow != null) { - subTableID = modRow.getValueOne(); - - if (LootTable.modTables.containsKey(subTableID)) { - - modTable = LootTable.modTables.get(subTableID); - - randomRoll = gaussianLevel((int) calculatedMobLevel); - - if (randomRoll < modTable.minRoll) - randomRoll = (int) modTable.minRoll; - - if (randomRoll > modTable.maxRoll) - randomRoll = (int) modTable.maxRoll; - - modRow = modTable.getLootRow(randomRoll); - - if (modRow == null) - modRow = modTable.getLootRow((int) ((modTable.minRoll + modTable.maxRoll) * .05f)); - - if (modRow != null) { - prefixValue = modRow.getValueOne(); - modifierPrefix = modRow.getAction(); - } - } - } - } - - //get modifierSuffix - modGroup = LootTable.modGroups.get(groupRow.getValueThree()); - - if (modGroup != null) { - - for (int a = 0; a < 10; a++) { - randomRoll = ThreadLocalRandom.current().nextInt(100) + 1; - modRow = modGroup.getLootRow(randomRoll); - if (modRow != null) - break; - } - - if (modRow != null) { - - subTableID = modRow.getValueOne(); - - if (LootTable.modTables.containsKey(subTableID)) { - - modTable = LootTable.modTables.get(subTableID); - randomRoll = gaussianLevel((int) calculatedMobLevel); - - if (randomRoll < modTable.minRoll) - randomRoll = (int) modTable.minRoll; - - if (randomRoll > modTable.maxRoll) - randomRoll = (int) modTable.maxRoll; - - modRow = modTable.getLootRow(randomRoll); - - if (modRow == null) - modRow = modTable.getLootRow((int) ((modTable.minRoll + modTable.maxRoll) * .05f)); - - if (modRow != null) { - suffixValue = modRow.getValueOne(); - modifierSuffix = modRow.getAction(); - } - } - } - } - } - - itemBase = ItemBase.getItemBase(itemBaseUUID); - - if (itemBase == null) - return; - - //Handle logging of drops - LootTable.HandleDropLogs(itemBase); - - if (itemBase.getType() == ItemType.OFFERING) - spawnQuanity = 1; - - if (spawnQuanity > 0) - mobLoot = new MobLoot(mob, itemBase, spawnQuanity, false); - else - mobLoot = new MobLoot(mob, itemBase, false); - - if (!modifierPrefix.isEmpty()) - mobLoot.addPermanentEnchantment(modifierPrefix, 0, prefixValue, true); - - if (!modifierSuffix.isEmpty()) - mobLoot.addPermanentEnchantment(modifierSuffix, 0, suffixValue, false); - - mobLoot.loadEnchantments(); - - loot.add(mobLoot); - - } - } - - private static void addMobLootResources(Mob mob, ArrayList loot, int mobLevel, int lootTableID, int cnt, boolean hotzone) { - - // Member variable declaration - float calculatedMobLevel; - int minSpawn; - int maxSpawn; - int spawnQuanity = 0; - - // Lookup Table Variables - LootTable lootTable; - LootRow lootRow; - LootTable lootGroup; - LootRow groupRow = null; - - // Used for actual generation of items - int itemBaseUUID; - ItemBase itemBase; - MobLoot mobLoot; - - if (!LootTable.lootGroups.containsKey(lootTableID)) - return; - - lootGroup = LootTable.lootGroups.get(lootTableID); - - calculatedMobLevel = mobLevel; - - if (calculatedMobLevel > 49) - calculatedMobLevel = 49; - - int roll = 0; - for (int i = 0; i < cnt; i++) { - - if (lootTableID == 1901) - groupRow = lootGroup.getLootRow(66); - else if (lootTableID == 1501) - groupRow = lootGroup.getLootRow(98); - else - groupRow = lootGroup.getLootRow(80); - - if (groupRow == null) - return; - - //get loot table for this group - - if (!LootTable.lootTables.containsKey(groupRow.getValueOne())) - return; - - lootTable = LootTable.lootTables.get(groupRow.getValueOne()); - - int minRoll = (int) ((calculatedMobLevel - 5) * 5); - int maxRoll = (int) ((calculatedMobLevel + 15) * 5); - - if (minRoll < (int) lootTable.minRoll) - minRoll = (int) lootTable.minRoll; - - if (maxRoll < minRoll) - maxRoll = minRoll; - - if (maxRoll > 320) - maxRoll = 320; - - roll = ThreadLocalRandom.current().nextInt(minRoll, maxRoll + 1); //Does not return Max, but does return min? - lootRow = lootTable.getLootRow(roll); //get the item row from the bell's curve of level +-15 - - if (lootRow == null) - continue; //no item found for roll - - itemBaseUUID = lootRow.getValueOne(); - - if (lootRow.getValueOne() == 0) - continue; - - //handle quantities > 1 for resource drops - - minSpawn = lootRow.getValueTwo(); - maxSpawn = lootRow.getValueThree(); - - // spawnQuanity between minspawn (inclusive) and maxspawn (inclusive) - - if (maxSpawn > 1) - spawnQuanity = ThreadLocalRandom.current().nextInt((maxSpawn + 1 - minSpawn)) + minSpawn; - - itemBase = ItemBase.getItemBase(itemBaseUUID); - - if (itemBase == null) - return; - - LootTable.HandleDropLogs(itemBase); - - switch (itemBase.getUUID()) { - case 19290: - continue; - case 19291: - continue; - case 19292: - continue; - case 27530: - continue; - case 973000: - continue; - case 973200: - continue; - - case 26360: - continue; - } - - // Handle drop rates of resources/runes/contracts. - // We intentionally drop them in half - - if (itemBase.getType() == ItemType.OFFERING) - spawnQuanity = 1; - - if (spawnQuanity > 0) - mobLoot = new MobLoot(mob, itemBase, spawnQuanity, false); - else - mobLoot = new MobLoot(mob, itemBase, false); - - loot.add(mobLoot); - - } - } - - public static int gaussianLevel(int level) { - int ret = -76; - - while (ret < -75 || ret > 75) { - ret = (int) (ThreadLocalRandom.current().nextGaussian() * 75); - } - - return (level * 5) + ret; - - } - - //This set's the drop chances for stat runes. - public static void populateStatRuneChances() { - //+3, Increased - statRuneChances.put(250018, 60); - statRuneChances.put(250009, 60); - statRuneChances.put(250027, 60); - statRuneChances.put(250036, 60); - statRuneChances.put(250000, 60); - - //+5, Enhanced - statRuneChances.put(250019, 60); - statRuneChances.put(250010, 60); - statRuneChances.put(250028, 60); - statRuneChances.put(250037, 60); - statRuneChances.put(250001, 60); - - //+10 Exceptional - statRuneChances.put(250020, 60); - statRuneChances.put(250011, 60); - statRuneChances.put(250029, 60); - statRuneChances.put(250038, 60); - statRuneChances.put(250002, 60); - - //+15, Amazing - statRuneChances.put(250021, 60); - statRuneChances.put(250012, 60); - statRuneChances.put(250030, 60); - statRuneChances.put(250039, 60); - statRuneChances.put(250003, 60); - - //+20, Incredible - statRuneChances.put(250022, 60); - statRuneChances.put(250013, 60); - statRuneChances.put(250031, 60); - statRuneChances.put(250040, 60); - statRuneChances.put(250004, 60); - - //+25, Great - statRuneChances.put(250023, 60); - statRuneChances.put(250014, 60); - statRuneChances.put(250032, 60); - statRuneChances.put(250041, 60); - statRuneChances.put(250005, 60); - - //+30, Heroic - statRuneChances.put(250024, 60); - statRuneChances.put(250015, 60); - statRuneChances.put(250033, 60); - statRuneChances.put(250042, 60); - statRuneChances.put(250006, 60); - - //+35, Legendary - statRuneChances.put(250025, 60); - statRuneChances.put(250016, 60); - statRuneChances.put(250034, 60); - statRuneChances.put(250043, 60); - statRuneChances.put(250007, 60); - - //+40, of the Gods - statRuneChances.put(250026, 60); - statRuneChances.put(250017, 60); - statRuneChances.put(250035, 60); - statRuneChances.put(250044, 60); - statRuneChances.put(250008, 60); - } - - private static void HandleDropLogs(ItemBase itemBase) { - - if (itemBase == null) - return; - - LootTable.dropCount++; //item dropped, add to all item count. - - - if (LootTable.itemsDroppedMap.get(itemBase) == null) { - LootTable.itemsDroppedMap.put(itemBase, 1); //First time dropping, make count 1. - } else { - int dropCount = LootTable.itemsDroppedMap.get(itemBase); - dropCount++; - LootTable.itemsDroppedMap.put(itemBase, dropCount); - } - - switch (itemBase.getType()) { - case RESOURCE: - LootTable.resourceCount++; - - if (LootTable.resourceDroppedMap.get(itemBase) == null) { - LootTable.resourceDroppedMap.put(itemBase, 1); //First time dropping, make count 1. - } else { - int dropCount = LootTable.resourceDroppedMap.get(itemBase); - dropCount++; - LootTable.resourceDroppedMap.put(itemBase, dropCount); - } - break; - case RUNE: - LootTable.runeCount++; - if (LootTable.runeDroppedMap.get(itemBase) == null) { - LootTable.runeDroppedMap.put(itemBase, 1); //First time dropping, make count 1. - } else { - int dropCount = LootTable.runeDroppedMap.get(itemBase); - dropCount++; - LootTable.runeDroppedMap.put(itemBase, dropCount); - } - break; - case CONTRACT: - LootTable.contractCount++; - - if (LootTable.contractDroppedMap.get(itemBase) == null) { - LootTable.contractDroppedMap.put(itemBase, 1); //First time dropping, make count 1. - } else { - int dropCount = LootTable.contractDroppedMap.get(itemBase); - dropCount++; - LootTable.contractDroppedMap.put(itemBase, dropCount); - } - - break; - case WEAPON: //Glass Drop - - if (itemBase.isGlass()) { - LootTable.glassCount++; - if (LootTable.glassDroppedMap.get(itemBase) == null) { - LootTable.glassDroppedMap.put(itemBase, 1); //First time dropping, make count 1. - } else { - int dropCount = LootTable.glassDroppedMap.get(itemBase); - dropCount++; - LootTable.glassDroppedMap.put(itemBase, dropCount); - } - } - - break; - } - - } - - public static Item CreateGamblerItem(Item item, PlayerCharacter gambler) { - - if (item == null) - return null; - - int groupID = 0; - - switch (item.getItemBase().getUUID()) { - case 971050: //Wrapped Axe - groupID = 3000; - break; - case 971051://Wrapped Great Axe - groupID = 3005; - break; - case 971052://Wrapped Throwing Axe - groupID = 3010; - break; - case 971053:// Wrapped Bow - groupID = 3015; - break; - case 971054://Wrapped Crossbow - groupID = 3020; - break; - case 971055: //Wrapped Dagger - groupID = 3025; - break; - case 971056: // Wrapped Throwing Dagger - groupID = 3030; - break; - case 971057: // Wrapped Hammer - groupID = 3035; - break; - case 971058:// Wrapped Great Hammer - groupID = 3040; - break; - case 971059:// Wrapped Throwing Hammer - groupID = 3045; - break; - case 971060:// Wrapped Polearm - groupID = 3050; - break; - case 971061:// Wrapped Spear - groupID = 3055; - break; - case 971062:// Wrapped Staff - groupID = 3060; - break; - case 971063:// Wrapped Sword - groupID = 3065; - break; - case 971064:// Wrapped Great Sword - groupID = 3070; - break; - case 971065:// Wrapped Unarmed Weapon - groupID = 3075; - break; - case 971066:// Wrapped Cloth Armor - groupID = 3100; - break; - case 971067:// Wrapped Light Armor - groupID = 3105; - break; - case 971068:// Wrapped Medium Armor - groupID = 3110; - break; - case 971069:// Wrapped Heavy Armor - groupID = 3115; - break; - case 971070:// Wrapped Rune - groupID = 3200; - break; - case 971071:// Wrapped City Improvement - groupID = 3210; - break; - } - //couldnt find group - if (groupID == 0) - return null; - - - LootTable lootGroup = LootTable.lootGroups.get(groupID); - - if (lootGroup == null) - return null; - float calculatedMobLevel; - int minSpawn; - int maxSpawn; - int spawnQuanity = 0; - int prefixValue = 0; - int suffixValue = 0; - int subTableID; - String modifierPrefix = ""; - String modifierSuffix = ""; - - // Lookup Table Variables - LootTable lootTable; - LootRow lootRow; - LootRow groupRow = null; - LootTable modTable; - LootTable modGroup; - LootRow modRow = null; - - // Used for actual generation of items - int itemBaseUUID; - ItemBase itemBase = null; - MobLoot mobLoot; - - - int roll = ThreadLocalRandom.current().nextInt(100) + 1; //Does not return Max, but does return min? - - groupRow = lootGroup.getLootRow(roll); - - lootTable = LootTable.lootTables.get(groupRow.getValueOne()); - roll = ThreadLocalRandom.current().nextInt(100) + 1; - lootRow = lootTable.getLootRow(roll + 220); //get the item row from the bell's curve of level +-15 - - if (lootRow == null) - return null; //no item found for roll - - itemBaseUUID = lootRow.getValueOne(); - - - if (lootRow.getValueOne() == 0) - return null; - - //handle quantities > 1 for resource drops - minSpawn = lootRow.getValueTwo(); - maxSpawn = lootRow.getValueThree(); - - // spawnQuanity between minspawn (inclusive) and maxspawn (inclusive) - if (maxSpawn > 1) - spawnQuanity = ThreadLocalRandom.current().nextInt((maxSpawn + 1 - minSpawn)) + minSpawn; - - - //get modifierPrefix - - calculatedMobLevel = 49; - - - int chanceMod = ThreadLocalRandom.current().nextInt(100) + 1; - - if (chanceMod < 25) { - modGroup = LootTable.modGroups.get(groupRow.getValueTwo()); - - if (modGroup != null) { - - - for (int a = 0; a < 10; a++) { - roll = ThreadLocalRandom.current().nextInt(100) + 1; - modRow = modGroup.getLootRow(roll); - if (modRow != null) - break; - } - - - if (modRow != null) { - subTableID = modRow.getValueOne(); - - if (LootTable.modTables.containsKey(subTableID)) { - - modTable = LootTable.modTables.get(subTableID); - - roll = gaussianLevel((int) calculatedMobLevel); - - if (roll < modTable.minRoll) - roll = (int) modTable.minRoll; - - if (roll > modTable.maxRoll) - roll = (int) modTable.maxRoll; - - - modRow = modTable.getLootRow(roll); - - if (modRow != null) { - prefixValue = modRow.getValueOne(); - modifierPrefix = modRow.getAction(); - } - } - } - } - } else if (chanceMod < 50) { - modGroup = LootTable.modGroups.get(groupRow.getValueThree()); - - if (modGroup != null) { - - for (int a = 0; a < 10; a++) { - roll = ThreadLocalRandom.current().nextInt(100) + 1; - modRow = modGroup.getLootRow(roll); - if (modRow != null) - break; - } - - if (modRow != null) { - - subTableID = modRow.getValueOne(); - - if (LootTable.modTables.containsKey(subTableID)) { - - modTable = LootTable.modTables.get(subTableID); - roll = gaussianLevel((int) calculatedMobLevel); - - if (roll < modTable.minRoll) - roll = (int) modTable.minRoll; - - if (roll > modTable.maxRoll) - roll = (int) modTable.maxRoll; - - modRow = modTable.getLootRow(roll); - - if (modRow == null) { - modRow = modTable.getLootRow((int) ((modTable.minRoll + modTable.maxRoll) * .05f)); - } - - if (modRow != null) { - suffixValue = modRow.getValueOne(); - modifierSuffix = modRow.getAction(); - } - } - } - } - } else { - modGroup = LootTable.modGroups.get(groupRow.getValueTwo()); - - if (modGroup != null) { - - - for (int a = 0; a < 10; a++) { - roll = ThreadLocalRandom.current().nextInt(100) + 1; - modRow = modGroup.getLootRow(roll); - if (modRow != null) - break; - } - - - if (modRow != null) { - subTableID = modRow.getValueOne(); - - if (LootTable.modTables.containsKey(subTableID)) { - - modTable = LootTable.modTables.get(subTableID); - - roll = gaussianLevel((int) calculatedMobLevel); - - if (roll < modTable.minRoll) - roll = (int) modTable.minRoll; - - if (roll > modTable.maxRoll) - roll = (int) modTable.maxRoll; - - - modRow = modTable.getLootRow(roll); - - if (modRow == null) { - modRow = modTable.getLootRow((int) ((modTable.minRoll + modTable.maxRoll) * .05f)); - } - - if (modRow != null) { - prefixValue = modRow.getValueOne(); - modifierPrefix = modRow.getAction(); - } - } - } - } - - //get modifierSuffix - modGroup = LootTable.modGroups.get(groupRow.getValueThree()); - - if (modGroup != null) { - - for (int a = 0; a < 10; a++) { - roll = ThreadLocalRandom.current().nextInt(100) + 1; - modRow = modGroup.getLootRow(roll); - if (modRow != null) - break; - } - - if (modRow != null) { - - subTableID = modRow.getValueOne(); - - if (LootTable.modTables.containsKey(subTableID)) { - - modTable = LootTable.modTables.get(subTableID); - roll = gaussianLevel((int) calculatedMobLevel); - - if (roll < modTable.minRoll) - roll = (int) modTable.minRoll; - - if (roll > modTable.maxRoll) - roll = (int) modTable.maxRoll; - - modRow = modTable.getLootRow(roll); - - if (modRow == null) { - modRow = modTable.getLootRow((int) ((modTable.minRoll + modTable.maxRoll) * .05f)); - } - - if (modRow != null) { - suffixValue = modRow.getValueOne(); - modifierSuffix = modRow.getAction(); - } - } - } - } - } - - - itemBase = ItemBase.getItemBase(itemBaseUUID); - byte charges = (byte) itemBase.getNumCharges(); - short dur = (short) itemBase.getDurability(); - - - short weight = itemBase.getWeight(); - if (!gambler.getCharItemManager().hasRoomInventory(weight)) { - return null; - } - - - Item gambledItem = new Item(itemBase, gambler.getObjectUUID(), - OwnerType.PlayerCharacter, charges, charges, dur, dur, - true, false, ItemContainerType.INVENTORY, (byte) 0, - new ArrayList<>(), ""); - - if (spawnQuanity == 0 && itemBase.getType().equals(ItemType.RESOURCE)) - spawnQuanity = 1; - - if (spawnQuanity > 0) - item.setNumOfItems(spawnQuanity); - - try { - gambledItem = DbManager.ItemQueries.ADD_ITEM(gambledItem); - - } catch (Exception e) { - Logger.error(e); - } - - if (gambledItem == null) { - - return null; - } - if (!modifierPrefix.isEmpty()) - gambledItem.addPermanentEnchantment(modifierPrefix, 0); - - if (!modifierSuffix.isEmpty()) - gambledItem.addPermanentEnchantment(modifierSuffix, 0); - - - //add item to inventory - gambler.getCharItemManager().addItemToInventory(gambledItem); - - gambler.getCharItemManager().updateInventory(); - - return gambledItem; - } - - public void addRow(float min, float max, int valueOne, int valueTwo, int valueThree, String action) { - - //hackey way to set the minimum roll for SHIAT! - if (min < this.minRoll) - this.minRoll = min; - - if (max > this.maxRoll) - this.maxRoll = max; - - int minInt = (int) min; - int maxInt = (int) max; - - //Round up min - if (minInt != min) { - min = minInt + 1; - } - - //Round down max; - if (maxInt != max) - max = maxInt; - - - LootRow lootRow = new LootRow(valueOne, valueTwo, valueThree, action); - for (int i = (int) min; i <= max; i++) { - lootTable.put(i, lootRow); - } - } - - public LootRow getLootRow(int probability) { - if (lootTable.containsKey(probability)) - return lootTable.get(probability); - return null; - } - - public ConcurrentHashMap getLootTable() { - return lootTable; - } - -} diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 109bad24..fc3b508c 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -13,17 +13,16 @@ import ch.claude_martin.enumbitset.EnumBitSet; import engine.Enum; import engine.Enum.*; import engine.InterestManagement.WorldGrid; -import engine.mobileAI.Threads.MobAIThread; import engine.exception.SerializationException; import engine.gameManager.*; import engine.job.JobScheduler; import engine.jobs.DeferredPowerJob; import engine.jobs.UpgradeNPCJob; -import engine.loot.LootManager; import engine.math.Bounds; import engine.math.Quaternion; import engine.math.Vector3f; import engine.math.Vector3fImmutable; +import engine.mobileAI.Threads.MobAIThread; import engine.net.ByteBufferWriter; import engine.net.Dispatch; import engine.net.DispatchMessage; diff --git a/src/engine/objects/MobBase.java b/src/engine/objects/MobBase.java index 1c8fa548..66620a25 100644 --- a/src/engine/objects/MobBase.java +++ b/src/engine/objects/MobBase.java @@ -13,6 +13,7 @@ import ch.claude_martin.enumbitset.EnumBitSet; import engine.Enum; import engine.gameManager.DbManager; import engine.gameManager.NPCManager; +import engine.loot.BootySetEntry; import engine.server.MBServerStatics; import java.sql.ResultSet; diff --git a/src/engine/objects/MobLootBase.java b/src/engine/objects/MobLootBase.java deleted file mode 100644 index e7a64b28..00000000 --- a/src/engine/objects/MobLootBase.java +++ /dev/null @@ -1,59 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2022 -// www.magicbane.com - - -package engine.objects; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; - -public class MobLootBase { - - public static HashMap> MobLootSet = new HashMap<>(); - private int mobBaseID; - private int lootTableID; - private float chance; - - - /** - * ResultSet Constructor - */ - - public MobLootBase(ResultSet rs) throws SQLException { - this.mobBaseID = rs.getInt("mobBaseID"); - this.lootTableID = rs.getInt("lootTable"); - this.chance = rs.getFloat("chance"); - } - - public MobLootBase(int mobBaseID, int lootTableID, int chance) { - super(); - this.mobBaseID = mobBaseID; - this.lootTableID = lootTableID; - this.chance = chance; - - } - - public int getMobBaseID() { - return mobBaseID; - } - - public float getChance() { - return chance; - } - - public int getLootTableID() { - return lootTableID; - } - - public void setLootTableID(int lootTableID) { - this.lootTableID = lootTableID; - } - -} diff --git a/src/engine/objects/NPC.java b/src/engine/objects/NPC.java index e4851196..ae21de63 100644 --- a/src/engine/objects/NPC.java +++ b/src/engine/objects/NPC.java @@ -1310,20 +1310,47 @@ public class NPC extends AbstractCharacter { if (this.canRoll == null) { this.canRoll = DbManager.ItemQueries.GET_ITEMS_FOR_VENDOR(this.vendorID); - + } + HashSet fullItemList = this.canRoll; + HashSet returnIDs = new HashSet<>(); + short maxSkill = 25; + switch(this.getRank()){ + case 1: + maxSkill = 25; + break; + case 2: + maxSkill = 50; + break; + case 3: + case 4: + maxSkill = 75; + break; + case 5: + case 6: + maxSkill = 100; + break; + case 7: + maxSkill = 110; + break; + } + for(Integer itemID : fullItemList){ + if(ItemBase.getItemBase(itemID).getPercentRequired() <= maxSkill){ + returnIDs.add(itemID); + } + } if (this.contract.getVendorID() == 102) { for (int i = 0; i < this.getRank(); i++) { int subID = i + 1; - this.canRoll.add(910010 + subID); + returnIDs.add(910010 + subID); } if (this.getRank() == 7) - this.canRoll.add(910018); + returnIDs.add(910018); } - } + //} - return this.canRoll; + return returnIDs; } public int getRollingTimeInSeconds(int itemID) { diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index b7b520e6..cdcf6f90 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -17,15 +17,14 @@ import engine.Enum.SupportMsgType; import engine.InterestManagement.HeightMap; import engine.InterestManagement.RealmMap; import engine.InterestManagement.WorldGrid; -import engine.mobileAI.Threads.MobAIThread; -import engine.mobileAI.Threads.MobRespawnThread; import engine.db.archive.DataWarehouse; import engine.exception.MsgSendException; import engine.gameManager.*; import engine.job.JobContainer; import engine.job.JobScheduler; import engine.jobs.LogoutCharacterJob; -import engine.loot.LootManager; +import engine.mobileAI.Threads.MobAIThread; +import engine.mobileAI.Threads.MobRespawnThread; import engine.net.Dispatch; import engine.net.DispatchMessage; import engine.net.ItemProductionManager; @@ -338,11 +337,9 @@ public class WorldServer { NPCManager.LoadAllBootySets(); // Load new loot system - Logger.info("Loading New Loot Tables"); - LootManager.loadLootData(); + Logger.info("Initializing Loot Manager"); + LootManager.init(); - //load old loot system (still needed for rolling for now) - LootTable.populateLootTables(); RuneBaseAttribute.LoadAllAttributes(); RuneBase.LoadAllRuneBases(); BaseClass.LoadAllBaseClasses(); @@ -507,7 +504,6 @@ public class WorldServer { Logger.info("Bootstrap time was " + boottime); bootTime = LocalDateTime.now(); - LootTable.initialized = true; Logger.info("Running garbage collection..."); System.gc();