[教程分享] 掉落强化物品如题增加的部分表示,关于游戏对服务端需要修改的JAVA文件表示: =========================================================================================== NpcTable.java try { PreparedStatement statement2 = con.prepareStatement("SELECT " + L2DatabaseFactory.getInstance().safetyString(new String[] { "mobId", "itemId", "min", "max","EnchantLevel", "category", "chance" }) + " FROM droplist ORDER BY mobId, chance DESC"); ResultSet dropData = statement2.executeQuery(); L2DropData dropDat = null; L2NpcTemplate npcDat = null; int cCount = 0; while (dropData.next()) { int mobId = dropData.getInt("mobId"); npcDat = _npcs.get(mobId); if (npcDat == null) { _log.warning("WARNING 掉落物品表: 不存在的Npc.I d: " + mobId); continue; } dropDat = new L2DropData(); dropDat.setItemId(dropData.getInt("itemId")); dropDat.setMinDrop(dropData.getInt("min")); dropDat.setMaxDrop(dropData.getInt("max")); dropDat.setChance(dropData.getInt("chance")); dropDat.setEnchantLevel(dropData.getInt("EnchantLevel")); int category = dropData.getInt("category"); if (ItemTable.getInstance().getTemplate(dropDat.getItemId()) == null) { _log.warning("WARNING 掉落物品表: 不存在的物品: 物品I d: "+dropDat.getItemId()); continue; } npcDat.addDropData(dropDat, category); cCount++; } dropData.close(); statement2.close(); _log.info("INFO 从掉落表中读取 " + cCount + " 个掉落物品数据."); } catch (Exception e) { _log.log(Level.SEVERE, "ERROR 无法初始化掉落物品表!原 因:"+ e.getMessage()); } if (Config.CUSTOM_DROPLIST_TABLE) { try { PreparedStatement statement2 = con.prepareStatement("SELECT " + L2DatabaseFactory.getInstance().safetyString(new String[] { "mobId", "itemId", "min", "max","EnchantLevel", "category", "chance" }) + " FROM custom_droplist ORDER BY mobId, chance DESC"); ResultSet dropData = statement2.executeQuery(); L2DropData dropDat = null; L2NpcTemplate npcDat = null; int cCount = 0; while (dropData.next()) { int mobId = dropData.getInt("mobId"); npcDat = _npcs.get(mobId); if (npcDat == null) { _log.warning("WARNING 新天堂2自定义-自定义掉落物品表: 不存在的Npc.I d: " + mobId); continue; } dropDat = new L2DropData(); dropDat.setItemId(dropData.getInt("itemId")); dropDat.setMinDrop(dropData.getInt("min")); dropDat.setMaxDrop(dropData.getInt("max")); dropDat.setEnchantLevel(dropData.getInt("EnchantLevel")); dropDat.setChance(dropData.getInt("chance")); int category = dropData.getInt("category"); if (ItemTable.getInstance().getTemplate(dropDat.getItemId()) == null) { _log.warning("WARNING 新天堂2自定义-掉落物品表: 不存在的物品: 物品I d: "+dropDat.getItemId()); continue; } npcDat.addDropData(dropDat, category); cCount++; } dropData.close(); statement2.close(); _log.info("INFO 就玩天堂2私服发布www.9wtt2.com 掉宝管理 读取 " + cCount + " 个自定掉宝"); } catch (Exception e) { _log.log(Level.SEVERE, "ERROR 无法初始化自定义掉落物品表!原 因:"+ e.getMessage()); } =========================================================================================== L2DropData.java public class L2DropData { public static final int MAX_CHANCE = 1000000; private int _itemId; private int _minDrop; private int _maxDrop; private int _EnchantLevel; private int _chance; private String _questID = null; private String[] _stateID = null; public int getMaxDrop() { return _maxDrop; } public int getEnchantLevel() { return _EnchantLevel; } public void setMaxDrop(int maxdrop) { _maxDrop = maxdrop; } public void setEnchantLevel(int EnchantLevel) { _EnchantLevel = EnchantLevel; } =========================================================================================== L2AttackAble.java public final class RewardItem { protected int _itemId; protected int _EnchantLevel; protected int _count; public RewardItem(int itemId, int count , int EnchantLevel) { _itemId = itemId; _EnchantLevel = EnchantLevel; _count = count; } public RewardItem(int itemId, int count) { _itemId = itemId; _EnchantLevel = 0; _count = count; } private RewardItem calculateCategorizedRewardItem(L2PcInstance lastAttacker, L2DropCategory categoryDrops, int levelModifier) { if (categoryDrops == null) return null; // Get default drop chance for the category (that's the sum of chances for all items in the category) // keep track of the base category chance as it'll be used later, if an item is drop from the category. // for everything else, use the total "categoryDropChance" int basecategoryDropChance = categoryDrops.getCategoryChance() ; int categoryDropChance = basecategoryDropChance; int deepBlueDrop = 1; if ((!isRaid() && Config.DEEPBLUE_DROP_RULES) || (isRaid() && Config.DEEPBLUE_DROP_RULES_RAID)) { // We should multiply by the server's drop rate, so we always get a low chance of drop for deep blue mobs. // NOTE: This is valid only for adena drops! Others drops will still obey server's rate if (levelModifier > 0) deepBlueDrop = 3; } // Avoid dividing by 0 if (deepBlueDrop == 0) deepBlueDrop = 1; // Check if we should apply our maths so deep blue mobs will not drop that easy if ((!isRaid() && Config.DEEPBLUE_DROP_RULES) || (isRaid() && Config.DEEPBLUE_DROP_RULES_RAID)) categoryDropChance = ((categoryDropChance - ((categoryDropChance * levelModifier)/100)) / deepBlueDrop); // Applies Drop rates if (lastAttacker.getPremiumService()==1) categoryDropChance *= isRaid() && !isRaidMinion() ? Config.RATE_DROP_ITEMS_BY_RAID : Config.PREMIUM_RATE_DROP_ITEMS; else categoryDropChance *= isRaid() && !isRaidMinion() ? Config.RATE_DROP_ITEMS_BY_RAID : Config.RATE_DROP_ITEMS; if (Config.L2JMOD_CHAMPION_ENABLE && isChampion()) categoryDropChance *= Config.L2JMOD_CHAMPION_REWARDS; // Round drop chance categoryDropChance = Math.round(categoryDropChance); // Set our limits for chance of drop if (categoryDropChance < 1) categoryDropChance = 1; // Check if an Item from this category must be dropped if (Rnd.get(L2DropData.MAX_CHANCE) < categoryDropChance) { L2DropData drop = categoryDrops.dropOne(isRaid() && !isRaidMinion()); if (drop == null) return null; // Now decide the quantity to drop based on the rates and penalties. To get this value // simply divide the modified categoryDropChance by the base category chance. This // results in a chance that will dictate the drops amounts: for each amount over 100 // that it is, it will give another chance to add to the min/max quantities. // For example, If the final chance is 120%, then the item should drop between // its min and max one time, and then have 20% chance to drop again. If the final // chance is 330%, it will similarly give 3 times the min and max, and have a 30% // chance to give a 4th time. // At least 1 item will be dropped for sure. So the chance will be adjusted to 100% // if smaller. int dropChance = drop.getChance(); if (Config.PREMIUM_RATE_DROP_ITEMS_ID.get(drop.getItemId()) != 0 && lastAttacker.getPremiumService()==1) dropChance *= Config.PREMIUM_RATE_DROP_ITEMS_ID.get(drop.getItemId()); if (Config.RATE_DROP_ITEMS_ID.get(drop.getItemId()) != 0) dropChance *= Config.RATE_DROP_ITEMS_ID.get(drop.getItemId()); else dropChance *= isRaid() && !isRaidMinion() ? Config.RATE_DROP_ITEMS_BY_RAID : Config.RATE_DROP_ITEMS; if (Config.L2JMOD_CHAMPION_ENABLE && isChampion()) dropChance *= Config.L2JMOD_CHAMPION_REWARDS; dropChance = Math.round(dropChance); if (dropChance < L2DropData.MAX_CHANCE) dropChance = L2DropData.MAX_CHANCE; // Get min and max Item quantity that can be dropped in one time int min = drop.getMinDrop(); int max = drop.getMaxDrop(); // Get the item quantity dropped int itemCount = 0; // Count and chance adjustment for high rate servers if (dropChance > L2DropData.MAX_CHANCE && !Config.PRECISE_DROP_CALCULATION) { int multiplier = dropChance / L2DropData.MAX_CHANCE; if (min < max) itemCount += Rnd.get(min * multiplier, max * multiplier); else if (min == max) itemCount += min * multiplier; else itemCount += multiplier; dropChance = dropChance % L2DropData.MAX_CHANCE; } // Check if the Item must be dropped int random = Rnd.get(L2DropData.MAX_CHANCE); while (random < dropChance) { // Get the item quantity dropped if (min < max) itemCount += Rnd.get(min, max); else if (min == max) itemCount += min; else itemCount++; // Prepare for next iteration if dropChance > L2DropData.MAX_CHANCE dropChance -= L2DropData.MAX_CHANCE; } if (Config.L2JMOD_CHAMPION_ENABLE) // TODO (April 11, 2009): Find a way not to hardcode these values. if ((drop.getItemId() == 57 || (drop.getItemId() >= 6360 && drop.getItemId() <= 6362)) && isChampion()) itemCount *= Config.L2JMOD_CHAMPION_ADENAS_REWARDS; if (!Config.MULTIPLE_ITEM_DROP && !ItemTable.getInstance().getTemplate(drop.getItemId()).isStackable() && itemCount > 1) itemCount = 1; if (itemCount > 0) return new RewardItem(drop.getItemId(), itemCount ,drop.getEnchantLevel()); } return null; } private RewardItem calculateRewardItem(L2PcInstance lastAttacker, L2DropData drop, int levelModifier, boolean isSweep) { // Get default drop chance float dropChance = drop.getChance(); int deepBlueDrop = 1; if ((!isRaid() && Config.DEEPBLUE_DROP_RULES) || (isRaid() && Config.DEEPBLUE_DROP_RULES_RAID)) { if (levelModifier > 0) { // We should multiply by the server's drop rate, so we always get a low chance of drop for deep blue mobs. // NOTE: This is valid only for adena drops! Others drops will still obey server's rate deepBlueDrop = 3; if (drop.getItemId() == 57) deepBlueDrop *= isRaid() && !isRaidMinion()? (int)Config.RATE_DROP_ITEMS_BY_RAID : (int)Config.RATE_DROP_ITEMS; } } // Avoid dividing by 0 if (deepBlueDrop == 0) deepBlueDrop = 1; // Check if we should apply our maths so deep blue mobs will not drop that easy if ((!isRaid() && Config.DEEPBLUE_DROP_RULES) || (isRaid() && Config.DEEPBLUE_DROP_RULES_RAID)) dropChance = ((drop.getChance() - ((drop.getChance() * levelModifier)/100)) / deepBlueDrop); // Applies Drop rates if (Config.PREMIUM_RATE_DROP_ITEMS_ID.get(drop.getItemId()) != 0 && lastAttacker.getPremiumService()==1) dropChance *= Config.PREMIUM_RATE_DROP_ITEMS_ID.get(drop.getItemId()); else if (Config.RATE_DROP_ITEMS_ID.get(drop.getItemId()) != 0) dropChance *= Config.RATE_DROP_ITEMS_ID.get(drop.getItemId()); else if (isSweep) { if (lastAttacker.getPremiumService()==1) dropChance *= Config.PREMIUM_RATE_DROP_SPOIL; else dropChance *= Config.RATE_DROP_SPOIL; } else if (lastAttacker.getPremiumService()==1) dropChance *= isRaid() && !isRaidMinion() ? Config.RATE_DROP_ITEMS_BY_RAID : Config.PREMIUM_RATE_DROP_ITEMS; else dropChance *= isRaid() && !isRaidMinion() ? Config.RATE_DROP_ITEMS_BY_RAID : Config.RATE_DROP_ITEMS; if (Config.L2JMOD_CHAMPION_ENABLE && isChampion()) dropChance *= Config.L2JMOD_CHAMPION_REWARDS; // Round drop chance dropChance = Math.round(dropChance); // Set our limits for chance of drop if (dropChance < 1) dropChance = 1; // Get min and max Item quantity that can be dropped in one time int minCount = drop.getMinDrop(); int maxCount = drop.getMaxDrop(); int itemCount = 0; // Count and chance adjustment for high rate servers if (dropChance > L2DropData.MAX_CHANCE && !Config.PRECISE_DROP_CALCULATION) { int multiplier = (int)dropChance / L2DropData.MAX_CHANCE; if (minCount < maxCount) itemCount += Rnd.get(minCount * multiplier, maxCount * multiplier); else if (minCount == maxCount) itemCount += minCount * multiplier; else itemCount += multiplier; dropChance = dropChance % L2DropData.MAX_CHANCE; } // Check if the Item must be dropped int random = Rnd.get(L2DropData.MAX_CHANCE); while (random < dropChance) { // Get the item quantity dropped if (minCount < maxCount) itemCount += Rnd.get(minCount, maxCount); else if (minCount == maxCount) itemCount += minCount; else itemCount++; // Prepare for next iteration if dropChance > L2DropData.MAX_CHANCE dropChance -= L2DropData.MAX_CHANCE; } if (Config.L2JMOD_CHAMPION_ENABLE) // TODO (April 11, 2009): Find a way not to hardcode these values. if ((drop.getItemId() == 57 || (drop.getItemId() >= 6360 && drop.getItemId() <= 6362)) && isChampion()) itemCount *= Config.L2JMOD_CHAMPION_ADENAS_REWARDS; if (itemCount > 0) return new RewardItem(drop.getItemId(), itemCount ,drop.getEnchantLevel()); return null; } public L2ItemInstance dropItem(L2PcInstance lastAttacker, RewardItem item) { int randDropLim = 70; L2ItemInstance ditem = null; for (int i = 0; i < item.getCount(); i++) { // Randomize drop position int newX = getX() + Rnd.get(randDropLim * 2 + 1) - randDropLim; int newY = getY() + Rnd.get(randDropLim * 2 + 1) - randDropLim; int newZ = Math.max(getZ(), lastAttacker.getZ()) + 20; // TODO: temp hack, do somethign nicer when we have geodatas if (ItemTable.getInstance().getTemplate(item.getItemId()) != null) { // Init the dropped L2ItemInstance and add it in the world as a visible object at the position where mob was last ditem = ItemTable.getInstance().createItem("Loot", item.getItemId(), item.getCount(), lastAttacker, this); ditem.dropMe(this, newX, newY, newZ); ditem.setEnchantLevel(item._EnchantLevel); // Add drop to auto destroy item task if (!Config.LIST_PROTECTED_ITEMS.contains(item.getItemId())) { if ((Config.AUTODESTROY_ITEM_AFTER > 0 && ditem.getItemType() != L2EtcItemType.HERB) || (Config.HERB_AUTO_DESTROY_TIME > 0 && ditem.getItemType() == L2EtcItemType.HERB)) ItemsAutoDestroy.getInstance().addItem(ditem); } ditem.setProtected(false); // If stackable, end loop as entire count is included in 1 instance of item if (ditem.isStackable() || !Config.MULTIPLE_ITEM_DROP) break; } else _log.log(Level.SEVERE, "Item doesn't exist so cannot be dropped. Item ID: " + item.getItemId()); } return ditem; } =========================================================================================== 最后在天堂2私服数据库查询量句SQL语句 ALTER TABLE `droplist` ADD `EnchantLevel` INT( 10 ) NOT NULL DEFAULT '0' ALTER TABLE `custom_droplist` ADD `EnchantLevel` INT( 10 ) NOT NULL DEFAULT '0' =========================================================================================== (责任编辑:tt2sf) |