Drops rework.

This commit is contained in:
MobiusDev
2017-10-06 00:53:49 +00:00
parent 2c61857b12
commit fc94704b2d
408 changed files with 741952 additions and 835872 deletions

View File

@@ -265,7 +265,7 @@ public class AdminAdmin implements IAdminCommandHandler
}
case "RateDropSpoil":
{
Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER = Float.valueOf(pValue);
Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER = Float.valueOf(pValue);
break;
}
case "EnchantChanceElementStone":
@@ -462,7 +462,7 @@ public class AdminAdmin implements IAdminCommandHandler
replyMSG.append("<tr><td><font color=\"00AA00\">Drop:</font></td><td></td><td></td></tr>");
replyMSG.append("<tr><td><font color=\"LEVEL\">Rate EXP</font> = " + Config.RATE_XP + "</td><td><edit var=\"param1\" width=40 height=15></td><td><button value=\"Set\" action=\"bypass -h admin_setconfig RateXp $param1\" width=40 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr>");
replyMSG.append("<tr><td><font color=\"LEVEL\">Rate SP</font> = " + Config.RATE_SP + "</td><td><edit var=\"param2\" width=40 height=15></td><td><button value=\"Set\" action=\"bypass -h admin_setconfig RateSp $param2\" width=40 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr>");
replyMSG.append("<tr><td><font color=\"LEVEL\">Rate Drop Spoil</font> = " + Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER + "</td><td><edit var=\"param4\" width=40 height=15></td><td><button value=\"Set\" action=\"bypass -h admin_setconfig RateDropSpoil $param4\" width=40 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr>");
replyMSG.append("<tr><td><font color=\"LEVEL\">Rate Drop Spoil</font> = " + Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER + "</td><td><edit var=\"param4\" width=40 height=15></td><td><button value=\"Set\" action=\"bypass -h admin_setconfig RateDropSpoil $param4\" width=40 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr>");
replyMSG.append("<tr><td width=140></td><td width=40></td><td width=40></td></tr>");
replyMSG.append("<tr><td><font color=\"00AA00\">Enchant:</font></td><td></td><td></td></tr>");
replyMSG.append("<tr><td><font color=\"LEVEL\">Enchant Element Stone</font> = " + Config.ENCHANT_CHANCE_ELEMENT_STONE + "</td><td><edit var=\"param8\" width=40 height=15></td><td><button value=\"Set\" action=\"bypass -h admin_setconfig EnchantChanceElementStone $param8\" width=40 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr>");

View File

@@ -18,14 +18,15 @@ package handlers.bypasshandlers;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.TimeUnit;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.CommonUtil;
import com.l2jmobius.gameserver.cache.HtmCache;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.AttributeType;
import com.l2jmobius.gameserver.enums.DropType;
import com.l2jmobius.gameserver.handler.IBypassHandler;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2Spawn;
@@ -34,10 +35,7 @@ import com.l2jmobius.gameserver.model.actor.L2Attackable;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.drops.DropListScope;
import com.l2jmobius.gameserver.model.drops.GeneralDropItem;
import com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem;
import com.l2jmobius.gameserver.model.drops.IDropItem;
import com.l2jmobius.gameserver.model.holders.DropHolder;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.util.HtmlUtil;
@@ -106,10 +104,10 @@ public class NpcViewMod implements IBypassHandler
return false;
}
final String dropListScopeString = st.nextToken();
final String dropListTypeString = st.nextToken();
try
{
final DropListScope dropListScope = Enum.valueOf(DropListScope.class, dropListScopeString);
final DropType dropListType = Enum.valueOf(DropType.class, dropListTypeString);
final L2Object target = L2World.getInstance().findObject(Integer.parseInt(st.nextToken()));
final L2Npc npc = target instanceof L2Npc ? (L2Npc) target : null;
if (npc == null)
@@ -117,7 +115,7 @@ public class NpcViewMod implements IBypassHandler
return false;
}
final int page = st.hasMoreElements() ? Integer.parseInt(st.nextToken()) : 0;
sendNpcDropList(activeChar, npc, dropListScope, page);
sendNpcDropList(activeChar, npc, dropListType, page);
}
catch (NumberFormatException e)
{
@@ -125,7 +123,7 @@ public class NpcViewMod implements IBypassHandler
}
catch (IllegalArgumentException e)
{
_log.warning("Bypass[NpcViewMod] unknown drop list scope: " + dropListScopeString);
_log.warning("Bypass[NpcViewMod] unknown drop list scope: " + dropListTypeString);
return false;
}
break;
@@ -336,21 +334,22 @@ public class NpcViewMod implements IBypassHandler
activeChar.sendPacket(html);
}
public static String getDropListButtons(L2Npc npc)
private static String getDropListButtons(L2Npc npc)
{
final StringBuilder sb = new StringBuilder();
final Map<DropListScope, List<IDropItem>> dropLists = npc.getTemplate().getDropLists();
if ((dropLists != null) && !dropLists.isEmpty() && (dropLists.containsKey(DropListScope.DEATH) || dropLists.containsKey(DropListScope.CORPSE)))
final List<DropHolder> dropListDeath = npc.getTemplate().getDropList(DropType.DROP);
final List<DropHolder> dropListSpoil = npc.getTemplate().getDropList(DropType.SPOIL);
if ((dropListDeath != null) || (dropListSpoil != null))
{
sb.append("<table width=275 cellpadding=0 cellspacing=0><tr>");
if (dropLists.containsKey(DropListScope.DEATH))
if (dropListDeath != null)
{
sb.append("<td align=center><button value=\"Show Drop\" width=100 height=25 action=\"bypass NpcViewMod dropList DEATH " + npc.getObjectId() + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
sb.append("<td align=center><button value=\"Show Drop\" width=100 height=25 action=\"bypass NpcViewMod dropList DROP " + npc.getObjectId() + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
}
if (dropLists.containsKey(DropListScope.CORPSE))
if (dropListSpoil != null)
{
sb.append("<td align=center><button value=\"Show Spoil\" width=100 height=25 action=\"bypass NpcViewMod dropList CORPSE " + npc.getObjectId() + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
sb.append("<td align=center><button value=\"Show Spoil\" width=100 height=25 action=\"bypass NpcViewMod dropList SPOIL " + npc.getObjectId() + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
}
sb.append("</tr></table>");
@@ -358,10 +357,10 @@ public class NpcViewMod implements IBypassHandler
return sb.toString();
}
public static void sendNpcDropList(L2PcInstance activeChar, L2Npc npc, DropListScope dropListScope, int page)
private static void sendNpcDropList(L2PcInstance activeChar, L2Npc npc, DropType dropType, int page)
{
final List<IDropItem> dropList = npc.getTemplate().getDropList(dropListScope);
if ((dropList == null) || dropList.isEmpty())
final List<DropHolder> dropList = npc.getTemplate().getDropList(dropType);
if (dropList == null)
{
return;
}
@@ -378,7 +377,7 @@ public class NpcViewMod implements IBypassHandler
pagesSb.append("<table><tr>");
for (int i = 0; i < pages; i++)
{
pagesSb.append("<td align=center><button value=\"" + (i + 1) + "\" width=20 height=20 action=\"bypass NpcViewMod dropList " + dropListScope + " " + npc.getObjectId() + " " + i + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
pagesSb.append("<td align=center><button value=\"" + (i + 1) + "\" width=20 height=20 action=\"bypass NpcViewMod dropList " + dropType + " " + npc.getObjectId() + " " + i + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
}
pagesSb.append("</tr></table>");
}
@@ -409,124 +408,126 @@ public class NpcViewMod implements IBypassHandler
final StringBuilder sb = new StringBuilder();
int height = 64;
final IDropItem dropItem = dropList.get(i);
if (dropItem instanceof GeneralDropItem)
final DropHolder dropItem = dropList.get(i);
final L2Item item = ItemTable.getInstance().getTemplate(dropItem.getItemId());
// real time server rate calculations
double rateChance = 1;
double rateAmount = 1;
if (dropType == DropType.SPOIL)
{
final GeneralDropItem generalDropItem = (GeneralDropItem) dropItem;
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
sb.append("<table width=332 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
sb.append("<tr><td width=32 valign=top>");
sb.append("<img src=\"" + item.getIcon() + "\" width=32 height=32>");
sb.append("</td><td fixwidth=300 align=center><font name=\"hs9\" color=\"CD9000\">");
sb.append(item.getName());
sb.append("</font></td></tr><tr><td width=32></td><td width=300><table width=295 cellpadding=0 cellspacing=0>");
sb.append("<tr><td width=48 align=right valign=top><font color=\"LEVEL\">Amount:</font></td>");
sb.append("<td width=247 align=center>");
rateChance = Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER;
rateAmount = Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER;
final long min = generalDropItem.getMin(npc, activeChar);
final long max = generalDropItem.getMax(npc, activeChar);
if (min == max)
// also check premium rates if available
if (Config.PREMIUM_SYSTEM_ENABLED && activeChar.hasPremiumStatus())
{
sb.append(amountFormat.format(min));
rateChance *= Config.PREMIUM_RATE_SPOIL_CHANCE;
rateAmount *= Config.PREMIUM_RATE_SPOIL_AMOUNT;
}
}
else
{
if (Config.RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId()) != null)
{
rateChance *= Config.RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId());
}
else if (item.hasExImmediateEffect())
{
rateChance *= Config.RATE_HERB_DROP_CHANCE_MULTIPLIER;
}
else if (npc.isRaid())
{
rateChance *= Config.RATE_RAID_DROP_CHANCE_MULTIPLIER;
}
else
{
sb.append(amountFormat.format(min));
sb.append(" - ");
sb.append(amountFormat.format(max));
rateChance *= Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
}
sb.append("</td></tr><tr><td width=48 align=right valign=top><font color=\"LEVEL\">Chance:</font></td>");
sb.append("<td width=247 align=center>");
sb.append(chanceFormat.format(Math.min(generalDropItem.getChance(npc, activeChar), 100)));
sb.append("%</td></tr></table></td></tr><tr><td width=32></td><td width=300>&nbsp;</td></tr></table>");
}
else if (dropItem instanceof GroupedGeneralDropItem)
{
final GroupedGeneralDropItem generalGroupedDropItem = (GroupedGeneralDropItem) dropItem;
if (generalGroupedDropItem.getItems().size() == 1)
if (Config.RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
{
final GeneralDropItem generalDropItem = generalGroupedDropItem.getItems().get(0);
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
sb.append("<table width=332 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
sb.append("<tr><td width=32 valign=top>");
sb.append("<img src=\"" + item.getIcon() + "\" width=32 height=32>");
sb.append("</td><td fixwidth=300 align=center><font name=\"hs9\" color=\"CD9000\">");
sb.append(item.getName());
sb.append("</font></td></tr><tr><td width=32></td><td width=300><table width=295 cellpadding=0 cellspacing=0>");
sb.append("<tr><td width=48 align=right valign=top><font color=\"LEVEL\">Amount:</font></td>");
sb.append("<td width=247 align=center>");
final long min = generalDropItem.getMin(npc, activeChar);
final long max = generalDropItem.getMax(npc, activeChar);
if (min == max)
rateAmount *= Config.RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId());
}
else if (item.hasExImmediateEffect())
{
rateAmount *= Config.RATE_HERB_DROP_AMOUNT_MULTIPLIER;
}
else if (npc.isRaid())
{
rateAmount *= Config.RATE_RAID_DROP_AMOUNT_MULTIPLIER;
}
else
{
rateAmount *= Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
}
// also check premium rates if available
if (Config.PREMIUM_SYSTEM_ENABLED && activeChar.hasPremiumStatus())
{
if (Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId()) != null)
{
sb.append(amountFormat.format(min));
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId());
}
else if (item.hasExImmediateEffect())
{
// TODO: Premium herb chance? :)
}
else if (npc.isRaid())
{
// TODO: Premium raid chance? :)
}
else
{
sb.append(amountFormat.format(min));
sb.append(" - ");
sb.append(amountFormat.format(max));
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE;
}
sb.append("</td></tr><tr><td width=48 align=right valign=top><font color=\"LEVEL\">Chance:</font></td>");
sb.append("<td width=247 align=center>");
sb.append(chanceFormat.format(Math.min(generalGroupedDropItem.getChance(npc, activeChar), 100)));
sb.append("%</td></tr></table></td></tr><tr><td width=32></td><td width=300>&nbsp;</td></tr></table>");
}
else
{
sb.append("<table width=332 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
sb.append("<tr><td width=32 valign=top><img src=\"L2UI_CT1.ICON_DF_premiumItem\" width=32 height=32></td>");
sb.append("<td fixwidth=300 align=center><font name=\"ScreenMessageSmall\" color=\"CD9000\">One from group</font>");
sb.append("</td></tr><tr><td width=32></td><td width=300><table width=295 cellpadding=0 cellspacing=0><tr>");
sb.append("<td width=48 align=right valign=top><font color=\"LEVEL\">Chance:</font></td>");
sb.append("<td width=247 align=center>");
sb.append(chanceFormat.format(Math.min(generalGroupedDropItem.getChance(npc, activeChar), 100)));
sb.append("%</td></tr></table><br>");
for (GeneralDropItem generalDropItem : generalGroupedDropItem.getItems())
if (Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
{
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
sb.append("<table width=291 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
sb.append("<tr><td width=32 valign=top>");
String icon = item.getIcon();
if (icon == null)
{
icon = "icon.etc_question_mark_i00";
}
sb.append("<img src=\"" + icon + "\" width=32 height=32>");
sb.append("</td><td fixwidth=259 align=center><font name=\"hs9\" color=\"CD9000\">");
sb.append(item.getName());
sb.append("</font></td></tr><tr><td width=32></td><td width=259><table width=253 cellpadding=0 cellspacing=0>");
sb.append("<tr><td width=48 align=right valign=top><font color=\"LEVEL\">Amount:</font></td><td width=205 align=center>");
final long min = generalDropItem.getMin(npc, activeChar);
final long max = generalDropItem.getMax(npc, activeChar);
if (min == max)
{
sb.append(amountFormat.format(min));
}
else
{
sb.append(amountFormat.format(min));
sb.append(" - ");
sb.append(amountFormat.format(max));
}
sb.append("</td></tr><tr><td width=48 align=right valign=top><font color=\"LEVEL\">Chance:</font></td>");
sb.append("<td width=205 align=center>");
sb.append(chanceFormat.format(Math.min(generalDropItem.getChance(npc, activeChar), 100)));
sb.append("%</td></tr></table></td></tr><tr><td width=32></td><td width=259>&nbsp;</td></tr></table>");
height += 64;
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId());
}
else if (item.hasExImmediateEffect())
{
// TODO: Premium herb amount? :)
}
else if (npc.isRaid())
{
// TODO: Premium raid amount? :)
}
else
{
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT;
}
sb.append("</td></tr><tr><td width=32></td><td width=300>&nbsp;</td></tr></table>");
}
}
sb.append("<table width=332 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
sb.append("<tr><td width=32 valign=top>");
sb.append("<img src=\"" + (item.getIcon() == null ? "icon.etc_question_mark_i00" : item.getIcon()) + "\" width=32 height=32>");
sb.append("</td><td fixwidth=300 align=center><font name=\"hs9\" color=\"CD9000\">");
sb.append(item.getName());
sb.append("</font></td></tr><tr><td width=32></td><td width=300><table width=295 cellpadding=0 cellspacing=0>");
sb.append("<tr><td width=48 align=right valign=top><font color=\"LEVEL\">Amount:</font></td>");
sb.append("<td width=247 align=center>");
final long min = (long) (dropItem.getMin() * rateAmount);
final long max = (long) (dropItem.getMax() * rateAmount);
if (min == max)
{
sb.append(amountFormat.format(min));
}
else
{
sb.append(amountFormat.format(min));
sb.append(" - ");
sb.append(amountFormat.format(max));
}
sb.append("</td></tr><tr><td width=48 align=right valign=top><font color=\"LEVEL\">Chance:</font></td>");
sb.append("<td width=247 align=center>");
sb.append(chanceFormat.format(Math.min((long) dropItem.getChance() * rateChance, 100)));
sb.append("%</td></tr></table></td></tr><tr><td width=32></td><td width=300>&nbsp;</td></tr></table>");
if ((sb.length() + rightSb.length() + leftSb.length()) < 16000) // limit of 32766?
{
if (leftHeight >= (rightHeight + height))

View File

@@ -22,23 +22,21 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringJoiner;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.cache.HtmCache;
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
import com.l2jmobius.gameserver.data.xml.impl.SpawnsData;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.DropType;
import com.l2jmobius.gameserver.handler.CommunityBoardHandler;
import com.l2jmobius.gameserver.handler.IParseBoardHandler;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.drops.DropListScope;
import com.l2jmobius.gameserver.model.drops.GeneralDropItem;
import com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem;
import com.l2jmobius.gameserver.model.drops.IDropItem;
import com.l2jmobius.gameserver.model.holders.DropHolder;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
@@ -56,40 +54,40 @@ public class DropSearchBoard implements IParseBoardHandler
"_bbs_npc_trace"
};
class DropHolder
class CBDropHolder
{
int itemId;
int npcId;
byte npcLevel;
long basemin;
long basemax;
double baseGroupChance;
double basechance;
boolean isSweep;
long min;
long max;
double chance;
boolean isSpoil;
boolean isRaid;
public DropHolder(L2NpcTemplate npc, GeneralDropItem item, double groupChance, boolean isSweep)
public CBDropHolder(L2NpcTemplate npcTemplate, DropHolder dropHolder)
{
itemId = item.getItemId();
npcId = npc.getId();
npcLevel = npc.getLevel();
basemin = item.getMin();
basemax = item.getMax();
baseGroupChance = groupChance;
basechance = item.getChance();
this.isSweep = isSweep;
isSpoil = dropHolder.getDropType() == DropType.SPOIL;
itemId = dropHolder.getItemId();
npcId = npcTemplate.getId();
npcLevel = npcTemplate.getLevel();
min = dropHolder.getMin();
max = dropHolder.getMax();
chance = dropHolder.getChance();
isRaid = npcTemplate.getType().equals("L2RaidBoss") || npcTemplate.getType().equals("L2GrandBoss");
}
/**
* only for debug'/;
* only for debug
*/
@Override
public String toString()
{
return "DropHolder [itemId=" + itemId + ", npcId=" + npcId + ", npcLevel=" + npcLevel + ", basemin=" + basemin + ", basemax=" + basemax + ", baseGroupChance=" + baseGroupChance + ", basechance=" + basechance + ", isSweep=" + isSweep + "]";
return "DropHolder [itemId=" + itemId + ", npcId=" + npcId + ", npcLevel=" + npcLevel + ", min=" + min + ", max=" + max + ", chance=" + chance + ", isSpoil=" + isSpoil + "]";
}
}
private final Map<Integer, List<DropHolder>> DROP_INDEX_CACHE = new HashMap<>();
private final Map<Integer, List<CBDropHolder>> DROP_INDEX_CACHE = new HashMap<>();
// nonsupport items
private final Set<Integer> BLOCK_ID = new HashSet<>();
@@ -104,44 +102,39 @@ public class DropSearchBoard implements IParseBoardHandler
private void buildDropIndex()
{
NpcData.getInstance().getTemplates(npc -> npc.getDropLists() != null).forEach(npcTemplate ->
NpcData.getInstance().getTemplates(npc -> npc.getDropList(DropType.DROP) != null).forEach(npcTemplate ->
{
for (Entry<DropListScope, List<IDropItem>> entry : npcTemplate.getDropLists().entrySet())
for (DropHolder dropHolder : npcTemplate.getDropList(DropType.DROP))
{
entry.getValue().forEach(idrop ->
{
if (idrop instanceof GroupedGeneralDropItem)
{
GroupedGeneralDropItem ggd = (GroupedGeneralDropItem) idrop;
ggd.getItems().stream().forEach(gd -> addToDropList(npcTemplate, gd, ggd.getChance(), entry.getKey() == DropListScope.CORPSE));
}
else
{
GeneralDropItem gd = (GeneralDropItem) idrop;
addToDropList(npcTemplate, gd, 100.0, entry.getKey() == DropListScope.CORPSE);
}
});
addToDropList(npcTemplate, dropHolder);
}
});
NpcData.getInstance().getTemplates(npc -> npc.getDropList(DropType.SPOIL) != null).forEach(npcTemplate ->
{
for (DropHolder dropHolder : npcTemplate.getDropList(DropType.SPOIL))
{
addToDropList(npcTemplate, dropHolder);
}
});
DROP_INDEX_CACHE.values().stream().forEach(l -> l.sort((d1, d2) -> Byte.valueOf(d1.npcLevel).compareTo(Byte.valueOf(d2.npcLevel))));
}
private void addToDropList(L2NpcTemplate npcTemplate, GeneralDropItem gd, double groupChance, boolean isSweep)
private void addToDropList(L2NpcTemplate npcTemplate, DropHolder dropHolder)
{
if (BLOCK_ID.contains(gd.getItemId()))
if (BLOCK_ID.contains(dropHolder.getItemId()))
{
return;
}
List<DropHolder> dropList = DROP_INDEX_CACHE.get(gd.getItemId());
List<CBDropHolder> dropList = DROP_INDEX_CACHE.get(dropHolder.getItemId());
if (dropList == null)
{
dropList = new ArrayList<>();
DROP_INDEX_CACHE.put(gd.getItemId(), dropList);
DROP_INDEX_CACHE.put(dropHolder.getItemId(), dropList);
}
dropList.add(new DropHolder(npcTemplate, gd, groupChance, isSweep));
dropList.add(new CBDropHolder(npcTemplate, dropHolder));
}
@Override
@@ -164,7 +157,7 @@ public class DropSearchBoard implements IParseBoardHandler
final DecimalFormat chanceFormat = new DecimalFormat("0.00##");
int itemId = Integer.parseInt(params[1]);
int page = Integer.parseInt(params[2]);
List<DropHolder> list = DROP_INDEX_CACHE.get(itemId);
List<CBDropHolder> list = DROP_INDEX_CACHE.get(itemId);
int pages = list.size() / 14;
if (pages == 0)
{
@@ -176,13 +169,106 @@ public class DropSearchBoard implements IParseBoardHandler
StringBuilder builder = new StringBuilder();
for (int index = start; index <= end; index++)
{
DropHolder dropHolder = list.get(index);
CBDropHolder cbDropHolder = list.get(index);
// real time server rate calculations
double rateChance = 1;
double rateAmount = 1;
if (cbDropHolder.isSpoil)
{
rateChance = Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER;
rateAmount = Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER;
// also check premium rates if available
if (Config.PREMIUM_SYSTEM_ENABLED && player.hasPremiumStatus())
{
rateChance *= Config.PREMIUM_RATE_SPOIL_CHANCE;
rateAmount *= Config.PREMIUM_RATE_SPOIL_AMOUNT;
}
}
else
{
final L2Item item = ItemTable.getInstance().getTemplate(cbDropHolder.itemId);
if (Config.RATE_DROP_CHANCE_BY_ID.get(cbDropHolder.itemId) != null)
{
rateChance *= Config.RATE_DROP_CHANCE_BY_ID.get(cbDropHolder.itemId);
}
else if (item.hasExImmediateEffect())
{
rateChance *= Config.RATE_HERB_DROP_CHANCE_MULTIPLIER;
}
else if (cbDropHolder.isRaid)
{
rateAmount *= Config.RATE_RAID_DROP_CHANCE_MULTIPLIER;
}
else
{
rateChance *= Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
}
if (Config.RATE_DROP_AMOUNT_BY_ID.get(cbDropHolder.itemId) != null)
{
rateAmount *= Config.RATE_DROP_AMOUNT_BY_ID.get(cbDropHolder.itemId);
}
else if (cbDropHolder.isRaid)
{
rateAmount *= Config.RATE_RAID_DROP_AMOUNT_MULTIPLIER;
}
else if (item.hasExImmediateEffect())
{
rateAmount *= Config.RATE_HERB_DROP_AMOUNT_MULTIPLIER;
}
else
{
rateAmount *= Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
}
// also check premium rates if available
if (Config.PREMIUM_SYSTEM_ENABLED && player.hasPremiumStatus())
{
if (Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(cbDropHolder.itemId) != null)
{
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(cbDropHolder.itemId);
}
else if (item.hasExImmediateEffect())
{
// TODO: Premium herb chance? :)
}
else if (cbDropHolder.isRaid)
{
// TODO: Premium raid chance? :)
}
else
{
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE;
}
if (Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(cbDropHolder.itemId) != null)
{
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(cbDropHolder.itemId);
}
else if (item.hasExImmediateEffect())
{
// TODO: Premium herb amount? :)
}
else if (cbDropHolder.isRaid)
{
// TODO: Premium raid amount? :)
}
else
{
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT;
}
}
}
builder.append("<tr>");
builder.append("<td width=30>").append(dropHolder.npcLevel).append("</td>");
builder.append("<td width=170>").append("<a action=\"bypass _bbs_npc_trace " + dropHolder.npcId + "\">").append("&@").append(dropHolder.npcId).append(";").append("</a>").append("</td>");
builder.append("<td width=80 align=CENTER>").append(dropHolder.basemin).append("-").append(dropHolder.basemax).append("</td>");
builder.append("<td width=50 align=CENTER>").append(chanceFormat.format((dropHolder.basechance * dropHolder.baseGroupChance) / 100)).append("%").append("</td>");
builder.append("<td width=50 align=CENTER>").append(dropHolder.isSweep ? "Sweep" : "Drop").append("</td>");
builder.append("<td width=30>").append(cbDropHolder.npcLevel).append("</td>");
builder.append("<td width=170>").append("<a action=\"bypass _bbs_npc_trace " + cbDropHolder.npcId + "\">").append("&@").append(cbDropHolder.npcId).append(";").append("</a>").append("</td>");
builder.append("<td width=80 align=CENTER>").append(cbDropHolder.min * rateAmount).append("-").append(cbDropHolder.max * rateAmount).append("</td>");
builder.append("<td width=50 align=CENTER>").append(chanceFormat.format(cbDropHolder.chance * rateChance)).append("%").append("</td>");
builder.append("<td width=50 align=CENTER>").append(cbDropHolder.isSpoil ? "Spoil" : "Drop").append("</td>");
builder.append("</tr>");
}
@@ -204,7 +290,7 @@ public class DropSearchBoard implements IParseBoardHandler
List<NpcSpawnTemplate> spawnList = SpawnsData.getInstance().getNpcSpawns(npc -> npc.getId() == npcId);
if (spawnList.isEmpty())
{
player.sendMessage("cant find any spawn maybe boss or instance mob");
player.sendMessage("Cannot find any spawn. Maybe dropped by a boss or instance monster.");
}
else
{

View File

@@ -49,15 +49,15 @@ public class Premium implements IVoicedCommandHandler
html.append("<tr><td>Rate SP: <font color=\"LEVEL\"> x" + Config.RATE_SP + "<br1></font></td></tr>");
html.append("<tr><td>Drop Chance: <font color=\"LEVEL\"> x" + Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER + "<br1></font></td></tr><br>");
html.append("<tr><td>Drop Amount: <font color=\"LEVEL\"> x" + Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER + "<br1></font></td></tr><br>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\"> x" + Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER + "<br1></font></td></tr><br>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\"> x" + Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER + "<br><br></font></td></tr><br>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\"> x" + Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER + "<br1></font></td></tr><br>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\"> x" + Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER + "<br><br></font></td></tr><br>");
html.append("<tr><td><center>Premium Info & Rules<br></td></tr>");
html.append("<tr><td>Rate XP: <font color=\"LEVEL\"> x" + (Config.RATE_XP * Config.PREMIUM_RATE_XP) + "<br1></font></td></tr>");
html.append("<tr><td>Rate SP: <font color=\"LEVEL\"> x" + (Config.RATE_SP * Config.PREMIUM_RATE_SP) + "<br1></font></td></tr>");
html.append("<tr><td>Drop Chance: <font color=\"LEVEL\"> x" + (Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER * Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_DROP_CHANCE) + "<br1></font></td></tr>");
html.append("<tr><td>Drop Amount: <font color=\"LEVEL\"> x" + (Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_DROP_AMOUNT) + "<br1></font></td></tr>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\"> x" + (Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_CHANCE) + "<br1></font></td></tr>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\"> x" + (Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + "<br1></font></td></tr>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\"> x" + (Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_CHANCE) + "<br1></font></td></tr>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\"> x" + (Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + "<br1></font></td></tr>");
html.append("<tr><td> <font color=\"70FFCA\">1. Premium benefits CAN NOT BE TRANSFERED.<br1></font></td></tr>");
html.append("<tr><td> <font color=\"70FFCA\">2. Premium does not effect party members.<br1></font></td></tr>");
html.append("<tr><td> <font color=\"70FFCA\">3. Premium benefits effect ALL characters in same account.</font></td></tr>");
@@ -71,8 +71,8 @@ public class Premium implements IVoicedCommandHandler
html.append("<tr><td>Rate SP: <font color=\"LEVEL\">x" + (Config.RATE_SP * Config.PREMIUM_RATE_SP) + " <br1></font></td></tr>");
html.append("<tr><td>Drop Chance: <font color=\"LEVEL\">x" + (Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_DROP_CHANCE) + " <br1></font></td></tr>");
html.append("<tr><td>Drop Amount: <font color=\"LEVEL\">x" + (Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_DROP_AMOUNT) + " <br1></font></td></tr>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\">x" + (Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_CHANCE) + " <br1></font></td></tr>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\">x" + (Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + " <br1></font></td></tr>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\">x" + (Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_CHANCE) + " <br1></font></td></tr>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\">x" + (Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + " <br1></font></td></tr>");
html.append("<tr><td>Expires: <font color=\"00A5FF\">" + format.format(endDate) + "</font></td></tr>");
html.append("<tr><td>Current Date: <font color=\"70FFCA\">" + format.format(System.currentTimeMillis()) + "<br><br></font></td></tr>");
html.append("<tr><td><center>Premium Info & Rules<br></center></td></tr>");