package server.life; import client.inventory.MapleInventoryType; import constants.ItemConstants; import database.DatabaseConnection; import java.io.File; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import provider.MapleData; import provider.MapleDataProvider; import provider.MapleDataProviderFactory; import provider.MapleDataTool; import server.MapleItemInformationProvider; import server.StructFamiliar; import tools.Pair; public class MapleMonsterInformationProvider { private static final MapleMonsterInformationProvider instance = new MapleMonsterInformationProvider(); private final Map<Integer, String> mobCache = new TreeMap(); private final Map<Integer, ArrayList<MonsterDropEntry>> drops = new HashMap(); private final List<MonsterGlobalDropEntry> globaldrops = new ArrayList(); private static final MapleDataProvider stringDataWZ = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath", "wz") + "/String.wz")); public static MapleMonsterInformationProvider getInstance() { return instance; } public List<MonsterGlobalDropEntry> getGlobalDrop() { return this.globaldrops; } public void load() { PreparedStatement ps = null; ResultSet rs = null; try { Connection con = DatabaseConnection.getConnection(); ps = con.prepareStatement("SELECT * FROM drop_data_global WHERE chance > 0"); rs = ps.executeQuery(); while (rs.next()) { this.globaldrops.add(new MonsterGlobalDropEntry(rs.getInt("itemid"), rs.getInt("chance"), rs.getInt("continent"), rs.getByte("dropType"), rs.getInt("minimum_quantity"), rs.getInt("maximum_quantity"), rs.getInt("questid"))); } rs.close(); ps.close(); ps = con.prepareStatement("SELECT mobID FROM drop_data"); List mobIds = new ArrayList(); rs = ps.executeQuery(); while (rs.next()) { int mobId = rs.getInt("mobID"); if (!mobIds.contains(mobId)) { loadDrop(mobId); mobIds.add(mobId); } } } catch (SQLException ignore) { System.err.println("Error retrieving drop" + ignore); } finally { try { if (ps != null) { ps.close(); } if (rs != null) { rs.close(); } } catch (SQLException ignore) { } } } public ArrayList<MonsterDropEntry> retrieveDrop(int monsterId) { return (ArrayList) this.drops.get(monsterId); } private void loadDrop(int monsterId) { ArrayList ret = new ArrayList(); PreparedStatement ps = null; ResultSet rs = null; try { MapleMonsterStats mons = MapleLifeFactory.getMonsterStats(monsterId); if (mons == null) { return; } ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM drop_data WHERE mobID = ?"); ps.setInt(1, monsterId); rs = ps.executeQuery(); while (rs.next()) { int itemid = rs.getInt("itemid"); int chance = rs.getInt("chance"); ret.add(new MonsterDropEntry(itemid, chance, rs.getInt("minimum_quantity"), rs.getInt("maximum_quantity"), rs.getInt("questid"))); } } catch (SQLException ignore) { System.err.println("Error retrieving drop" + ignore); } finally { try { if (ps != null) { ps.close(); } if (rs != null) { rs.close(); } } catch (SQLException ignore) { return; } } this.drops.put(monsterId, ret); } public void addExtra() { MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); for (Map.Entry e : this.drops.entrySet()) { for (int i = 0; i < ((ArrayList) e.getValue()).size(); i++) { if ((((MonsterDropEntry) ((ArrayList) e.getValue()).get(i)).itemId != 0) && (!ii.itemExists(((MonsterDropEntry) ((ArrayList) e.getValue()).get(i)).itemId))) { ((ArrayList) e.getValue()).remove(i); } } MapleMonsterStats mons = MapleLifeFactory.getMonsterStats(((Integer) e.getKey()).intValue()); Integer item = ii.getItemIdByMob(((Integer) e.getKey()).intValue()); if ((item != null) && (item > 0)) { if (item / 10000 == 238) { continue; } ((ArrayList) e.getValue()).add(new MonsterDropEntry(item, mons.isBoss() ? 1000000 : 10000, 1, 1, 0)); } StructFamiliar f = ii.getFamiliarByMob(((Integer) e.getKey()).intValue()); if (f != null) { if (f.itemid / 10000 == 238) { continue; } ((ArrayList) e.getValue()).add(new MonsterDropEntry(f.itemid, mons.isBoss() ? 10000 : 100, 1, 1, 0)); } } for (StructFamiliar f : ii.getFamiliars().values()) { if (!this.drops.containsKey(f.mob)) { MapleMonsterStats mons = MapleLifeFactory.getMonsterStats(f.mob); ArrayList e = new ArrayList(); if (f.itemid / 10000 == 238) { continue; } e.add(new MonsterDropEntry(f.itemid, mons.isBoss() ? 10000 : 100, 1, 1, 0)); addMeso(mons, e); this.drops.put(f.mob, e); } } } public void addMeso(MapleMonsterStats mons, ArrayList<MonsterDropEntry> ret) { double divided = mons.getLevel() < 100 ? 10.0D : mons.getLevel() < 10 ? mons.getLevel() : mons.getLevel() / 10.0D; int maxMeso = mons.getLevel() * (int) Math.ceil(mons.getLevel() / divided); if ((mons.isBoss()) && (!mons.isPartyBonus())) { maxMeso *= 3; } for (int i = 0; i < mons.dropsMesoCount(); i++) { if ((mons.getId() >= 9600086) && (mons.getId() <= 9600098)) { int meso = (int) Math.floor(Math.random() * 500.0D + 1000.0D); ret.add(new MonsterDropEntry(0, 20000, (int) Math.floor(0.46D * meso), meso, 0)); } else { ret.add(new MonsterDropEntry(0, mons.isPartyBonus() ? 40000 : (mons.isBoss()) && (!mons.isPartyBonus()) ? 800000 : 40000, (int) Math.floor(0.66D * maxMeso), maxMeso, 0)); } } } public void clearDrops() { this.drops.clear(); this.globaldrops.clear(); load(); addExtra(); } public boolean contains(ArrayList<MonsterDropEntry> e, int toAdd) { for (MonsterDropEntry f : e) { if (f.itemId == toAdd) { return true; } } return false; } public int chanceLogic(int itemId) { switch (itemId) { case 2049301: case 2049401: case 4280000: case 4280001: return 5000; case 1002419: case 2049300: case 2049400: return 2000; case 1002938: return 50; } if (ItemConstants.getInventoryType(itemId) == MapleInventoryType.EQUIP) { return 8000; } if ((ItemConstants.getInventoryType(itemId) == MapleInventoryType.SETUP) || (ItemConstants.getInventoryType(itemId) == MapleInventoryType.CASH)) { return 500; } switch (itemId / 10000) { case 204: return 1800; case 207: case 233: return 3000; case 229: return 400; case 401: case 402: return 5000; case 403: return 4000; } return 8000; } public Map<Integer, String> getAllMonsters() { if (mobCache.isEmpty()) { final MapleDataProvider stringData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath", "wz") + "//String.wz")); MapleData mobsData = stringData.getData("Mob.img"); for (MapleData itemFolder : mobsData.getChildren()) { mobCache.put(Integer.parseInt(itemFolder.getName()), MapleDataTool.getString("name", itemFolder, "NO-NAME")); } } return mobCache; } }