Drops rework.
This commit is contained in:
parent
2c61857b12
commit
fc94704b2d
@ -1,10 +0,0 @@
|
|||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Old Drop Behavior
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Enables L2J old drop behavior
|
|
||||||
# The old L2J system used to add amount of items drop per 100% range of chance.
|
|
||||||
# For example, if chance is 230% when rate are applied, it will do :
|
|
||||||
# amount dropped = (2 * getRandomAmount(min,max)) + 30% chance to get ad additional getRandomAmount(min,max)
|
|
||||||
# Default : False
|
|
||||||
OldDropBehavior = False
|
|
@ -225,11 +225,6 @@ OrderQuestListByQuestId = True
|
|||||||
# Default: False
|
# Default: False
|
||||||
AutoDeleteInvalidQuestData = False
|
AutoDeleteInvalidQuestData = False
|
||||||
|
|
||||||
# If True, allows a special handling for drops when chance raises over 100% (eg. when applying chance rates).
|
|
||||||
# True value causes better drop handling at higher rates.
|
|
||||||
# Default: True
|
|
||||||
PreciseDropCalculation = True
|
|
||||||
|
|
||||||
# Allow creating multiple non-stackable items at one time?
|
# Allow creating multiple non-stackable items at one time?
|
||||||
# Default: True
|
# Default: True
|
||||||
MultipleItemDrop = True
|
MultipleItemDrop = True
|
||||||
|
30
L2J_Mobius_1.0_Ertheia/dist/game/config/NPC.ini
vendored
30
L2J_Mobius_1.0_Ertheia/dist/game/config/NPC.ini
vendored
@ -174,36 +174,6 @@ GrandChaosTime = 10
|
|||||||
MinionChaosTime = 10
|
MinionChaosTime = 10
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Drops
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# The min and max level difference used for level gap calculation
|
|
||||||
# this is only for how many levels higher the player is than the monster
|
|
||||||
# Default: 8
|
|
||||||
DropAdenaMinLevelDifference = 8
|
|
||||||
# Default: 15
|
|
||||||
DropAdenaMaxLevelDifference = 15
|
|
||||||
|
|
||||||
# This is the minimum level gap chance meaning for 10 that the monster will have 10% chance
|
|
||||||
# to allow dropping the item if level difference is bigger than DropAdenaMaxLevelDifference
|
|
||||||
# Note: This value is scalling from 100 to the specified value for DropAdenaMinLevelDifference to DropAdenaMaxLevelDifference limits
|
|
||||||
# Default: 10
|
|
||||||
DropAdenaMinLevelGapChance = 10
|
|
||||||
|
|
||||||
# The min and max level difference used for level gap calculation
|
|
||||||
# this is only for how many levels higher the player is than the monster
|
|
||||||
# Default: 5
|
|
||||||
DropItemMinLevelDifference = 5
|
|
||||||
# Default: 10
|
|
||||||
DropItemMaxLevelDifference = 10
|
|
||||||
|
|
||||||
# This is the minimum level gap chance meaning for 10 that the monster will have 10% chance
|
|
||||||
# to allow dropping the item if level difference is bigger than DropAdenaMaxLevelDifference
|
|
||||||
# Note: This value is scalling from 100 to the specified value for DropAdenaMinLevelDifference to DropAdenaMaxLevelDifference limits
|
|
||||||
# Default: 10
|
|
||||||
DropItemMinLevelGapChance = 10
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Vitality
|
# Vitality
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
@ -5,39 +5,6 @@
|
|||||||
# Warning:
|
# Warning:
|
||||||
# Please take extreme caution when changing anything. Also please understand what you are changing before you do so on a live server.
|
# Please take extreme caution when changing anything. Also please understand what you are changing before you do so on a live server.
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Item Rates
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Warning: to achieve old l2j behavior before drops rework you need to enable OldDropBehavior in Custom.ini
|
|
||||||
# and increase only chance multipliers! Remember if you increase both chance and amount you will have higher rates than expected
|
|
||||||
# Example: if amount multiplier is 5 and chance multiplier is 5 you will end up with 5*5 = 25 drop rates so be careful!
|
|
||||||
|
|
||||||
# Multiplies the amount of items dropped from monster on ground when it dies.
|
|
||||||
DeathDropAmountMultiplier = 1
|
|
||||||
# Multiplies the amount of items looted from monster when a skill like Sweeper(Spoil) is used.
|
|
||||||
CorpseDropAmountMultiplier = 1
|
|
||||||
# Multiplies the amount of items dropped from monster on ground when it dies.
|
|
||||||
HerbDropAmountMultiplier = 1
|
|
||||||
RaidDropAmountMultiplier = 1
|
|
||||||
|
|
||||||
# Multiplies the chance of items that can be dropped from monster on ground when it dies.
|
|
||||||
DeathDropChanceMultiplier = 1
|
|
||||||
# Multiplies the chance of items that can be looted from monster when a skill like Sweeper(Spoil) is used.
|
|
||||||
CorpseDropChanceMultiplier = 1
|
|
||||||
# Multiplies the chance of items that can be dropped from monster on ground when it dies.
|
|
||||||
HerbDropChanceMultiplier = 1
|
|
||||||
RaidDropChanceMultiplier = 1
|
|
||||||
|
|
||||||
# List of items affected by custom drop rate by id, used now for Adena rate too.
|
|
||||||
# Usage: itemId1,multiplier1;itemId2,multiplier2;...
|
|
||||||
# Note: Make sure the lists do NOT CONTAIN trailing spaces or spaces between the numbers!
|
|
||||||
# Example for Raid boss 1x jewelry: 6656,1;6657,1;6658,1;6659,1;6660,1;6661,1;6662,1;8191,1;10170,1;10314,1;
|
|
||||||
# Default: 57,1
|
|
||||||
DropAmountMultiplierByItemId = 57,1
|
|
||||||
DropChanceMultiplierByItemId = 57,1
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Standard Settings (Retail value = 1)
|
# Standard Settings (Retail value = 1)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@ -109,6 +76,68 @@ RateQuestRewardRecipe = 1
|
|||||||
RateQuestRewardMaterial = 1
|
RateQuestRewardMaterial = 1
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Item Drop Rates
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Remember if you increase both chance and amount you will have higher rates than expected.
|
||||||
|
# Example: if amount multiplier is 5 and chance multiplier is 5 you will end up with 5*5 = 25 drop rates so be careful!
|
||||||
|
|
||||||
|
# Multiplies the amount of items rewarded from monsters when they die.
|
||||||
|
DeathDropAmountMultiplier = 1
|
||||||
|
# Multiplies the amount of items rewarded from monsters when a Spoil skill is used.
|
||||||
|
SpoilDropAmountMultiplier = 1
|
||||||
|
# Multiplies the amount of items rewarded from monsters when they die.
|
||||||
|
HerbDropAmountMultiplier = 1
|
||||||
|
RaidDropAmountMultiplier = 1
|
||||||
|
|
||||||
|
# Multiplies the chance of items that can be rewarded from monsters when they die.
|
||||||
|
DeathDropChanceMultiplier = 1
|
||||||
|
# Multiplies the chance of items that can be rewarded from monsters when a Spoil skill is used.
|
||||||
|
SpoilDropChanceMultiplier = 1
|
||||||
|
# Multiplies the chance of items that can be rewarded from monsters when they die.
|
||||||
|
HerbDropChanceMultiplier = 1
|
||||||
|
RaidDropChanceMultiplier = 1
|
||||||
|
|
||||||
|
# List of items affected by custom drop rate by id, used now for Adena rate too.
|
||||||
|
# Usage: itemId1,multiplier1;itemId2,multiplier2;...
|
||||||
|
# Note: Make sure the lists do NOT CONTAIN trailing spaces or spaces between the numbers!
|
||||||
|
# Example for Raid boss 1x jewelry: 6656,1;6657,1;6658,1;6659,1;6660,1;6661,1;6662,1;8191,1;10170,1;10314,1;
|
||||||
|
# Default: 57,1
|
||||||
|
DropAmountMultiplierByItemId = 57,1
|
||||||
|
DropChanceMultiplierByItemId = 57,1
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Item Drop Level Difference Settings
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# The min and max level difference used for level gap calculation
|
||||||
|
# this is only for how many levels higher the player is than the monster
|
||||||
|
# Default: 8
|
||||||
|
DropAdenaMinLevelDifference = 8
|
||||||
|
# Default: 15
|
||||||
|
DropAdenaMaxLevelDifference = 15
|
||||||
|
|
||||||
|
# This is the minimum level gap chance meaning for 10 that the monster will have 10% chance
|
||||||
|
# to allow dropping the item if level difference is bigger than DropAdenaMaxLevelDifference
|
||||||
|
# Note: This value is scalling from 100 to the specified value for DropAdenaMinLevelDifference to DropAdenaMaxLevelDifference limits
|
||||||
|
# Default: 10
|
||||||
|
DropAdenaMinLevelGapChance = 10
|
||||||
|
|
||||||
|
# The min and max level difference used for level gap calculation
|
||||||
|
# this is only for how many levels higher the player is than the monster
|
||||||
|
# Default: 5
|
||||||
|
DropItemMinLevelDifference = 5
|
||||||
|
# Default: 10
|
||||||
|
DropItemMaxLevelDifference = 10
|
||||||
|
|
||||||
|
# This is the minimum level gap chance meaning for 10 that the monster will have 10% chance
|
||||||
|
# to allow dropping the item if level difference is bigger than DropAdenaMaxLevelDifference
|
||||||
|
# Note: This value is scalling from 100 to the specified value for DropAdenaMinLevelDifference to DropAdenaMaxLevelDifference limits
|
||||||
|
# Default: 10
|
||||||
|
DropItemMinLevelGapChance = 10
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Vitality system rates. Works only if EnableVitality = True
|
# Vitality system rates. Works only if EnableVitality = True
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
@ -265,7 +265,7 @@ public class AdminAdmin implements IAdminCommandHandler
|
|||||||
}
|
}
|
||||||
case "RateDropSpoil":
|
case "RateDropSpoil":
|
||||||
{
|
{
|
||||||
Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER = Float.valueOf(pValue);
|
Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER = Float.valueOf(pValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "EnchantChanceElementStone":
|
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=\"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 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 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 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=\"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>");
|
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>");
|
||||||
|
@ -18,14 +18,15 @@ package handlers.bypasshandlers;
|
|||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.util.CommonUtil;
|
import com.l2jmobius.commons.util.CommonUtil;
|
||||||
import com.l2jmobius.gameserver.cache.HtmCache;
|
import com.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||||
import com.l2jmobius.gameserver.enums.AttributeType;
|
import com.l2jmobius.gameserver.enums.AttributeType;
|
||||||
|
import com.l2jmobius.gameserver.enums.DropType;
|
||||||
import com.l2jmobius.gameserver.handler.IBypassHandler;
|
import com.l2jmobius.gameserver.handler.IBypassHandler;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
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.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.drops.DropListScope;
|
import com.l2jmobius.gameserver.model.holders.DropHolder;
|
||||||
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.items.L2Item;
|
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||||
import com.l2jmobius.gameserver.util.HtmlUtil;
|
import com.l2jmobius.gameserver.util.HtmlUtil;
|
||||||
@ -106,10 +104,10 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String dropListScopeString = st.nextToken();
|
final String dropListTypeString = st.nextToken();
|
||||||
try
|
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 L2Object target = L2World.getInstance().findObject(Integer.parseInt(st.nextToken()));
|
||||||
final L2Npc npc = target instanceof L2Npc ? (L2Npc) target : null;
|
final L2Npc npc = target instanceof L2Npc ? (L2Npc) target : null;
|
||||||
if (npc == null)
|
if (npc == null)
|
||||||
@ -117,7 +115,7 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final int page = st.hasMoreElements() ? Integer.parseInt(st.nextToken()) : 0;
|
final int page = st.hasMoreElements() ? Integer.parseInt(st.nextToken()) : 0;
|
||||||
sendNpcDropList(activeChar, npc, dropListScope, page);
|
sendNpcDropList(activeChar, npc, dropListType, page);
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e)
|
catch (NumberFormatException e)
|
||||||
{
|
{
|
||||||
@ -125,7 +123,7 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (IllegalArgumentException e)
|
||||||
{
|
{
|
||||||
_log.warning("Bypass[NpcViewMod] unknown drop list scope: " + dropListScopeString);
|
_log.warning("Bypass[NpcViewMod] unknown drop list scope: " + dropListTypeString);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -336,21 +334,22 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
activeChar.sendPacket(html);
|
activeChar.sendPacket(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDropListButtons(L2Npc npc)
|
private static String getDropListButtons(L2Npc npc)
|
||||||
{
|
{
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
final Map<DropListScope, List<IDropItem>> dropLists = npc.getTemplate().getDropLists();
|
final List<DropHolder> dropListDeath = npc.getTemplate().getDropList(DropType.DROP);
|
||||||
if ((dropLists != null) && !dropLists.isEmpty() && (dropLists.containsKey(DropListScope.DEATH) || dropLists.containsKey(DropListScope.CORPSE)))
|
final List<DropHolder> dropListSpoil = npc.getTemplate().getDropList(DropType.SPOIL);
|
||||||
|
if ((dropListDeath != null) || (dropListSpoil != null))
|
||||||
{
|
{
|
||||||
sb.append("<table width=275 cellpadding=0 cellspacing=0><tr>");
|
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>");
|
sb.append("</tr></table>");
|
||||||
@ -358,10 +357,10 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
return sb.toString();
|
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);
|
final List<DropHolder> dropList = npc.getTemplate().getDropList(dropType);
|
||||||
if ((dropList == null) || dropList.isEmpty())
|
if (dropList == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -378,7 +377,7 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
pagesSb.append("<table><tr>");
|
pagesSb.append("<table><tr>");
|
||||||
for (int i = 0; i < pages; i++)
|
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>");
|
pagesSb.append("</tr></table>");
|
||||||
}
|
}
|
||||||
@ -409,124 +408,126 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
int height = 64;
|
int height = 64;
|
||||||
final IDropItem dropItem = dropList.get(i);
|
final DropHolder dropItem = dropList.get(i);
|
||||||
if (dropItem instanceof GeneralDropItem)
|
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;
|
rateChance = Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER;
|
||||||
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
|
rateAmount = Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER;
|
||||||
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);
|
// also check premium rates if available
|
||||||
final long max = generalDropItem.getMax(npc, activeChar);
|
if (Config.PREMIUM_SYSTEM_ENABLED && activeChar.hasPremiumStatus())
|
||||||
if (min == max)
|
|
||||||
{
|
{
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
sb.append(amountFormat.format(min));
|
rateChance *= Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
|
||||||
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>");
|
if (Config.RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
|
||||||
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> </td></tr></table>");
|
|
||||||
}
|
|
||||||
else if (dropItem instanceof GroupedGeneralDropItem)
|
|
||||||
{
|
|
||||||
final GroupedGeneralDropItem generalGroupedDropItem = (GroupedGeneralDropItem) dropItem;
|
|
||||||
if (generalGroupedDropItem.getItems().size() == 1)
|
|
||||||
{
|
{
|
||||||
final GeneralDropItem generalDropItem = generalGroupedDropItem.getItems().get(0);
|
rateAmount *= Config.RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId());
|
||||||
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
|
}
|
||||||
sb.append("<table width=332 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
|
else if (item.hasExImmediateEffect())
|
||||||
sb.append("<tr><td width=32 valign=top>");
|
{
|
||||||
sb.append("<img src=\"" + item.getIcon() + "\" width=32 height=32>");
|
rateAmount *= Config.RATE_HERB_DROP_AMOUNT_MULTIPLIER;
|
||||||
sb.append("</td><td fixwidth=300 align=center><font name=\"hs9\" color=\"CD9000\">");
|
}
|
||||||
sb.append(item.getName());
|
else if (npc.isRaid())
|
||||||
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>");
|
rateAmount *= Config.RATE_RAID_DROP_AMOUNT_MULTIPLIER;
|
||||||
sb.append("<td width=247 align=center>");
|
}
|
||||||
|
else
|
||||||
final long min = generalDropItem.getMin(npc, activeChar);
|
{
|
||||||
final long max = generalDropItem.getMax(npc, activeChar);
|
rateAmount *= Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
|
||||||
if (min == max)
|
}
|
||||||
|
|
||||||
|
// 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
|
else
|
||||||
{
|
{
|
||||||
sb.append(amountFormat.format(min));
|
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE;
|
||||||
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>");
|
if (Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
|
||||||
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> </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())
|
|
||||||
{
|
{
|
||||||
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
|
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.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>");
|
else if (item.hasExImmediateEffect())
|
||||||
String icon = item.getIcon();
|
{
|
||||||
if (icon == null)
|
// TODO: Premium herb amount? :)
|
||||||
{
|
}
|
||||||
icon = "icon.etc_question_mark_i00";
|
else if (npc.isRaid())
|
||||||
}
|
{
|
||||||
sb.append("<img src=\"" + icon + "\" width=32 height=32>");
|
// TODO: Premium raid amount? :)
|
||||||
sb.append("</td><td fixwidth=259 align=center><font name=\"hs9\" color=\"CD9000\">");
|
}
|
||||||
sb.append(item.getName());
|
else
|
||||||
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>");
|
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT;
|
||||||
|
|
||||||
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> </td></tr></table>");
|
|
||||||
|
|
||||||
height += 64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append("</td></tr><tr><td width=32></td><td width=300> </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> </td></tr></table>");
|
||||||
|
|
||||||
if ((sb.length() + rightSb.length() + leftSb.length()) < 16000) // limit of 32766?
|
if ((sb.length() + rightSb.length() + leftSb.length()) < 16000) // limit of 32766?
|
||||||
{
|
{
|
||||||
if (leftHeight >= (rightHeight + height))
|
if (leftHeight >= (rightHeight + height))
|
||||||
|
@ -22,23 +22,21 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.util.Rnd;
|
import com.l2jmobius.commons.util.Rnd;
|
||||||
import com.l2jmobius.gameserver.cache.HtmCache;
|
import com.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
|
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
|
||||||
import com.l2jmobius.gameserver.data.xml.impl.SpawnsData;
|
import com.l2jmobius.gameserver.data.xml.impl.SpawnsData;
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||||
|
import com.l2jmobius.gameserver.enums.DropType;
|
||||||
import com.l2jmobius.gameserver.handler.CommunityBoardHandler;
|
import com.l2jmobius.gameserver.handler.CommunityBoardHandler;
|
||||||
import com.l2jmobius.gameserver.handler.IParseBoardHandler;
|
import com.l2jmobius.gameserver.handler.IParseBoardHandler;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||||
import com.l2jmobius.gameserver.model.drops.DropListScope;
|
import com.l2jmobius.gameserver.model.holders.DropHolder;
|
||||||
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.itemcontainer.Inventory;
|
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||||
import com.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
|
import com.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
|
||||||
@ -56,40 +54,40 @@ public class DropSearchBoard implements IParseBoardHandler
|
|||||||
"_bbs_npc_trace"
|
"_bbs_npc_trace"
|
||||||
};
|
};
|
||||||
|
|
||||||
class DropHolder
|
class CBDropHolder
|
||||||
{
|
{
|
||||||
int itemId;
|
int itemId;
|
||||||
int npcId;
|
int npcId;
|
||||||
byte npcLevel;
|
byte npcLevel;
|
||||||
long basemin;
|
long min;
|
||||||
long basemax;
|
long max;
|
||||||
double baseGroupChance;
|
double chance;
|
||||||
double basechance;
|
boolean isSpoil;
|
||||||
boolean isSweep;
|
boolean isRaid;
|
||||||
|
|
||||||
public DropHolder(L2NpcTemplate npc, GeneralDropItem item, double groupChance, boolean isSweep)
|
public CBDropHolder(L2NpcTemplate npcTemplate, DropHolder dropHolder)
|
||||||
{
|
{
|
||||||
itemId = item.getItemId();
|
isSpoil = dropHolder.getDropType() == DropType.SPOIL;
|
||||||
npcId = npc.getId();
|
itemId = dropHolder.getItemId();
|
||||||
npcLevel = npc.getLevel();
|
npcId = npcTemplate.getId();
|
||||||
basemin = item.getMin();
|
npcLevel = npcTemplate.getLevel();
|
||||||
basemax = item.getMax();
|
min = dropHolder.getMin();
|
||||||
baseGroupChance = groupChance;
|
max = dropHolder.getMax();
|
||||||
basechance = item.getChance();
|
chance = dropHolder.getChance();
|
||||||
this.isSweep = isSweep;
|
isRaid = npcTemplate.getType().equals("L2RaidBoss") || npcTemplate.getType().equals("L2GrandBoss");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* only for debug'/;
|
* only for debug
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
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
|
// nonsupport items
|
||||||
private final Set<Integer> BLOCK_ID = new HashSet<>();
|
private final Set<Integer> BLOCK_ID = new HashSet<>();
|
||||||
@ -104,44 +102,39 @@ public class DropSearchBoard implements IParseBoardHandler
|
|||||||
|
|
||||||
private void buildDropIndex()
|
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 ->
|
addToDropList(npcTemplate, dropHolder);
|
||||||
{
|
}
|
||||||
if (idrop instanceof GroupedGeneralDropItem)
|
});
|
||||||
{
|
NpcData.getInstance().getTemplates(npc -> npc.getDropList(DropType.SPOIL) != null).forEach(npcTemplate ->
|
||||||
GroupedGeneralDropItem ggd = (GroupedGeneralDropItem) idrop;
|
{
|
||||||
ggd.getItems().stream().forEach(gd -> addToDropList(npcTemplate, gd, ggd.getChance(), entry.getKey() == DropListScope.CORPSE));
|
for (DropHolder dropHolder : npcTemplate.getDropList(DropType.SPOIL))
|
||||||
}
|
{
|
||||||
else
|
addToDropList(npcTemplate, dropHolder);
|
||||||
{
|
|
||||||
GeneralDropItem gd = (GeneralDropItem) idrop;
|
|
||||||
addToDropList(npcTemplate, gd, 100.0, entry.getKey() == DropListScope.CORPSE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
DROP_INDEX_CACHE.values().stream().forEach(l -> l.sort((d1, d2) -> Byte.valueOf(d1.npcLevel).compareTo(Byte.valueOf(d2.npcLevel))));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DropHolder> dropList = DROP_INDEX_CACHE.get(gd.getItemId());
|
List<CBDropHolder> dropList = DROP_INDEX_CACHE.get(dropHolder.getItemId());
|
||||||
if (dropList == null)
|
if (dropList == null)
|
||||||
{
|
{
|
||||||
dropList = new ArrayList<>();
|
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
|
@Override
|
||||||
@ -164,7 +157,7 @@ public class DropSearchBoard implements IParseBoardHandler
|
|||||||
final DecimalFormat chanceFormat = new DecimalFormat("0.00##");
|
final DecimalFormat chanceFormat = new DecimalFormat("0.00##");
|
||||||
int itemId = Integer.parseInt(params[1]);
|
int itemId = Integer.parseInt(params[1]);
|
||||||
int page = Integer.parseInt(params[2]);
|
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;
|
int pages = list.size() / 14;
|
||||||
if (pages == 0)
|
if (pages == 0)
|
||||||
{
|
{
|
||||||
@ -176,13 +169,106 @@ public class DropSearchBoard implements IParseBoardHandler
|
|||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for (int index = start; index <= end; index++)
|
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("<tr>");
|
||||||
builder.append("<td width=30>").append(dropHolder.npcLevel).append("</td>");
|
builder.append("<td width=30>").append(cbDropHolder.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=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(dropHolder.basemin).append("-").append(dropHolder.basemax).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((dropHolder.basechance * dropHolder.baseGroupChance) / 100)).append("%").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(dropHolder.isSweep ? "Sweep" : "Drop").append("</td>");
|
builder.append("<td width=50 align=CENTER>").append(cbDropHolder.isSpoil ? "Spoil" : "Drop").append("</td>");
|
||||||
builder.append("</tr>");
|
builder.append("</tr>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +290,7 @@ public class DropSearchBoard implements IParseBoardHandler
|
|||||||
List<NpcSpawnTemplate> spawnList = SpawnsData.getInstance().getNpcSpawns(npc -> npc.getId() == npcId);
|
List<NpcSpawnTemplate> spawnList = SpawnsData.getInstance().getNpcSpawns(npc -> npc.getId() == npcId);
|
||||||
if (spawnList.isEmpty())
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -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>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 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>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 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_CORPSE_DROP_AMOUNT_MULTIPLIER + "<br><br></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><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 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>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 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>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 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_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + "<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\">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\">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>");
|
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>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 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>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 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_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + " <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>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>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>");
|
html.append("<tr><td><center>Premium Info & Rules<br></center></td></tr>");
|
||||||
|
@ -1,272 +1,236 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
|
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
|
||||||
<npc id="2081" level="82" type="L2Monster" name="Canabion of Plague">
|
<npc id="2081" level="82" type="L2Monster" name="Canabion of Plague">
|
||||||
<!-- TODO: Must be confirmed -->
|
<!-- TODO: Must be confirmed -->
|
||||||
<parameters>
|
<parameters>
|
||||||
<param name="MoveAroundSocial" value="100" />
|
<param name="MoveAroundSocial" value="100" />
|
||||||
<param name="MoveAroundSocial1" value="100" />
|
<param name="MoveAroundSocial1" value="100" />
|
||||||
<param name="MoveAroundSocial2" value="100" />
|
<param name="MoveAroundSocial2" value="100" />
|
||||||
<param name="Skill01_Probablity" value="2000" />
|
<param name="Skill01_Probablity" value="2000" />
|
||||||
<param name="Type" value="0" />
|
<param name="Type" value="0" />
|
||||||
<param name="PrivatesNorm" value="2081" />
|
<param name="PrivatesNorm" value="2081" />
|
||||||
<param name="PrivatesSpA" value="2082" />
|
<param name="PrivatesSpA" value="2082" />
|
||||||
<param name="PrivatesSpB" value="2083" />
|
<param name="PrivatesSpB" value="2083" />
|
||||||
<param name="MyMakerName" value="inzone03_2111_80m1" />
|
<param name="MyMakerName" value="inzone03_2111_80m1" />
|
||||||
<param name="SoulShot" value="200" />
|
<param name="SoulShot" value="200" />
|
||||||
<param name="SoulShotRate" value="5" />
|
<param name="SoulShotRate" value="5" />
|
||||||
<param name="SpiritShot" value="100" />
|
<param name="SpiritShot" value="100" />
|
||||||
<param name="SpiritShotRate" value="10" />
|
<param name="SpiritShotRate" value="10" />
|
||||||
<param name="LongRangeGuardRate" value="5" />
|
<param name="LongRangeGuardRate" value="5" />
|
||||||
<skill name="Skill01_ID" id="4032" level="8" />
|
<skill name="Skill01_ID" id="4032" level="8" />
|
||||||
<skill name="Debuff" id="5719" level="1" />
|
<skill name="Debuff" id="5719" level="1" />
|
||||||
</parameters>
|
</parameters>
|
||||||
<race>HUMANOID</race>
|
<race>HUMANOID</race>
|
||||||
<sex>MALE</sex>
|
<sex>MALE</sex>
|
||||||
<acquire exp="12707" sp="3" />
|
<acquire exp="12707" sp="3" />
|
||||||
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
|
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
|
||||||
<vitals hp="3643" mp="1743" hpRegen="8.5" mpRegen="3" />
|
<vitals hp="3643" mp="1743" hpRegen="8.5" mpRegen="3" />
|
||||||
<attack physical="1055.28566004965" magical="720.623302603812" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="10" critical="4" accuracy="5" />
|
<attack physical="1055.28566004965" magical="720.623302603812" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="10" critical="4" accuracy="5" />
|
||||||
<defence physical="349.77477" magical="255.95" />
|
<defence physical="349.77477" magical="255.95" />
|
||||||
<attribute>
|
<attribute>
|
||||||
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
|
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
|
||||||
</attribute>
|
</attribute>
|
||||||
<speed>
|
<speed>
|
||||||
<walk ground="8" />
|
<walk ground="8" />
|
||||||
<run ground="120" />
|
<run ground="120" />
|
||||||
</speed>
|
</speed>
|
||||||
<abnormalResist physical="10" magical="10" />
|
<abnormalResist physical="10" magical="10" />
|
||||||
</stats>
|
</stats>
|
||||||
<skill_list>
|
<skill_list>
|
||||||
<skill id="4032" level="1" /> <!-- NPC Strike -->
|
<skill id="4032" level="1" /> <!-- NPC Strike -->
|
||||||
<skill id="4416" level="9" /> <!-- Demons -->
|
<skill id="4416" level="9" /> <!-- Demons -->
|
||||||
<skill id="5565" level="1" /> <!-- Expose Weak Point -->
|
<skill id="5565" level="1" /> <!-- Expose Weak Point -->
|
||||||
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
||||||
</skill_list>
|
</skill_list>
|
||||||
<ai clanHelpRange="200" aggroRange="300">
|
<ai clanHelpRange="200" aggroRange="300">
|
||||||
<clan_list>
|
<clan_list>
|
||||||
<clan>RIM</clan>
|
<clan>RIM</clan>
|
||||||
</clan_list>
|
</clan_list>
|
||||||
</ai>
|
</ai>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<group chance="42">
|
<item id="8600" min="1" max="1" chance="8.4" /> <!-- Herb of Life -->
|
||||||
<item id="8600" min="1" max="1" chance="20" /> <!-- Herb of Life -->
|
<item id="8601" min="1" max="1" chance="18.9" /> <!-- Major Herb of Life -->
|
||||||
<item id="8601" min="1" max="1" chance="45" /> <!-- Major Herb of Life -->
|
<item id="8602" min="1" max="1" chance="14.7" /> <!-- Superior Herb of Life -->
|
||||||
<item id="8602" min="1" max="1" chance="35" /> <!-- Superior Herb of Life -->
|
<item id="8603" min="1" max="1" chance="1.1" /> <!-- Herb of Mana -->
|
||||||
</group>
|
<item id="8604" min="1" max="1" chance="5.94" /> <!-- Major Herb of Mana -->
|
||||||
<group chance="11">
|
<item id="8605" min="1" max="1" chance="3.96" /> <!-- Superior Herb of Mana -->
|
||||||
<item id="8603" min="1" max="1" chance="10" /> <!-- Herb of Mana -->
|
<item id="8606" min="1" max="1" chance="5" /> <!-- Herb of Power -->
|
||||||
<item id="8604" min="1" max="1" chance="54" /> <!-- Major Herb of Mana -->
|
<item id="8608" min="1" max="1" chance="5" /> <!-- Haste Herb -->
|
||||||
<item id="8605" min="1" max="1" chance="36" /> <!-- Superior Herb of Mana -->
|
<item id="8610" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Probability -->
|
||||||
</group>
|
<item id="10655" min="1" max="1" chance="5" /> <!-- Herb of HP Drain -->
|
||||||
<group chance="25">
|
<item id="10656" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Power -->
|
||||||
<item id="8606" min="1" max="1" chance="20" /> <!-- Herb of Power -->
|
<item id="8607" min="1" max="1" chance="5" /> <!-- Herb of Magic -->
|
||||||
<item id="8608" min="1" max="1" chance="20" /> <!-- Haste Herb -->
|
<item id="8609" min="1" max="1" chance="5" /> <!-- Herb of Casting Spd. -->
|
||||||
<item id="8610" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Probability -->
|
<item id="8612" min="1" max="1" chance="0.33" /> <!-- Herb of the Warrior -->
|
||||||
<item id="10655" min="1" max="1" chance="20" /> <!-- Herb of HP Drain -->
|
<item id="8613" min="1" max="1" chance="0.33" /> <!-- Wizard Herb -->
|
||||||
<item id="10656" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Power -->
|
<item id="8614" min="1" max="1" chance="0.34" /> <!-- Herb of Recovery -->
|
||||||
</group>
|
<item id="8611" min="1" max="1" chance="10.34" /> <!-- Wind Walk Herb -->
|
||||||
<group chance="10">
|
<item id="10657" min="1" max="1" chance="0.66" /> <!-- Mysterious Herb -->
|
||||||
<item id="8607" min="1" max="1" chance="50" /> <!-- Herb of Magic -->
|
</drop>
|
||||||
<item id="8609" min="1" max="1" chance="50" /> <!-- Herb of Casting Spd. -->
|
</drop_lists>
|
||||||
</group>
|
<status undying="false" />
|
||||||
<group chance="1">
|
<collision>
|
||||||
<item id="8612" min="1" max="1" chance="33" /> <!-- Herb of the Warrior -->
|
<radius normal="9" />
|
||||||
<item id="8613" min="1" max="1" chance="33" /> <!-- Wizard Herb -->
|
<height normal="29" />
|
||||||
<item id="8614" min="1" max="1" chance="34" /> <!-- Herb of Recovery -->
|
</collision>
|
||||||
</group>
|
</npc>
|
||||||
<group chance="11">
|
<npc id="2082" level="82" type="L2Monster" name="Canabion of Plague" title="Doppler">
|
||||||
<item id="8611" min="1" max="1" chance="94" /> <!-- Wind Walk Herb -->
|
<!-- TODO: Must be confirmed -->
|
||||||
<item id="10657" min="1" max="1" chance="6" /> <!-- Mysterious Herb -->
|
<parameters>
|
||||||
</group>
|
<param name="MoveAroundSocial" value="160" />
|
||||||
</death>
|
<param name="MoveAroundSocial1" value="160" />
|
||||||
</drop_lists>
|
<param name="MoveAroundSocial2" value="160" />
|
||||||
<status undying="false" />
|
<param name="IsAggressive" value="1" />
|
||||||
<collision>
|
<param name="Aggressive_Time" value="1" />
|
||||||
<radius normal="9" />
|
<param name="Skill01_Probablity" value="3500" />
|
||||||
<height normal="29" />
|
<param name="Type" value="1" />
|
||||||
</collision>
|
<param name="PrivatesNorm" value="2081" />
|
||||||
</npc>
|
<param name="PrivatesSpA" value="2082" />
|
||||||
<npc id="2082" level="82" type="L2Monster" name="Canabion of Plague" title="Doppler">
|
<param name="PrivatesSpB" value="2083" />
|
||||||
<!-- TODO: Must be confirmed -->
|
<param name="MyMakerName" value="inzone03_2111_80m1" />
|
||||||
<parameters>
|
<param name="SoulShot" value="200" />
|
||||||
<param name="MoveAroundSocial" value="160" />
|
<param name="SoulShotRate" value="5" />
|
||||||
<param name="MoveAroundSocial1" value="160" />
|
<param name="SpiritShot" value="100" />
|
||||||
<param name="MoveAroundSocial2" value="160" />
|
<param name="SpiritShotRate" value="10" />
|
||||||
<param name="IsAggressive" value="1" />
|
<param name="LongRangeGuardRate" value="5" />
|
||||||
<param name="Aggressive_Time" value="1" />
|
<skill name="Skill01_ID" id="4032" level="8" />
|
||||||
<param name="Skill01_Probablity" value="3500" />
|
<skill name="Debuff" id="5719" level="1" />
|
||||||
<param name="Type" value="1" />
|
</parameters>
|
||||||
<param name="PrivatesNorm" value="2081" />
|
<race>DEMONIC</race>
|
||||||
<param name="PrivatesSpA" value="2082" />
|
<sex>FEMALE</sex>
|
||||||
<param name="PrivatesSpB" value="2083" />
|
<acquire exp="12707" sp="3" />
|
||||||
<param name="MyMakerName" value="inzone03_2111_80m1" />
|
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
|
||||||
<param name="SoulShot" value="200" />
|
<vitals hp="3643" mp="1743" hpRegen="8.5" mpRegen="3" />
|
||||||
<param name="SoulShotRate" value="5" />
|
<attack physical="1055.28566004965" magical="720.623302603812" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="10" critical="4" accuracy="5" />
|
||||||
<param name="SpiritShot" value="100" />
|
<defence physical="349.77477" magical="255.95" />
|
||||||
<param name="SpiritShotRate" value="10" />
|
<attribute>
|
||||||
<param name="LongRangeGuardRate" value="5" />
|
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
|
||||||
<skill name="Skill01_ID" id="4032" level="8" />
|
</attribute>
|
||||||
<skill name="Debuff" id="5719" level="1" />
|
<speed>
|
||||||
</parameters>
|
<walk ground="10" />
|
||||||
<race>DEMONIC</race>
|
<run ground="120" />
|
||||||
<sex>FEMALE</sex>
|
</speed>
|
||||||
<acquire exp="12707" sp="3" />
|
<abnormalResist physical="10" magical="10" />
|
||||||
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
|
</stats>
|
||||||
<vitals hp="3643" mp="1743" hpRegen="8.5" mpRegen="3" />
|
<skill_list>
|
||||||
<attack physical="1055.28566004965" magical="720.623302603812" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="10" critical="4" accuracy="5" />
|
<skill id="4032" level="1" /> <!-- NPC Strike -->
|
||||||
<defence physical="349.77477" magical="255.95" />
|
<skill id="4416" level="9" /> <!-- Demons -->
|
||||||
<attribute>
|
<skill id="5565" level="1" /> <!-- Expose Weak Point -->
|
||||||
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
|
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
||||||
</attribute>
|
</skill_list>
|
||||||
<speed>
|
<ai clanHelpRange="200" aggroRange="300">
|
||||||
<walk ground="10" />
|
<clan_list>
|
||||||
<run ground="120" />
|
<clan>RIM</clan>
|
||||||
</speed>
|
<ignore_npc_id>2081</ignore_npc_id>
|
||||||
<abnormalResist physical="10" magical="10" />
|
</clan_list>
|
||||||
</stats>
|
</ai>
|
||||||
<skill_list>
|
<drop_lists>
|
||||||
<skill id="4032" level="1" /> <!-- NPC Strike -->
|
<drop>
|
||||||
<skill id="4416" level="9" /> <!-- Demons -->
|
<item id="8600" min="1" max="1" chance="8.4" /> <!-- Herb of Life -->
|
||||||
<skill id="5565" level="1" /> <!-- Expose Weak Point -->
|
<item id="8601" min="1" max="1" chance="18.9" /> <!-- Major Herb of Life -->
|
||||||
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
<item id="8602" min="1" max="1" chance="14.7" /> <!-- Superior Herb of Life -->
|
||||||
</skill_list>
|
<item id="8603" min="1" max="1" chance="1.1" /> <!-- Herb of Mana -->
|
||||||
<ai clanHelpRange="200" aggroRange="300">
|
<item id="8604" min="1" max="1" chance="5.94" /> <!-- Major Herb of Mana -->
|
||||||
<clan_list>
|
<item id="8605" min="1" max="1" chance="3.96" /> <!-- Superior Herb of Mana -->
|
||||||
<clan>RIM</clan>
|
<item id="8606" min="1" max="1" chance="5" /> <!-- Herb of Power -->
|
||||||
<ignore_npc_id>2081</ignore_npc_id>
|
<item id="8608" min="1" max="1" chance="5" /> <!-- Haste Herb -->
|
||||||
</clan_list>
|
<item id="8610" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Probability -->
|
||||||
</ai>
|
<item id="10655" min="1" max="1" chance="5" /> <!-- Herb of HP Drain -->
|
||||||
<drop_lists>
|
<item id="10656" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Power -->
|
||||||
<death>
|
<item id="8607" min="1" max="1" chance="5" /> <!-- Herb of Magic -->
|
||||||
<group chance="42">
|
<item id="8609" min="1" max="1" chance="5" /> <!-- Herb of Casting Spd. -->
|
||||||
<item id="8600" min="1" max="1" chance="20" /> <!-- Herb of Life -->
|
<item id="8612" min="1" max="1" chance="0.33" /> <!-- Herb of the Warrior -->
|
||||||
<item id="8601" min="1" max="1" chance="45" /> <!-- Major Herb of Life -->
|
<item id="8613" min="1" max="1" chance="0.33" /> <!-- Wizard Herb -->
|
||||||
<item id="8602" min="1" max="1" chance="35" /> <!-- Superior Herb of Life -->
|
<item id="8614" min="1" max="1" chance="0.34" /> <!-- Herb of Recovery -->
|
||||||
</group>
|
<item id="8611" min="1" max="1" chance="10.34" /> <!-- Wind Walk Herb -->
|
||||||
<group chance="11">
|
<item id="10657" min="1" max="1" chance="0.66" /> <!-- Mysterious Herb -->
|
||||||
<item id="8603" min="1" max="1" chance="10" /> <!-- Herb of Mana -->
|
</drop>
|
||||||
<item id="8604" min="1" max="1" chance="54" /> <!-- Major Herb of Mana -->
|
</drop_lists>
|
||||||
<item id="8605" min="1" max="1" chance="36" /> <!-- Superior Herb of Mana -->
|
<status undying="false" />
|
||||||
</group>
|
<collision>
|
||||||
<group chance="25">
|
<radius normal="9" />
|
||||||
<item id="8606" min="1" max="1" chance="20" /> <!-- Herb of Power -->
|
<height normal="31.5" />
|
||||||
<item id="8608" min="1" max="1" chance="20" /> <!-- Haste Herb -->
|
</collision>
|
||||||
<item id="8610" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Probability -->
|
</npc>
|
||||||
<item id="10655" min="1" max="1" chance="20" /> <!-- Herb of HP Drain -->
|
<npc id="2083" level="83" type="L2Monster" name="Canabion of Plague" title="Void">
|
||||||
<item id="10656" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Power -->
|
<!-- TODO: Must be confirmed -->
|
||||||
</group>
|
<parameters>
|
||||||
<group chance="10">
|
<param name="MoveAroundSocial" value="160" />
|
||||||
<item id="8607" min="1" max="1" chance="50" /> <!-- Herb of Magic -->
|
<param name="MoveAroundSocial1" value="160" />
|
||||||
<item id="8609" min="1" max="1" chance="50" /> <!-- Herb of Casting Spd. -->
|
<param name="MoveAroundSocial2" value="160" />
|
||||||
</group>
|
<param name="IsAggressive" value="1" />
|
||||||
<group chance="1">
|
<param name="Aggressive_Time" value="1" />
|
||||||
<item id="8612" min="1" max="1" chance="33" /> <!-- Herb of the Warrior -->
|
<param name="Skill01_Probablity" value="4500" />
|
||||||
<item id="8613" min="1" max="1" chance="33" /> <!-- Wizard Herb -->
|
<param name="Type" value="2" />
|
||||||
<item id="8614" min="1" max="1" chance="34" /> <!-- Herb of Recovery -->
|
<param name="PrivatesNorm" value="2081" />
|
||||||
</group>
|
<param name="PrivatesSpA" value="2082" />
|
||||||
<group chance="11">
|
<param name="PrivatesSpB" value="2083" />
|
||||||
<item id="8611" min="1" max="1" chance="94" /> <!-- Wind Walk Herb -->
|
<param name="MyMakerName" value="inzone03_2111_80m1" />
|
||||||
<item id="10657" min="1" max="1" chance="6" /> <!-- Mysterious Herb -->
|
<param name="SoulShot" value="200" />
|
||||||
</group>
|
<param name="SoulShotRate" value="5" />
|
||||||
</death>
|
<param name="SpiritShot" value="100" />
|
||||||
</drop_lists>
|
<param name="SpiritShotRate" value="10" />
|
||||||
<status undying="false" />
|
<param name="LongRangeGuardRate" value="5" />
|
||||||
<collision>
|
<skill name="Skill01_ID" id="4032" level="8" />
|
||||||
<radius normal="9" />
|
<skill name="Buff" id="4340" level="1" />
|
||||||
<height normal="31.5" />
|
<skill name="Debuff" id="5719" level="1" />
|
||||||
</collision>
|
</parameters>
|
||||||
</npc>
|
<race>HUMANOID</race>
|
||||||
<npc id="2083" level="83" type="L2Monster" name="Canabion of Plague" title="Void">
|
<sex>MALE</sex>
|
||||||
<!-- TODO: Must be confirmed -->
|
<acquire exp="13020" sp="3" />
|
||||||
<parameters>
|
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
|
||||||
<param name="MoveAroundSocial" value="160" />
|
<vitals hp="3835" mp="1777" hpRegen="8.5" mpRegen="3" />
|
||||||
<param name="MoveAroundSocial1" value="160" />
|
<attack physical="1099.42361669366" magical="750.763809564873" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="10" critical="4" accuracy="5" />
|
||||||
<param name="MoveAroundSocial2" value="160" />
|
<defence physical="353.86144" magical="258.94045" />
|
||||||
<param name="IsAggressive" value="1" />
|
<attribute>
|
||||||
<param name="Aggressive_Time" value="1" />
|
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
|
||||||
<param name="Skill01_Probablity" value="4500" />
|
</attribute>
|
||||||
<param name="Type" value="2" />
|
<speed>
|
||||||
<param name="PrivatesNorm" value="2081" />
|
<walk ground="15" />
|
||||||
<param name="PrivatesSpA" value="2082" />
|
<run ground="120" />
|
||||||
<param name="PrivatesSpB" value="2083" />
|
</speed>
|
||||||
<param name="MyMakerName" value="inzone03_2111_80m1" />
|
<abnormalResist physical="10" magical="10" />
|
||||||
<param name="SoulShot" value="200" />
|
</stats>
|
||||||
<param name="SoulShotRate" value="5" />
|
<skill_list>
|
||||||
<param name="SpiritShot" value="100" />
|
<skill id="4032" level="1" /> <!-- NPC Strike -->
|
||||||
<param name="SpiritShotRate" value="10" />
|
<skill id="4340" level="1" /> <!-- Ultimate Buff, 2nd -->
|
||||||
<param name="LongRangeGuardRate" value="5" />
|
<skill id="4416" level="9" /> <!-- Demons -->
|
||||||
<skill name="Skill01_ID" id="4032" level="8" />
|
<skill id="5565" level="1" /> <!-- Expose Weak Point -->
|
||||||
<skill name="Buff" id="4340" level="1" />
|
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
||||||
<skill name="Debuff" id="5719" level="1" />
|
</skill_list>
|
||||||
</parameters>
|
<ai clanHelpRange="300" aggroRange="300">
|
||||||
<race>HUMANOID</race>
|
<clan_list>
|
||||||
<sex>MALE</sex>
|
<clan>RIM</clan>
|
||||||
<acquire exp="13020" sp="3" />
|
<ignore_npc_id>2081</ignore_npc_id>
|
||||||
<stats str="88" int="79" dex="55" wit="78" con="82" men="78">
|
</clan_list>
|
||||||
<vitals hp="3835" mp="1777" hpRegen="8.5" mpRegen="3" />
|
</ai>
|
||||||
<attack physical="1099.42361669366" magical="750.763809564873" attackSpeed="253" range="40" type="SWORD" distance="80" width="120" random="10" critical="4" accuracy="5" />
|
<drop_lists>
|
||||||
<defence physical="353.86144" magical="258.94045" />
|
<drop>
|
||||||
<attribute>
|
<item id="8600" min="1" max="1" chance="8.4" /> <!-- Herb of Life -->
|
||||||
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
|
<item id="8601" min="1" max="1" chance="18.9" /> <!-- Major Herb of Life -->
|
||||||
</attribute>
|
<item id="8602" min="1" max="1" chance="14.7" /> <!-- Superior Herb of Life -->
|
||||||
<speed>
|
<item id="8603" min="1" max="1" chance="1.1" /> <!-- Herb of Mana -->
|
||||||
<walk ground="15" />
|
<item id="8604" min="1" max="1" chance="5.94" /> <!-- Major Herb of Mana -->
|
||||||
<run ground="120" />
|
<item id="8605" min="1" max="1" chance="3.96" /> <!-- Superior Herb of Mana -->
|
||||||
</speed>
|
<item id="8606" min="1" max="1" chance="5" /> <!-- Herb of Power -->
|
||||||
<abnormalResist physical="10" magical="10" />
|
<item id="8608" min="1" max="1" chance="5" /> <!-- Haste Herb -->
|
||||||
</stats>
|
<item id="8610" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Probability -->
|
||||||
<skill_list>
|
<item id="10655" min="1" max="1" chance="5" /> <!-- Herb of HP Drain -->
|
||||||
<skill id="4032" level="1" /> <!-- NPC Strike -->
|
<item id="10656" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Power -->
|
||||||
<skill id="4340" level="1" /> <!-- Ultimate Buff, 2nd -->
|
<item id="8607" min="1" max="1" chance="5" /> <!-- Herb of Magic -->
|
||||||
<skill id="4416" level="9" /> <!-- Demons -->
|
<item id="8609" min="1" max="1" chance="5" /> <!-- Herb of Casting Spd. -->
|
||||||
<skill id="5565" level="1" /> <!-- Expose Weak Point -->
|
<item id="8612" min="1" max="1" chance="0.33" /> <!-- Herb of the Warrior -->
|
||||||
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
<item id="8613" min="1" max="1" chance="0.33" /> <!-- Wizard Herb -->
|
||||||
</skill_list>
|
<item id="8614" min="1" max="1" chance="0.34" /> <!-- Herb of Recovery -->
|
||||||
<ai clanHelpRange="300" aggroRange="300">
|
<item id="8611" min="1" max="1" chance="10.34" /> <!-- Wind Walk Herb -->
|
||||||
<clan_list>
|
<item id="10657" min="1" max="1" chance="0.66" /> <!-- Mysterious Herb -->
|
||||||
<clan>RIM</clan>
|
</drop>
|
||||||
<ignore_npc_id>2081</ignore_npc_id>
|
</drop_lists>
|
||||||
</clan_list>
|
<status undying="false" />
|
||||||
</ai>
|
<collision>
|
||||||
<drop_lists>
|
<radius normal="10" />
|
||||||
<death>
|
<height normal="35" />
|
||||||
<group chance="42">
|
</collision>
|
||||||
<item id="8600" min="1" max="1" chance="20" /> <!-- Herb of Life -->
|
</npc>
|
||||||
<item id="8601" min="1" max="1" chance="45" /> <!-- Major Herb of Life -->
|
</list>
|
||||||
<item id="8602" min="1" max="1" chance="35" /> <!-- Superior Herb of Life -->
|
|
||||||
</group>
|
|
||||||
<group chance="11">
|
|
||||||
<item id="8603" min="1" max="1" chance="10" /> <!-- Herb of Mana -->
|
|
||||||
<item id="8604" min="1" max="1" chance="54" /> <!-- Major Herb of Mana -->
|
|
||||||
<item id="8605" min="1" max="1" chance="36" /> <!-- Superior Herb of Mana -->
|
|
||||||
</group>
|
|
||||||
<group chance="25">
|
|
||||||
<item id="8606" min="1" max="1" chance="20" /> <!-- Herb of Power -->
|
|
||||||
<item id="8608" min="1" max="1" chance="20" /> <!-- Haste Herb -->
|
|
||||||
<item id="8610" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Probability -->
|
|
||||||
<item id="10655" min="1" max="1" chance="20" /> <!-- Herb of HP Drain -->
|
|
||||||
<item id="10656" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Power -->
|
|
||||||
</group>
|
|
||||||
<group chance="10">
|
|
||||||
<item id="8607" min="1" max="1" chance="50" /> <!-- Herb of Magic -->
|
|
||||||
<item id="8609" min="1" max="1" chance="50" /> <!-- Herb of Casting Spd. -->
|
|
||||||
</group>
|
|
||||||
<group chance="1">
|
|
||||||
<item id="8612" min="1" max="1" chance="33" /> <!-- Herb of the Warrior -->
|
|
||||||
<item id="8613" min="1" max="1" chance="33" /> <!-- Wizard Herb -->
|
|
||||||
<item id="8614" min="1" max="1" chance="34" /> <!-- Herb of Recovery -->
|
|
||||||
</group>
|
|
||||||
<group chance="11">
|
|
||||||
<item id="8611" min="1" max="1" chance="94" /> <!-- Wind Walk Herb -->
|
|
||||||
<item id="10657" min="1" max="1" chance="6" /> <!-- Mysterious Herb -->
|
|
||||||
</group>
|
|
||||||
</death>
|
|
||||||
</drop_lists>
|
|
||||||
<status undying="false" />
|
|
||||||
<collision>
|
|
||||||
<radius normal="10" />
|
|
||||||
<height normal="35" />
|
|
||||||
</collision>
|
|
||||||
</npc>
|
|
||||||
</list>
|
|
||||||
|
@ -2771,7 +2771,7 @@
|
|||||||
<height normal="68" />
|
<height normal="68" />
|
||||||
</collision>
|
</collision>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<item id="17404" min="1" max="1" chance="1.074" /> <!-- Seraph Leather Leggings -->
|
<item id="17404" min="1" max="1" chance="1.074" /> <!-- Seraph Leather Leggings -->
|
||||||
<item id="17398" min="1" max="1" chance="1.043" /> <!-- Seraph Gaiters -->
|
<item id="17398" min="1" max="1" chance="1.043" /> <!-- Seraph Gaiters -->
|
||||||
<item id="17409" min="1" max="1" chance="0.974" /> <!-- Seraph Stockings -->
|
<item id="17409" min="1" max="1" chance="0.974" /> <!-- Seraph Stockings -->
|
||||||
@ -2821,7 +2821,7 @@
|
|||||||
<item id="35438" min="1" max="1" chance="0.3" /> <!-- Recipe: Seraph Leather Armor (60%) -->
|
<item id="35438" min="1" max="1" chance="0.3" /> <!-- Recipe: Seraph Leather Armor (60%) -->
|
||||||
<item id="35439" min="1" max="1" chance="0.3" /> <!-- Recipe: Seraph Leather Leggings (60%) -->
|
<item id="35439" min="1" max="1" chance="0.3" /> <!-- Recipe: Seraph Leather Leggings (60%) -->
|
||||||
<item id="35430" min="1" max="1" chance="0.3" /> <!-- Recipe: Specter Retributer (60%) -->
|
<item id="35430" min="1" max="1" chance="0.3" /> <!-- Recipe: Specter Retributer (60%) -->
|
||||||
</death>
|
</drop>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
</npc>
|
</npc>
|
||||||
<npc id="3474" level="95" type="L2Monster" name="Super Kat the Cat">
|
<npc id="3474" level="95" type="L2Monster" name="Super Kat the Cat">
|
||||||
@ -3003,7 +3003,7 @@
|
|||||||
<height normal="37.5" />
|
<height normal="37.5" />
|
||||||
</collision>
|
</collision>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<item id="17308" min="1" max="1" chance="23.3" /> <!-- Immortal Boots -->
|
<item id="17308" min="1" max="1" chance="23.3" /> <!-- Immortal Boots -->
|
||||||
<item id="17318" min="1" max="1" chance="22.9" /> <!-- Immortal Gloves -->
|
<item id="17318" min="1" max="1" chance="22.9" /> <!-- Immortal Gloves -->
|
||||||
<item id="17304" min="1" max="1" chance="16.58" /> <!-- Immortal Helmet -->
|
<item id="17304" min="1" max="1" chance="16.58" /> <!-- Immortal Helmet -->
|
||||||
@ -3016,7 +3016,7 @@
|
|||||||
<item id="17291" min="1" max="1" chance="1.482" /> <!-- Requiem Cutter -->
|
<item id="17291" min="1" max="1" chance="1.482" /> <!-- Requiem Cutter -->
|
||||||
<item id="17527" min="1" max="1" chance="46.38" /> <!-- Scroll: Enchant Armor (R-grade) -->
|
<item id="17527" min="1" max="1" chance="46.38" /> <!-- Scroll: Enchant Armor (R-grade) -->
|
||||||
<item id="17526" min="1" max="1" chance="3.604" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
<item id="17526" min="1" max="1" chance="3.604" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
||||||
</death>
|
</drop>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
</npc>
|
</npc>
|
||||||
<npc id="3478" level="87" type="L2Monster" name="Reinforced Kat the Cat">
|
<npc id="3478" level="87" type="L2Monster" name="Reinforced Kat the Cat">
|
||||||
@ -3112,7 +3112,7 @@
|
|||||||
<height normal="37.5" />
|
<height normal="37.5" />
|
||||||
</collision>
|
</collision>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<item id="17343" min="1" max="1" chance="66.6" /> <!-- Twilight Shield -->
|
<item id="17343" min="1" max="1" chance="66.6" /> <!-- Twilight Shield -->
|
||||||
<item id="17339" min="1" max="1" chance="17.44" /> <!-- Twilight Breastplate -->
|
<item id="17339" min="1" max="1" chance="17.44" /> <!-- Twilight Breastplate -->
|
||||||
<item id="17350" min="1" max="1" chance="16.67" /> <!-- Twilight Tunic -->
|
<item id="17350" min="1" max="1" chance="16.67" /> <!-- Twilight Tunic -->
|
||||||
@ -3120,7 +3120,7 @@
|
|||||||
<item id="17330" min="1" max="1" chance="0.75" /> <!-- Apocalypse Thrower -->
|
<item id="17330" min="1" max="1" chance="0.75" /> <!-- Apocalypse Thrower -->
|
||||||
<item id="17527" min="1" max="1" chance="46.65" /> <!-- Scroll: Enchant Armor (R-grade) -->
|
<item id="17527" min="1" max="1" chance="46.65" /> <!-- Scroll: Enchant Armor (R-grade) -->
|
||||||
<item id="17526" min="1" max="1" chance="3.631" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
<item id="17526" min="1" max="1" chance="3.631" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
||||||
</death>
|
</drop>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
</npc>
|
</npc>
|
||||||
<npc id="3480" level="91" type="L2Monster" name="Mind-controlling Feline Queen">
|
<npc id="3480" level="91" type="L2Monster" name="Mind-controlling Feline Queen">
|
||||||
@ -3216,13 +3216,13 @@
|
|||||||
<height normal="37.5" />
|
<height normal="37.5" />
|
||||||
</collision>
|
</collision>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<item id="17352" min="1" max="1" chance="91.435" /> <!-- Twilight Gloves -->
|
<item id="17352" min="1" max="1" chance="91.435" /> <!-- Twilight Gloves -->
|
||||||
<item id="17347" min="1" max="1" chance="19.86" /> <!-- Twilight Leather Gloves -->
|
<item id="17347" min="1" max="1" chance="19.86" /> <!-- Twilight Leather Gloves -->
|
||||||
<item id="17330" min="1" max="1" chance="7.489" /> <!-- Apocalypse Thrower -->
|
<item id="17330" min="1" max="1" chance="7.489" /> <!-- Apocalypse Thrower -->
|
||||||
<item id="17334" min="1" max="1" chance="1.587" /> <!-- Apocalypse Retributer -->
|
<item id="17334" min="1" max="1" chance="1.587" /> <!-- Apocalypse Retributer -->
|
||||||
<item id="17526" min="1" max="1" chance="35.82" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
<item id="17526" min="1" max="1" chance="35.82" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
||||||
</death>
|
</drop>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
</npc>
|
</npc>
|
||||||
<npc id="3482" level="93" type="L2Monster" name="Traitorous Mew the Cat">
|
<npc id="3482" level="93" type="L2Monster" name="Traitorous Mew the Cat">
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1876,7 +1876,7 @@
|
|||||||
</skill_list>
|
</skill_list>
|
||||||
<ai aggroRange="300" isAggressive="true" clanHelpRange="300" />
|
<ai aggroRange="300" isAggressive="true" clanHelpRange="300" />
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<item id="17623" min="1" max="1" chance="10.047" /> <!-- Earth Wyrm Heart Ring -->
|
<item id="17623" min="1" max="1" chance="10.047" /> <!-- Earth Wyrm Heart Ring -->
|
||||||
<item id="17422" min="1" max="1" chance="9.133" /> <!-- Helios Thrower -->
|
<item id="17422" min="1" max="1" chance="9.133" /> <!-- Helios Thrower -->
|
||||||
<item id="17425" min="1" max="1" chance="9.106" /> <!-- Helios Caster -->
|
<item id="17425" min="1" max="1" chance="9.106" /> <!-- Helios Caster -->
|
||||||
@ -1932,11 +1932,11 @@
|
|||||||
<item id="39484" min="1" max="1" chance="3.339" /> <!-- Alchemic Tome: Life Stone -->
|
<item id="39484" min="1" max="1" chance="3.339" /> <!-- Alchemic Tome: Life Stone -->
|
||||||
<item id="39483" min="1" max="1" chance="3.31" /> <!-- Alchemic Tome: Enchant Scroll -->
|
<item id="39483" min="1" max="1" chance="3.31" /> <!-- Alchemic Tome: Enchant Scroll -->
|
||||||
<item id="39485" min="1" max="1" chance="3.266" /> <!-- Alchemic Tome: Dye -->
|
<item id="39485" min="1" max="1" chance="3.266" /> <!-- Alchemic Tome: Dye -->
|
||||||
</death>
|
</drop>
|
||||||
<lucky_corpse>
|
<lucky_drop>
|
||||||
<item id="39629" min="3" max="3" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
<item id="39629" min="3" max="3" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
||||||
<item id="40198" min="1" max="1" chance="2.518" /> <!-- Disassembly Recipe Pouch: Armor -->
|
<item id="40198" min="1" max="1" chance="2.518" /> <!-- Disassembly Recipe Pouch: Armor -->
|
||||||
</lucky_corpse>
|
</lucky_drop>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
<collision>
|
<collision>
|
||||||
<radius normal="500" />
|
<radius normal="500" />
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,361 +1,341 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
|
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
|
||||||
<npc id="21438" level="65" type="L2Monster" name="Heathen Warrior">
|
<npc id="21438" level="65" type="L2Monster" name="Heathen Warrior">
|
||||||
<!-- Confirmed CT2.5 -->
|
<!-- Confirmed CT2.5 -->
|
||||||
<parameters>
|
<parameters>
|
||||||
<param name="MoveAroundSocial" value="80" />
|
<param name="MoveAroundSocial" value="80" />
|
||||||
<param name="MoveAroundSocial1" value="80" />
|
<param name="MoveAroundSocial1" value="80" />
|
||||||
<param name="MoveAroundSocial2" value="80" />
|
<param name="MoveAroundSocial2" value="80" />
|
||||||
<param name="SoulShot" value="100" />
|
<param name="SoulShot" value="100" />
|
||||||
<param name="SoulShotRate" value="30" />
|
<param name="SoulShotRate" value="30" />
|
||||||
<param name="LongRangeGuardRate" value="5" />
|
<param name="LongRangeGuardRate" value="5" />
|
||||||
<skill name="PhysicalSpecial" id="4032" level="6" />
|
<skill name="PhysicalSpecial" id="4032" level="6" />
|
||||||
</parameters>
|
</parameters>
|
||||||
<race>UNDEAD</race>
|
<race>UNDEAD</race>
|
||||||
<sex>MALE</sex>
|
<sex>MALE</sex>
|
||||||
<equipment rhand="946" lhand="945" /> <!-- Skeleton Dagger / Skeleton Buckler -->
|
<equipment rhand="946" lhand="945" /> <!-- Skeleton Dagger / Skeleton Buckler -->
|
||||||
<acquire exp="2684" sp="1" />
|
<acquire exp="2684" sp="1" />
|
||||||
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
||||||
<vitals hp="2193.43142" hpRegen="7.5" mp="1188.8" mpRegen="2.7" />
|
<vitals hp="2193.43142" hpRegen="7.5" mp="1188.8" mpRegen="2.7" />
|
||||||
<attack physical="582.81759" magical="397.98887" random="5" critical="8" accuracy="0" attackSpeed="253" type="DAGGER" range="40" distance="80" width="120" />
|
<attack physical="582.81759" magical="397.98887" random="5" critical="8" accuracy="0" attackSpeed="253" type="DAGGER" range="40" distance="80" width="120" />
|
||||||
<defence physical="271.89033" magical="198.95754" shield="136" shieldRate="20" />
|
<defence physical="271.89033" magical="198.95754" shield="136" shieldRate="20" />
|
||||||
<speed>
|
<speed>
|
||||||
<walk ground="80" />
|
<walk ground="80" />
|
||||||
<run ground="175" />
|
<run ground="175" />
|
||||||
</speed>
|
</speed>
|
||||||
<hit_time>520</hit_time>
|
<hit_time>520</hit_time>
|
||||||
<abnormalResist physical="10" magical="10" />
|
<abnormalResist physical="10" magical="10" />
|
||||||
</stats>
|
</stats>
|
||||||
<status undying="false" canBeSown="true" />
|
<status undying="false" canBeSown="true" />
|
||||||
<skill_list>
|
<skill_list>
|
||||||
<skill id="4032" level="6" /> <!-- NPC Strike -->
|
<skill id="4032" level="6" /> <!-- NPC Strike -->
|
||||||
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
|
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
|
||||||
<skill id="4408" level="8" /> <!-- HP Increase (1/4x) -->
|
<skill id="4408" level="8" /> <!-- HP Increase (1/4x) -->
|
||||||
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
||||||
<skill id="4410" level="13" /> <!-- Slightly Strong P. Atk. -->
|
<skill id="4410" level="13" /> <!-- Slightly Strong P. Atk. -->
|
||||||
<skill id="4411" level="13" /> <!-- Slightly Strong M. Atk. -->
|
<skill id="4411" level="13" /> <!-- Slightly Strong M. Atk. -->
|
||||||
<skill id="4412" level="9" /> <!-- Slightly Weak P. Def. -->
|
<skill id="4412" level="9" /> <!-- Slightly Weak P. Def. -->
|
||||||
<skill id="4413" level="9" /> <!-- Slightly Weak M. Def. -->
|
<skill id="4413" level="9" /> <!-- Slightly Weak M. Def. -->
|
||||||
<skill id="4414" level="2" /> <!-- Standard Type -->
|
<skill id="4414" level="2" /> <!-- Standard Type -->
|
||||||
<skill id="4415" level="7" /> <!-- Daggers -->
|
<skill id="4415" level="7" /> <!-- Daggers -->
|
||||||
<skill id="4416" level="1" /> <!-- Undead -->
|
<skill id="4416" level="1" /> <!-- Undead -->
|
||||||
<skill id="4278" level="1" /> <!-- Dark Attack -->
|
<skill id="4278" level="1" /> <!-- Dark Attack -->
|
||||||
<skill id="4279" level="1" /> <!-- Fire Vulnerability -->
|
<skill id="4279" level="1" /> <!-- Fire Vulnerability -->
|
||||||
<skill id="4275" level="2" /> <!-- Holy Attack Vulnerability -->
|
<skill id="4275" level="2" /> <!-- Holy Attack Vulnerability -->
|
||||||
</skill_list>
|
</skill_list>
|
||||||
<shots shotChance="30" spiritChance="30" />
|
<shots shotChance="30" spiritChance="30" />
|
||||||
<ex_crt_effect>false</ex_crt_effect>
|
<ex_crt_effect>false</ex_crt_effect>
|
||||||
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
||||||
<ai aggroRange="300" clanHelpRange="300" isAggressive="true">
|
<ai aggroRange="300" clanHelpRange="300" isAggressive="true">
|
||||||
<clan_list>
|
<clan_list>
|
||||||
<clan>UNDEAD</clan>
|
<clan>UNDEAD</clan>
|
||||||
</clan_list>
|
</clan_list>
|
||||||
</ai>
|
</ai>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<group chance="70">
|
<item id="57" min="10" max="24" chance="70" /> <!-- Adena -->
|
||||||
<item id="57" min="10" max="24" chance="100" /> <!-- Adena -->
|
<item id="729" min="1" max="1" chance="0.003" /> <!-- Scroll: Enchant Weapon (A-grade) -->
|
||||||
</group>
|
</drop>
|
||||||
<group chance="0.003">
|
<spoil>
|
||||||
<item id="729" min="1" max="1" chance="100" /> <!-- Scroll: Enchant Weapon (A-grade) -->
|
<item id="729" min="1" max="1" chance="0.003" /> <!-- Scroll: Enchant Weapon (A-grade) -->
|
||||||
</group>
|
</spoil>
|
||||||
</death>
|
<lucky_drop>
|
||||||
<corpse>
|
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
||||||
<item id="729" min="1" max="1" chance="0.003" /> <!-- Scroll: Enchant Weapon (A-grade) -->
|
</lucky_drop>
|
||||||
</corpse>
|
</drop_lists>
|
||||||
<lucky_corpse>
|
<collision>
|
||||||
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
<radius normal="11" />
|
||||||
</lucky_corpse>
|
<height normal="28.5" />
|
||||||
</drop_lists>
|
</collision>
|
||||||
<collision>
|
</npc>
|
||||||
<radius normal="11" />
|
<npc id="21439" level="66" type="L2Monster" name="Heathen Inmate">
|
||||||
<height normal="28.5" />
|
<!-- Confirmed CT2.5 -->
|
||||||
</collision>
|
<parameters>
|
||||||
</npc>
|
<param name="MoveAroundSocial" value="130" />
|
||||||
<npc id="21439" level="66" type="L2Monster" name="Heathen Inmate">
|
<param name="MoveAroundSocial1" value="130" />
|
||||||
<!-- Confirmed CT2.5 -->
|
<param name="MoveAroundSocial2" value="130" />
|
||||||
<parameters>
|
<param name="SoulShot" value="100" />
|
||||||
<param name="MoveAroundSocial" value="130" />
|
<param name="SoulShotRate" value="30" />
|
||||||
<param name="MoveAroundSocial1" value="130" />
|
<param name="LongRangeGuardRate" value="5" />
|
||||||
<param name="MoveAroundSocial2" value="130" />
|
<skill name="PhysicalSpecial" id="4073" level="6" />
|
||||||
<param name="SoulShot" value="100" />
|
</parameters>
|
||||||
<param name="SoulShotRate" value="30" />
|
<race>UNDEAD</race>
|
||||||
<param name="LongRangeGuardRate" value="5" />
|
<sex>MALE</sex>
|
||||||
<skill name="PhysicalSpecial" id="4073" level="6" />
|
<acquire exp="2768" sp="1" />
|
||||||
</parameters>
|
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
||||||
<race>UNDEAD</race>
|
<vitals hp="2244.67715" hpRegen="7.5" mp="1219.8" mpRegen="2.7" />
|
||||||
<sex>MALE</sex>
|
<attack physical="603.79903" magical="412.31647" random="10" critical="4" accuracy="5" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
|
||||||
<acquire exp="2768" sp="1" />
|
<defence physical="276.72752" magical="202.49719" />
|
||||||
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
<speed>
|
||||||
<vitals hp="2244.67715" hpRegen="7.5" mp="1219.8" mpRegen="2.7" />
|
<walk ground="15" />
|
||||||
<attack physical="603.79903" magical="412.31647" random="10" critical="4" accuracy="5" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
|
<run ground="175" />
|
||||||
<defence physical="276.72752" magical="202.49719" />
|
</speed>
|
||||||
<speed>
|
<hit_time>450</hit_time>
|
||||||
<walk ground="15" />
|
<abnormalResist physical="10" magical="10" />
|
||||||
<run ground="175" />
|
</stats>
|
||||||
</speed>
|
<status undying="false" canBeSown="true" />
|
||||||
<hit_time>450</hit_time>
|
<skill_list>
|
||||||
<abnormalResist physical="10" magical="10" />
|
<skill id="4073" level="6" /> <!-- Stun -->
|
||||||
</stats>
|
<skill id="4408" level="8" /> <!-- HP Increase (1/4x) -->
|
||||||
<status undying="false" canBeSown="true" />
|
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
||||||
<skill_list>
|
<skill id="4410" level="13" /> <!-- Slightly Strong P. Atk. -->
|
||||||
<skill id="4073" level="6" /> <!-- Stun -->
|
<skill id="4411" level="13" /> <!-- Slightly Strong M. Atk. -->
|
||||||
<skill id="4408" level="8" /> <!-- HP Increase (1/4x) -->
|
<skill id="4412" level="9" /> <!-- Slightly Weak P. Def. -->
|
||||||
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
<skill id="4413" level="9" /> <!-- Slightly Weak M. Def. -->
|
||||||
<skill id="4410" level="13" /> <!-- Slightly Strong P. Atk. -->
|
<skill id="4414" level="3" /> <!-- Light Armor Type -->
|
||||||
<skill id="4411" level="13" /> <!-- Slightly Strong M. Atk. -->
|
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
||||||
<skill id="4412" level="9" /> <!-- Slightly Weak P. Def. -->
|
<skill id="4416" level="1" /> <!-- Undead -->
|
||||||
<skill id="4413" level="9" /> <!-- Slightly Weak M. Def. -->
|
<skill id="4278" level="1" /> <!-- Dark Attack -->
|
||||||
<skill id="4414" level="3" /> <!-- Light Armor Type -->
|
<skill id="4275" level="2" /> <!-- Holy Attack Vulnerability -->
|
||||||
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
</skill_list>
|
||||||
<skill id="4416" level="1" /> <!-- Undead -->
|
<shots shotChance="30" spiritChance="30" />
|
||||||
<skill id="4278" level="1" /> <!-- Dark Attack -->
|
<ex_crt_effect>false</ex_crt_effect>
|
||||||
<skill id="4275" level="2" /> <!-- Holy Attack Vulnerability -->
|
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
||||||
</skill_list>
|
<ai aggroRange="300" clanHelpRange="300" isAggressive="true">
|
||||||
<shots shotChance="30" spiritChance="30" />
|
<clan_list>
|
||||||
<ex_crt_effect>false</ex_crt_effect>
|
<clan>UNDEAD</clan>
|
||||||
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
</clan_list>
|
||||||
<ai aggroRange="300" clanHelpRange="300" isAggressive="true">
|
</ai>
|
||||||
<clan_list>
|
<drop_lists>
|
||||||
<clan>UNDEAD</clan>
|
<drop>
|
||||||
</clan_list>
|
<item id="57" min="11" max="25" chance="70" /> <!-- Adena -->
|
||||||
</ai>
|
<item id="730" min="1" max="1" chance="0.03" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
||||||
<drop_lists>
|
</drop>
|
||||||
<death>
|
<spoil>
|
||||||
<group chance="70">
|
<item id="730" min="1" max="1" chance="0.03" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
||||||
<item id="57" min="11" max="25" chance="100" /> <!-- Adena -->
|
</spoil>
|
||||||
</group>
|
<lucky_drop>
|
||||||
<group chance="0.03">
|
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
||||||
<item id="730" min="1" max="1" chance="100" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
</lucky_drop>
|
||||||
</group>
|
</drop_lists>
|
||||||
</death>
|
<collision>
|
||||||
<corpse>
|
<radius normal="30" grown="15.5" />
|
||||||
<item id="730" min="1" max="1" chance="0.03" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
<height normal="40" grown="48.5" />
|
||||||
</corpse>
|
</collision>
|
||||||
<lucky_corpse>
|
</npc>
|
||||||
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
<npc id="21440" level="67" type="L2Monster" name="Heathen Archer">
|
||||||
</lucky_corpse>
|
<!-- Confirmed CT2.5 -->
|
||||||
</drop_lists>
|
<parameters>
|
||||||
<collision>
|
<param name="MoveAroundSocial" value="157" />
|
||||||
<radius normal="30" grown="15.5" />
|
<param name="MoveAroundSocial1" value="157" />
|
||||||
<height normal="40" grown="48.5" />
|
<param name="MoveAroundSocial2" value="157" />
|
||||||
</collision>
|
<param name="SoulShot" value="100" />
|
||||||
</npc>
|
<param name="SoulShotRate" value="30" />
|
||||||
<npc id="21440" level="67" type="L2Monster" name="Heathen Archer">
|
<param name="LongRangeGuardRate" value="5" />
|
||||||
<!-- Confirmed CT2.5 -->
|
<skill name="PhysicalSpecial" id="4040" level="6" />
|
||||||
<parameters>
|
</parameters>
|
||||||
<param name="MoveAroundSocial" value="157" />
|
<race>UNDEAD</race>
|
||||||
<param name="MoveAroundSocial1" value="157" />
|
<sex>MALE</sex>
|
||||||
<param name="MoveAroundSocial2" value="157" />
|
<equipment rhand="284" /> <!-- Dark Elven Longbow -->
|
||||||
<param name="SoulShot" value="100" />
|
<acquire exp="3029" sp="1" />
|
||||||
<param name="SoulShotRate" value="30" />
|
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
||||||
<param name="LongRangeGuardRate" value="5" />
|
<vitals hp="2295.48154" hpRegen="7.5" mp="1251.0" mpRegen="2.7" />
|
||||||
<skill name="PhysicalSpecial" id="4040" level="6" />
|
<attack physical="624.93199" magical="426.74754" random="5" critical="8" accuracy="0" attackSpeed="253" reuseDelay="1500" type="BOW" range="1100" distance="10" width="0" />
|
||||||
</parameters>
|
<defence physical="281.55251" magical="206.02791" />
|
||||||
<race>UNDEAD</race>
|
<speed>
|
||||||
<sex>MALE</sex>
|
<walk ground="40" />
|
||||||
<equipment rhand="284" /> <!-- Dark Elven Longbow -->
|
<run ground="155" />
|
||||||
<acquire exp="3029" sp="1" />
|
</speed>
|
||||||
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
<hit_time>800</hit_time>
|
||||||
<vitals hp="2295.48154" hpRegen="7.5" mp="1251.0" mpRegen="2.7" />
|
<abnormalResist physical="10" magical="10" />
|
||||||
<attack physical="624.93199" magical="426.74754" random="5" critical="8" accuracy="0" attackSpeed="253" reuseDelay="1500" type="BOW" range="1100" distance="10" width="0" />
|
</stats>
|
||||||
<defence physical="281.55251" magical="206.02791" />
|
<status undying="false" canBeSown="true" />
|
||||||
<speed>
|
<skill_list>
|
||||||
<walk ground="40" />
|
<skill id="4040" level="6" /> <!-- NPC Bow Attack -->
|
||||||
<run ground="155" />
|
<skill id="4071" level="3" /> <!-- Resist Bow/Crossbow Weapons -->
|
||||||
</speed>
|
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
|
||||||
<hit_time>800</hit_time>
|
<skill id="4408" level="8" /> <!-- HP Increase (1/4x) -->
|
||||||
<abnormalResist physical="10" magical="10" />
|
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
||||||
</stats>
|
<skill id="4410" level="13" /> <!-- Slightly Strong P. Atk. -->
|
||||||
<status undying="false" canBeSown="true" />
|
<skill id="4411" level="13" /> <!-- Slightly Strong M. Atk. -->
|
||||||
<skill_list>
|
<skill id="4412" level="9" /> <!-- Slightly Weak P. Def. -->
|
||||||
<skill id="4040" level="6" /> <!-- NPC Bow Attack -->
|
<skill id="4413" level="9" /> <!-- Slightly Weak M. Def. -->
|
||||||
<skill id="4071" level="3" /> <!-- Resist Bow/Crossbow Weapons -->
|
<skill id="4414" level="3" /> <!-- Light Armor Type -->
|
||||||
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
|
<skill id="4415" level="9" /> <!-- Bows -->
|
||||||
<skill id="4408" level="8" /> <!-- HP Increase (1/4x) -->
|
<skill id="4416" level="1" /> <!-- Undead -->
|
||||||
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
<skill id="4278" level="1" /> <!-- Dark Attack -->
|
||||||
<skill id="4410" level="13" /> <!-- Slightly Strong P. Atk. -->
|
<skill id="4279" level="1" /> <!-- Fire Vulnerability -->
|
||||||
<skill id="4411" level="13" /> <!-- Slightly Strong M. Atk. -->
|
<skill id="4275" level="2" /> <!-- Holy Attack Vulnerability -->
|
||||||
<skill id="4412" level="9" /> <!-- Slightly Weak P. Def. -->
|
</skill_list>
|
||||||
<skill id="4413" level="9" /> <!-- Slightly Weak M. Def. -->
|
<shots shotChance="30" spiritChance="30" />
|
||||||
<skill id="4414" level="3" /> <!-- Light Armor Type -->
|
<ex_crt_effect>false</ex_crt_effect>
|
||||||
<skill id="4415" level="9" /> <!-- Bows -->
|
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
||||||
<skill id="4416" level="1" /> <!-- Undead -->
|
<ai type="ARCHER" clanHelpRange="300" dodge="15" aggroRange="300">
|
||||||
<skill id="4278" level="1" /> <!-- Dark Attack -->
|
<clan_list>
|
||||||
<skill id="4279" level="1" /> <!-- Fire Vulnerability -->
|
<clan>UNDEAD</clan>
|
||||||
<skill id="4275" level="2" /> <!-- Holy Attack Vulnerability -->
|
</clan_list>
|
||||||
</skill_list>
|
</ai>
|
||||||
<shots shotChance="30" spiritChance="30" />
|
<drop_lists>
|
||||||
<ex_crt_effect>false</ex_crt_effect>
|
<drop>
|
||||||
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
<item id="57" min="11" max="27" chance="70" /> <!-- Adena -->
|
||||||
<ai type="ARCHER" clanHelpRange="300" dodge="15" aggroRange="300">
|
<item id="730" min="1" max="1" chance="0.03" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
||||||
<clan_list>
|
</drop>
|
||||||
<clan>UNDEAD</clan>
|
<spoil>
|
||||||
</clan_list>
|
<item id="730" min="1" max="1" chance="0.03" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
||||||
</ai>
|
</spoil>
|
||||||
<drop_lists>
|
<lucky_drop>
|
||||||
<death>
|
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
||||||
<group chance="70">
|
</lucky_drop>
|
||||||
<item id="57" min="11" max="27" chance="100" /> <!-- Adena -->
|
</drop_lists>
|
||||||
</group>
|
<collision>
|
||||||
<group chance="0.03">
|
<radius normal="11" />
|
||||||
<item id="730" min="1" max="1" chance="100" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
<height normal="27" />
|
||||||
</group>
|
</collision>
|
||||||
</death>
|
</npc>
|
||||||
<corpse>
|
<npc id="21441" level="68" type="L2Monster" name="Heathen Soldier">
|
||||||
<item id="730" min="1" max="1" chance="0.03" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
<!-- Confirmed CT2.5 -->
|
||||||
</corpse>
|
<parameters>
|
||||||
<lucky_corpse>
|
<param name="MoveAroundSocial" value="0" />
|
||||||
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
<param name="MoveAroundSocial1" value="0" />
|
||||||
</lucky_corpse>
|
<param name="MoveAroundSocial2" value="0" />
|
||||||
</drop_lists>
|
<param name="SoulShot" value="100" />
|
||||||
<collision>
|
<param name="SoulShotRate" value="30" />
|
||||||
<radius normal="11" />
|
<param name="LongRangeGuardRate" value="5" />
|
||||||
<height normal="27" />
|
<skill name="PhysicalSpecial" id="4072" level="6" />
|
||||||
</collision>
|
</parameters>
|
||||||
</npc>
|
<race>UNDEAD</race>
|
||||||
<npc id="21441" level="68" type="L2Monster" name="Heathen Soldier">
|
<sex>MALE</sex>
|
||||||
<!-- Confirmed CT2.5 -->
|
<equipment rhand="96" /> <!-- Scythe -->
|
||||||
<parameters>
|
<acquire exp="2937" sp="1" />
|
||||||
<param name="MoveAroundSocial" value="0" />
|
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
||||||
<param name="MoveAroundSocial1" value="0" />
|
<vitals hp="2345.76698" hpRegen="7.5" mp="1282.4" mpRegen="2.7" />
|
||||||
<param name="MoveAroundSocial2" value="0" />
|
<attack physical="646.17968" magical="441.25696" random="10" critical="4" accuracy="5" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
|
||||||
<param name="SoulShot" value="100" />
|
<defence physical="286.3615" magical="209.54692" />
|
||||||
<param name="SoulShotRate" value="30" />
|
<speed>
|
||||||
<param name="LongRangeGuardRate" value="5" />
|
<walk ground="50" />
|
||||||
<skill name="PhysicalSpecial" id="4072" level="6" />
|
<run ground="170" />
|
||||||
</parameters>
|
</speed>
|
||||||
<race>UNDEAD</race>
|
<hit_time>210</hit_time>
|
||||||
<sex>MALE</sex>
|
<abnormalResist physical="10" magical="10" />
|
||||||
<equipment rhand="96" /> <!-- Scythe -->
|
</stats>
|
||||||
<acquire exp="2937" sp="1" />
|
<status undying="false" canBeSown="true" />
|
||||||
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
<skill_list>
|
||||||
<vitals hp="2345.76698" hpRegen="7.5" mp="1282.4" mpRegen="2.7" />
|
<skill id="4072" level="6" /> <!-- Stun -->
|
||||||
<attack physical="646.17968" magical="441.25696" random="10" critical="4" accuracy="5" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
|
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
|
||||||
<defence physical="286.3615" magical="209.54692" />
|
<skill id="4408" level="8" /> <!-- HP Increase (1/4x) -->
|
||||||
<speed>
|
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
||||||
<walk ground="50" />
|
<skill id="4410" level="13" /> <!-- Slightly Strong P. Atk. -->
|
||||||
<run ground="170" />
|
<skill id="4411" level="13" /> <!-- Slightly Strong M. Atk. -->
|
||||||
</speed>
|
<skill id="4412" level="9" /> <!-- Slightly Weak P. Def. -->
|
||||||
<hit_time>210</hit_time>
|
<skill id="4413" level="9" /> <!-- Slightly Weak M. Def. -->
|
||||||
<abnormalResist physical="10" magical="10" />
|
<skill id="4414" level="2" /> <!-- Standard Type -->
|
||||||
</stats>
|
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
||||||
<status undying="false" canBeSown="true" />
|
<skill id="4416" level="1" /> <!-- Undead -->
|
||||||
<skill_list>
|
<skill id="4278" level="1" /> <!-- Dark Attack -->
|
||||||
<skill id="4072" level="6" /> <!-- Stun -->
|
<skill id="4279" level="1" /> <!-- Fire Vulnerability -->
|
||||||
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
|
<skill id="4275" level="2" /> <!-- Holy Attack Vulnerability -->
|
||||||
<skill id="4408" level="8" /> <!-- HP Increase (1/4x) -->
|
</skill_list>
|
||||||
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
<shots shotChance="30" spiritChance="30" />
|
||||||
<skill id="4410" level="13" /> <!-- Slightly Strong P. Atk. -->
|
<ex_crt_effect>false</ex_crt_effect>
|
||||||
<skill id="4411" level="13" /> <!-- Slightly Strong M. Atk. -->
|
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
||||||
<skill id="4412" level="9" /> <!-- Slightly Weak P. Def. -->
|
<ai aggroRange="300" clanHelpRange="300" isAggressive="true">
|
||||||
<skill id="4413" level="9" /> <!-- Slightly Weak M. Def. -->
|
<clan_list>
|
||||||
<skill id="4414" level="2" /> <!-- Standard Type -->
|
<clan>UNDEAD</clan>
|
||||||
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
</clan_list>
|
||||||
<skill id="4416" level="1" /> <!-- Undead -->
|
</ai>
|
||||||
<skill id="4278" level="1" /> <!-- Dark Attack -->
|
<drop_lists>
|
||||||
<skill id="4279" level="1" /> <!-- Fire Vulnerability -->
|
<drop>
|
||||||
<skill id="4275" level="2" /> <!-- Holy Attack Vulnerability -->
|
<item id="57" min="11" max="26" chance="70" /> <!-- Adena -->
|
||||||
</skill_list>
|
<item id="729" min="1" max="1" chance="0.003" /> <!-- Scroll: Enchant Weapon (A-grade) -->
|
||||||
<shots shotChance="30" spiritChance="30" />
|
</drop>
|
||||||
<ex_crt_effect>false</ex_crt_effect>
|
<spoil>
|
||||||
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
<item id="729" min="1" max="1" chance="0.003" /> <!-- Scroll: Enchant Weapon (A-grade) -->
|
||||||
<ai aggroRange="300" clanHelpRange="300" isAggressive="true">
|
</spoil>
|
||||||
<clan_list>
|
<lucky_drop>
|
||||||
<clan>UNDEAD</clan>
|
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
||||||
</clan_list>
|
</lucky_drop>
|
||||||
</ai>
|
</drop_lists>
|
||||||
<drop_lists>
|
<collision>
|
||||||
<death>
|
<radius normal="10" grown="12" />
|
||||||
<group chance="70">
|
<height normal="28" grown="33" />
|
||||||
<item id="57" min="11" max="26" chance="100" /> <!-- Adena -->
|
</collision>
|
||||||
</group>
|
</npc>
|
||||||
<group chance="0.003">
|
<npc id="21442" level="69" type="L2Monster" name="Heathen Knight">
|
||||||
<item id="729" min="1" max="1" chance="100" /> <!-- Scroll: Enchant Weapon (A-grade) -->
|
<!-- Confirmed CT2.5 -->
|
||||||
</group>
|
<parameters>
|
||||||
</death>
|
<param name="MoveAroundSocial" value="215" />
|
||||||
<corpse>
|
<param name="MoveAroundSocial1" value="215" />
|
||||||
<item id="729" min="1" max="1" chance="0.003" /> <!-- Scroll: Enchant Weapon (A-grade) -->
|
<param name="MoveAroundSocial2" value="215" />
|
||||||
</corpse>
|
<param name="SoulShot" value="100" />
|
||||||
<lucky_corpse>
|
<param name="SoulShotRate" value="30" />
|
||||||
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
<param name="LongRangeGuardRate" value="5" />
|
||||||
</lucky_corpse>
|
<skill name="PhysicalSpecial" id="4232" level="6" />
|
||||||
</drop_lists>
|
</parameters>
|
||||||
<collision>
|
<race>UNDEAD</race>
|
||||||
<radius normal="10" grown="12" />
|
<sex>MALE</sex>
|
||||||
<height normal="28" grown="33" />
|
<equipment rhand="150" lhand="103" /> <!-- Elemental Sword / Tower Shield -->
|
||||||
</collision>
|
<acquire exp="3024" sp="1" />
|
||||||
</npc>
|
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
||||||
<npc id="21442" level="69" type="L2Monster" name="Heathen Knight">
|
<vitals hp="2395.45533" hpRegen="7.5" mp="1314.0" mpRegen="2.7" />
|
||||||
<!-- Confirmed CT2.5 -->
|
<attack physical="667.50361" magical="455.81844" random="10" critical="4" accuracy="5" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
|
||||||
<parameters>
|
<defence physical="291.15063" magical="213.05139" shield="146" shieldRate="20" />
|
||||||
<param name="MoveAroundSocial" value="215" />
|
<speed>
|
||||||
<param name="MoveAroundSocial1" value="215" />
|
<walk ground="40" />
|
||||||
<param name="MoveAroundSocial2" value="215" />
|
<run ground="165" />
|
||||||
<param name="SoulShot" value="100" />
|
</speed>
|
||||||
<param name="SoulShotRate" value="30" />
|
<hit_time>170</hit_time>
|
||||||
<param name="LongRangeGuardRate" value="5" />
|
<abnormalResist physical="10" magical="10" />
|
||||||
<skill name="PhysicalSpecial" id="4232" level="6" />
|
</stats>
|
||||||
</parameters>
|
<status undying="false" canBeSown="true" />
|
||||||
<race>UNDEAD</race>
|
<skill_list>
|
||||||
<sex>MALE</sex>
|
<skill id="4232" level="6" /> <!-- NPC AE Strike -->
|
||||||
<equipment rhand="150" lhand="103" /> <!-- Elemental Sword / Tower Shield -->
|
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
|
||||||
<acquire exp="3024" sp="1" />
|
<skill id="4408" level="8" /> <!-- HP Increase (1/4x) -->
|
||||||
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
||||||
<vitals hp="2395.45533" hpRegen="7.5" mp="1314.0" mpRegen="2.7" />
|
<skill id="4410" level="13" /> <!-- Slightly Strong P. Atk. -->
|
||||||
<attack physical="667.50361" magical="455.81844" random="10" critical="4" accuracy="5" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
|
<skill id="4411" level="13" /> <!-- Slightly Strong M. Atk. -->
|
||||||
<defence physical="291.15063" magical="213.05139" shield="146" shieldRate="20" />
|
<skill id="4412" level="9" /> <!-- Slightly Weak P. Def. -->
|
||||||
<speed>
|
<skill id="4413" level="9" /> <!-- Slightly Weak M. Def. -->
|
||||||
<walk ground="40" />
|
<skill id="4414" level="2" /> <!-- Standard Type -->
|
||||||
<run ground="165" />
|
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
||||||
</speed>
|
<skill id="4416" level="1" /> <!-- Undead -->
|
||||||
<hit_time>170</hit_time>
|
<skill id="4278" level="1" /> <!-- Dark Attack -->
|
||||||
<abnormalResist physical="10" magical="10" />
|
<skill id="4279" level="1" /> <!-- Fire Vulnerability -->
|
||||||
</stats>
|
<skill id="4275" level="2" /> <!-- Holy Attack Vulnerability -->
|
||||||
<status undying="false" canBeSown="true" />
|
</skill_list>
|
||||||
<skill_list>
|
<shots shotChance="30" spiritChance="30" />
|
||||||
<skill id="4232" level="6" /> <!-- NPC AE Strike -->
|
<ex_crt_effect>false</ex_crt_effect>
|
||||||
<skill id="4274" level="1" /> <!-- Blunt Weapon Weak Point -->
|
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
||||||
<skill id="4408" level="8" /> <!-- HP Increase (1/4x) -->
|
<ai aggroRange="300" clanHelpRange="300" isAggressive="true">
|
||||||
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
<clan_list>
|
||||||
<skill id="4410" level="13" /> <!-- Slightly Strong P. Atk. -->
|
<clan>UNDEAD</clan>
|
||||||
<skill id="4411" level="13" /> <!-- Slightly Strong M. Atk. -->
|
</clan_list>
|
||||||
<skill id="4412" level="9" /> <!-- Slightly Weak P. Def. -->
|
</ai>
|
||||||
<skill id="4413" level="9" /> <!-- Slightly Weak M. Def. -->
|
<drop_lists>
|
||||||
<skill id="4414" level="2" /> <!-- Standard Type -->
|
<drop>
|
||||||
<skill id="4415" level="3" /> <!-- One-handed Sword -->
|
<item id="57" min="12" max="27" chance="70" /> <!-- Adena -->
|
||||||
<skill id="4416" level="1" /> <!-- Undead -->
|
<item id="730" min="1" max="1" chance="0.03" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
||||||
<skill id="4278" level="1" /> <!-- Dark Attack -->
|
</drop>
|
||||||
<skill id="4279" level="1" /> <!-- Fire Vulnerability -->
|
<spoil>
|
||||||
<skill id="4275" level="2" /> <!-- Holy Attack Vulnerability -->
|
<item id="730" min="1" max="1" chance="0.03" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
||||||
</skill_list>
|
</spoil>
|
||||||
<shots shotChance="30" spiritChance="30" />
|
<lucky_drop>
|
||||||
<ex_crt_effect>false</ex_crt_effect>
|
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
||||||
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
</lucky_drop>
|
||||||
<ai aggroRange="300" clanHelpRange="300" isAggressive="true">
|
</drop_lists>
|
||||||
<clan_list>
|
<collision>
|
||||||
<clan>UNDEAD</clan>
|
<radius normal="10" />
|
||||||
</clan_list>
|
<height normal="25" />
|
||||||
</ai>
|
</collision>
|
||||||
<drop_lists>
|
</npc>
|
||||||
<death>
|
</list>
|
||||||
<group chance="70">
|
|
||||||
<item id="57" min="12" max="27" chance="100" /> <!-- Adena -->
|
|
||||||
</group>
|
|
||||||
<group chance="0.03">
|
|
||||||
<item id="730" min="1" max="1" chance="100" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
|
||||||
</group>
|
|
||||||
</death>
|
|
||||||
<corpse>
|
|
||||||
<item id="730" min="1" max="1" chance="0.03" /> <!-- Scroll: Enchant Armor (A-grade) -->
|
|
||||||
</corpse>
|
|
||||||
<lucky_corpse>
|
|
||||||
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
|
||||||
</lucky_corpse>
|
|
||||||
</drop_lists>
|
|
||||||
<collision>
|
|
||||||
<radius normal="10" />
|
|
||||||
<height normal="25" />
|
|
||||||
</collision>
|
|
||||||
</npc>
|
|
||||||
</list>
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,91 +1,85 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
|
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
|
||||||
<npc id="21797" level="55" type="L2Monster" name="Timiniel's Spirit">
|
<npc id="21797" level="55" type="L2Monster" name="Timiniel's Spirit">
|
||||||
<!-- Confirmed CT2.5 -->
|
<!-- Confirmed CT2.5 -->
|
||||||
<parameters>
|
<parameters>
|
||||||
<param name="MoveAroundSocial" value="0" />
|
<param name="MoveAroundSocial" value="0" />
|
||||||
<param name="MoveAroundSocial1" value="0" />
|
<param name="MoveAroundSocial1" value="0" />
|
||||||
<param name="MoveAroundSocial2" value="0" />
|
<param name="MoveAroundSocial2" value="0" />
|
||||||
<param name="SoulShot" value="100" />
|
<param name="SoulShot" value="100" />
|
||||||
<param name="SoulShotRate" value="10" />
|
<param name="SoulShotRate" value="10" />
|
||||||
<param name="SpiritShot" value="100" />
|
<param name="SpiritShot" value="100" />
|
||||||
<param name="SpiritShotRate" value="5" />
|
<param name="SpiritShotRate" value="5" />
|
||||||
<param name="LongRangeGuardRate" value="5" />
|
<param name="LongRangeGuardRate" value="5" />
|
||||||
<skill name="DDMagic" id="4562" level="5" /> <!-- NPC Solar Flare -->
|
<skill name="DDMagic" id="4562" level="5" /> <!-- NPC Solar Flare -->
|
||||||
</parameters>
|
</parameters>
|
||||||
<race>FAIRY</race>
|
<race>FAIRY</race>
|
||||||
<sex>FEMALE</sex>
|
<sex>FEMALE</sex>
|
||||||
<acquire exp="3562" sp="1" />
|
<acquire exp="3562" sp="1" />
|
||||||
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
<stats str="79" int="34" dex="42" wit="66" con="75" men="12">
|
||||||
<vitals hp="1673.05473" hpRegen="6.5" mp="889.8" mpRegen="2.4" />
|
<vitals hp="1673.05473" hpRegen="6.5" mp="889.8" mpRegen="2.4" />
|
||||||
<attack physical="388.11142" magical="265.02979" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
|
<attack physical="388.11142" magical="265.02979" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
|
||||||
<defence physical="223.6362" magical="148.899508363765" />
|
<defence physical="223.6362" magical="148.899508363765" />
|
||||||
<attribute>
|
<attribute>
|
||||||
<defence fire="20" water="20" wind="189" earth="-5" holy="20" dark="20" />
|
<defence fire="20" water="20" wind="189" earth="-5" holy="20" dark="20" />
|
||||||
</attribute>
|
</attribute>
|
||||||
<speed>
|
<speed>
|
||||||
<walk ground="80" />
|
<walk ground="80" />
|
||||||
<run ground="165" />
|
<run ground="165" />
|
||||||
</speed>
|
</speed>
|
||||||
<hit_time>720</hit_time>
|
<hit_time>720</hit_time>
|
||||||
</stats>
|
</stats>
|
||||||
<status undying="false" canBeSown="true" />
|
<status undying="false" canBeSown="true" />
|
||||||
<skill_list>
|
<skill_list>
|
||||||
<skill id="4408" level="9" /> <!-- HP Increase (1/2x) -->
|
<skill id="4408" level="9" /> <!-- HP Increase (1/2x) -->
|
||||||
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
<skill id="4409" level="1" /> <!-- MP Increase (1x) -->
|
||||||
<skill id="4410" level="9" /> <!-- Slightly Weak P. Atk. -->
|
<skill id="4410" level="9" /> <!-- Slightly Weak P. Atk. -->
|
||||||
<skill id="4411" level="9" /> <!-- Slightly Weak M. Atk. -->
|
<skill id="4411" level="9" /> <!-- Slightly Weak M. Atk. -->
|
||||||
<skill id="4412" level="13" /> <!-- Slightly Strong P. Def. -->
|
<skill id="4412" level="13" /> <!-- Slightly Strong P. Def. -->
|
||||||
<skill id="4413" level="13" /> <!-- Slightly Strong M. Def. -->
|
<skill id="4413" level="13" /> <!-- Slightly Strong M. Def. -->
|
||||||
<skill id="4414" level="3" /> <!-- Light Armor Type -->
|
<skill id="4414" level="3" /> <!-- Light Armor Type -->
|
||||||
<skill id="4415" level="5" /> <!-- Blunt Weapons -->
|
<skill id="4415" level="5" /> <!-- Blunt Weapons -->
|
||||||
<skill id="4416" level="13" /> <!-- Fairies -->
|
<skill id="4416" level="13" /> <!-- Fairies -->
|
||||||
<skill id="4562" level="5" /> <!-- NPC Solar Flare -->
|
<skill id="4562" level="5" /> <!-- NPC Solar Flare -->
|
||||||
<skill id="4011" level="5" /> <!-- Wind Resistance -->
|
<skill id="4011" level="5" /> <!-- Wind Resistance -->
|
||||||
<skill id="4282" level="1" /> <!-- Earth Attack Vulnerability -->
|
<skill id="4282" level="1" /> <!-- Earth Attack Vulnerability -->
|
||||||
</skill_list>
|
</skill_list>
|
||||||
<shots shotChance="30" spiritChance="30" />
|
<shots shotChance="30" spiritChance="30" />
|
||||||
<ex_crt_effect>false</ex_crt_effect>
|
<ex_crt_effect>false</ex_crt_effect>
|
||||||
<s_npc_prop_hp_rate>0.5</s_npc_prop_hp_rate>
|
<s_npc_prop_hp_rate>0.5</s_npc_prop_hp_rate>
|
||||||
<ai aggroRange="300" clanHelpRange="300" isAggressive="false">
|
<ai aggroRange="300" clanHelpRange="300" isAggressive="false">
|
||||||
<clan_list>
|
<clan_list>
|
||||||
<clan>TIMINIEL</clan>
|
<clan>TIMINIEL</clan>
|
||||||
</clan_list>
|
</clan_list>
|
||||||
</ai>
|
</ai>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<group chance="70">
|
<item id="57" min="315" max="643" chance="70" /> <!-- Adena -->
|
||||||
<item id="57" min="315" max="643" chance="100" /> <!-- Adena -->
|
<item id="2497" min="1" max="1" chance="0.00510302056932449" /> <!-- Full Plate Shield -->
|
||||||
</group>
|
<item id="2966" min="1" max="1" chance="0.403229309779644" /> <!-- Full Plate Shield Fragment -->
|
||||||
<group chance="0.6668000221252441">
|
<item id="2414" min="1" max="1" chance="0.00357204771852493" /> <!-- Full Plate Helmet -->
|
||||||
<item id="2497" min="1" max="1" chance="0.7653" /> <!-- Full Plate Shield -->
|
<item id="2959" min="1" max="1" chance="0.254895644057751" /> <!-- Full Plate Helmet Design -->
|
||||||
<item id="2966" min="1" max="1" chance="60.4723" /> <!-- Full Plate Shield Fragment -->
|
<item id="1869" min="1" max="1" chance="2.67955147268486" /> <!-- Iron Ore -->
|
||||||
<item id="2414" min="1" max="1" chance="0.5357" /> <!-- Full Plate Helmet -->
|
<item id="1870" min="1" max="1" chance="2.67955147268486" /> <!-- Coal -->
|
||||||
<item id="2959" min="1" max="1" chance="38.2267" /> <!-- Full Plate Helmet Design -->
|
<item id="1871" min="1" max="1" chance="2.67955147268486" /> <!-- Charcoal -->
|
||||||
</group>
|
<item id="1872" min="1" max="1" chance="3.57272508477974" /> <!-- Animal Bone -->
|
||||||
<group chance="15.31820011138916">
|
<item id="1867" min="1" max="1" chance="3.57272508477974" /> <!-- Animal Skin -->
|
||||||
<item id="1869" min="1" max="1" chance="17.4926" /> <!-- Iron Ore -->
|
<item id="4175" min="1" max="1" chance="0.0516223343753815" /> <!-- Recipe: Sealed Avadon Boots (100%) -->
|
||||||
<item id="1870" min="1" max="1" chance="17.4926" /> <!-- Coal -->
|
<item id="4972" min="1" max="1" chance="0.00309427642250061" /> <!-- Recipe: Great Axe (60%) -->
|
||||||
<item id="1871" min="1" max="1" chance="17.4926" /> <!-- Charcoal -->
|
<item id="8726" min="1" max="1" chance="0.0620233922510147" /> <!-- Life Stone - Level 55 -->
|
||||||
<item id="1872" min="1" max="1" chance="23.3234" /> <!-- Animal Bone -->
|
<item id="8736" min="1" max="1" chance="0.0155020185127258" /> <!-- Mid-Grade Life Stone - Level 55 -->
|
||||||
<item id="1867" min="1" max="1" chance="23.3234" /> <!-- Animal Skin -->
|
<item id="8746" min="1" max="1" chance="0.00154713821125031" /> <!-- High-Grade Life Stone - Level 55 -->
|
||||||
<item id="4175" min="1" max="1" chance="0.337" /> <!-- Recipe: Sealed Avadon Boots (100%) -->
|
<item id="8756" min="1" max="1" chance="0.000306364002227783" /> <!-- Top-Grade Life Stone - Level 55 -->
|
||||||
<item id="4972" min="1" max="1" chance="0.0202" /> <!-- Recipe: Great Axe (60%) -->
|
</drop>
|
||||||
<item id="8726" min="1" max="1" chance="0.4049" /> <!-- Life Stone - Level 55 -->
|
<spoil>
|
||||||
<item id="8736" min="1" max="1" chance="0.1012" /> <!-- Mid-Grade Life Stone - Level 55 -->
|
<item id="2961" min="1" max="1" chance="4.3468" /> <!-- Full Plate Boots Part -->
|
||||||
<item id="8746" min="1" max="1" chance="0.0101" /> <!-- High-Grade Life Stone - Level 55 -->
|
<item id="1867" min="1" max="3" chance="53.219" /> <!-- Animal Skin -->
|
||||||
<item id="8756" min="1" max="1" chance="0.002" /> <!-- Top-Grade Life Stone - Level 55 -->
|
<item id="1869" min="1" max="1" chance="79.8286" /> <!-- Iron Ore -->
|
||||||
</group>
|
</spoil>
|
||||||
</death>
|
</drop_lists>
|
||||||
<corpse>
|
<collision>
|
||||||
<item id="2961" min="1" max="1" chance="4.3468" /> <!-- Full Plate Boots Part -->
|
<radius normal="5" />
|
||||||
<item id="1867" min="1" max="3" chance="53.219" /> <!-- Animal Skin -->
|
<height normal="25" />
|
||||||
<item id="1869" min="1" max="1" chance="79.8286" /> <!-- Iron Ore -->
|
</collision>
|
||||||
</corpse>
|
</npc>
|
||||||
</drop_lists>
|
</list>
|
||||||
<collision>
|
|
||||||
<radius normal="5" />
|
|
||||||
<height normal="25" />
|
|
||||||
</collision>
|
|
||||||
</npc>
|
|
||||||
</list>
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -9,14 +9,6 @@
|
|||||||
<xs:complexType name="drop_list">
|
<xs:complexType name="drop_list">
|
||||||
<xs:choice minOccurs="1" maxOccurs="unbounded">
|
<xs:choice minOccurs="1" maxOccurs="unbounded">
|
||||||
<xs:element name="item" type="drop_list_item" />
|
<xs:element name="item" type="drop_list_item" />
|
||||||
<xs:element name="group">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:sequence>
|
|
||||||
<xs:element name="item" type="drop_list_item" minOccurs="1" maxOccurs="unbounded" />
|
|
||||||
</xs:sequence>
|
|
||||||
<xs:attribute name="chance" type="xs:decimal" />
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
</xs:choice>
|
</xs:choice>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
<xs:element name="list">
|
<xs:element name="list">
|
||||||
@ -267,9 +259,9 @@
|
|||||||
<xs:element name="drop_lists" minOccurs="0" maxOccurs="1">
|
<xs:element name="drop_lists" minOccurs="0" maxOccurs="1">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<xs:all>
|
||||||
<xs:element name="death" type="drop_list" minOccurs="0" maxOccurs="1" />
|
<xs:element name="drop" type="drop_list" minOccurs="0" maxOccurs="1" />
|
||||||
<xs:element name="corpse" type="drop_list" minOccurs="0" maxOccurs="1" />
|
<xs:element name="spoil" type="drop_list" minOccurs="0" maxOccurs="1" />
|
||||||
<xs:element name="lucky_corpse" type="drop_list" minOccurs="0" maxOccurs="1" />
|
<xs:element name="lucky_drop" type="drop_list" minOccurs="0" maxOccurs="1" />
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
@ -118,7 +118,6 @@ public final class Config
|
|||||||
public static final String CUSTOM_FIND_PVP_CONFIG_FILE = "./config/Custom/FindPvP.ini";
|
public static final String CUSTOM_FIND_PVP_CONFIG_FILE = "./config/Custom/FindPvP.ini";
|
||||||
public static final String CUSTOM_MULTILANGUAL_SUPPORT_CONFIG_FILE = "./config/Custom/MultilingualSupport.ini";
|
public static final String CUSTOM_MULTILANGUAL_SUPPORT_CONFIG_FILE = "./config/Custom/MultilingualSupport.ini";
|
||||||
public static final String CUSTOM_OFFLINE_TRADE_CONFIG_FILE = "./config/Custom/OfflineTrade.ini";
|
public static final String CUSTOM_OFFLINE_TRADE_CONFIG_FILE = "./config/Custom/OfflineTrade.ini";
|
||||||
public static final String CUSTOM_OLD_DROP_BEHAVIOR_CONFIG_FILE = "./config/Custom/OldDropBehavior.ini";
|
|
||||||
public static final String CUSTOM_PASSWORD_CHANGE_CONFIG_FILE = "./config/Custom/PasswordChange.ini";
|
public static final String CUSTOM_PASSWORD_CHANGE_CONFIG_FILE = "./config/Custom/PasswordChange.ini";
|
||||||
public static final String CUSTOM_PC_CAFE_CONFIG_FILE = "./config/Custom/PcCafe.ini";
|
public static final String CUSTOM_PC_CAFE_CONFIG_FILE = "./config/Custom/PcCafe.ini";
|
||||||
public static final String CUSTOM_PREMIUM_SYSTEM_CONFIG_FILE = "./config/Custom/PremiumSystem.ini";
|
public static final String CUSTOM_PREMIUM_SYSTEM_CONFIG_FILE = "./config/Custom/PremiumSystem.ini";
|
||||||
@ -451,7 +450,6 @@ public final class Config
|
|||||||
public static boolean CLEAR_DROPPED_ITEM_TABLE;
|
public static boolean CLEAR_DROPPED_ITEM_TABLE;
|
||||||
public static boolean ORDER_QUEST_LIST_BY_QUESTID;
|
public static boolean ORDER_QUEST_LIST_BY_QUESTID;
|
||||||
public static boolean AUTODELETE_INVALID_QUEST_DATA;
|
public static boolean AUTODELETE_INVALID_QUEST_DATA;
|
||||||
public static boolean PRECISE_DROP_CALCULATION;
|
|
||||||
public static boolean MULTIPLE_ITEM_DROP;
|
public static boolean MULTIPLE_ITEM_DROP;
|
||||||
public static boolean FORCE_INVENTORY_UPDATE;
|
public static boolean FORCE_INVENTORY_UPDATE;
|
||||||
public static boolean LAZY_CACHE;
|
public static boolean LAZY_CACHE;
|
||||||
@ -695,11 +693,11 @@ public final class Config
|
|||||||
public static float RATE_QUEST_REWARD_RECIPE;
|
public static float RATE_QUEST_REWARD_RECIPE;
|
||||||
public static float RATE_QUEST_REWARD_MATERIAL;
|
public static float RATE_QUEST_REWARD_MATERIAL;
|
||||||
public static float RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
|
public static float RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
|
||||||
public static float RATE_CORPSE_DROP_AMOUNT_MULTIPLIER;
|
public static float RATE_SPOIL_DROP_AMOUNT_MULTIPLIER;
|
||||||
public static float RATE_HERB_DROP_AMOUNT_MULTIPLIER;
|
public static float RATE_HERB_DROP_AMOUNT_MULTIPLIER;
|
||||||
public static float RATE_RAID_DROP_AMOUNT_MULTIPLIER;
|
public static float RATE_RAID_DROP_AMOUNT_MULTIPLIER;
|
||||||
public static float RATE_DEATH_DROP_CHANCE_MULTIPLIER;
|
public static float RATE_DEATH_DROP_CHANCE_MULTIPLIER;
|
||||||
public static float RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
|
public static float RATE_SPOIL_DROP_CHANCE_MULTIPLIER;
|
||||||
public static float RATE_HERB_DROP_CHANCE_MULTIPLIER;
|
public static float RATE_HERB_DROP_CHANCE_MULTIPLIER;
|
||||||
public static float RATE_RAID_DROP_CHANCE_MULTIPLIER;
|
public static float RATE_RAID_DROP_CHANCE_MULTIPLIER;
|
||||||
public static Map<Integer, Float> RATE_DROP_AMOUNT_BY_ID;
|
public static Map<Integer, Float> RATE_DROP_AMOUNT_BY_ID;
|
||||||
@ -1053,7 +1051,6 @@ public final class Config
|
|||||||
public static int DUALBOX_CHECK_MAX_L2EVENT_PARTICIPANTS_PER_IP;
|
public static int DUALBOX_CHECK_MAX_L2EVENT_PARTICIPANTS_PER_IP;
|
||||||
public static Map<Integer, Integer> DUALBOX_CHECK_WHITELIST;
|
public static Map<Integer, Integer> DUALBOX_CHECK_WHITELIST;
|
||||||
public static boolean ALLOW_CHANGE_PASSWORD;
|
public static boolean ALLOW_CHANGE_PASSWORD;
|
||||||
public static boolean OLD_DROP_BEHAVIOR;
|
|
||||||
public static boolean ALLOW_HUMAN;
|
public static boolean ALLOW_HUMAN;
|
||||||
public static boolean ALLOW_ELF;
|
public static boolean ALLOW_ELF;
|
||||||
public static boolean ALLOW_DARKELF;
|
public static boolean ALLOW_DARKELF;
|
||||||
@ -1954,14 +1951,6 @@ public final class Config
|
|||||||
PET_HP_REGEN_MULTIPLIER = NPC.getDouble("PetHpRegenMultiplier", 100) / 100;
|
PET_HP_REGEN_MULTIPLIER = NPC.getDouble("PetHpRegenMultiplier", 100) / 100;
|
||||||
PET_MP_REGEN_MULTIPLIER = NPC.getDouble("PetMpRegenMultiplier", 100) / 100;
|
PET_MP_REGEN_MULTIPLIER = NPC.getDouble("PetMpRegenMultiplier", 100) / 100;
|
||||||
|
|
||||||
DROP_ADENA_MIN_LEVEL_DIFFERENCE = NPC.getInt("DropAdenaMinLevelDifference", 8);
|
|
||||||
DROP_ADENA_MAX_LEVEL_DIFFERENCE = NPC.getInt("DropAdenaMaxLevelDifference", 15);
|
|
||||||
DROP_ADENA_MIN_LEVEL_GAP_CHANCE = NPC.getDouble("DropAdenaMinLevelGapChance", 10);
|
|
||||||
|
|
||||||
DROP_ITEM_MIN_LEVEL_DIFFERENCE = NPC.getInt("DropItemMinLevelDifference", 5);
|
|
||||||
DROP_ITEM_MAX_LEVEL_DIFFERENCE = NPC.getInt("DropItemMaxLevelDifference", 10);
|
|
||||||
DROP_ITEM_MIN_LEVEL_GAP_CHANCE = NPC.getDouble("DropItemMinLevelGapChance", 10);
|
|
||||||
|
|
||||||
VITALITY_CONSUME_BY_MOB = NPC.getInt("VitalityConsumeByMob", 2250);
|
VITALITY_CONSUME_BY_MOB = NPC.getInt("VitalityConsumeByMob", 2250);
|
||||||
VITALITY_CONSUME_BY_BOSS = NPC.getInt("VitalityConsumeByBoss", 1125);
|
VITALITY_CONSUME_BY_BOSS = NPC.getInt("VitalityConsumeByBoss", 1125);
|
||||||
|
|
||||||
@ -2034,11 +2023,11 @@ public final class Config
|
|||||||
KARMA_RATE_DROP_EQUIP_WEAPON = RatesSettings.getInt("KarmaRateDropEquipWeapon", 10);
|
KARMA_RATE_DROP_EQUIP_WEAPON = RatesSettings.getInt("KarmaRateDropEquipWeapon", 10);
|
||||||
|
|
||||||
RATE_DEATH_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("DeathDropAmountMultiplier", 1);
|
RATE_DEATH_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("DeathDropAmountMultiplier", 1);
|
||||||
RATE_CORPSE_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("CorpseDropAmountMultiplier", 1);
|
RATE_SPOIL_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("SpoilDropAmountMultiplier", 1);
|
||||||
RATE_HERB_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("HerbDropAmountMultiplier", 1);
|
RATE_HERB_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("HerbDropAmountMultiplier", 1);
|
||||||
RATE_RAID_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("RaidDropAmountMultiplier", 1);
|
RATE_RAID_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("RaidDropAmountMultiplier", 1);
|
||||||
RATE_DEATH_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("DeathDropChanceMultiplier", 1);
|
RATE_DEATH_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("DeathDropChanceMultiplier", 1);
|
||||||
RATE_CORPSE_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("CorpseDropChanceMultiplier", 1);
|
RATE_SPOIL_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("SpoilDropChanceMultiplier", 1);
|
||||||
RATE_HERB_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("HerbDropChanceMultiplier", 1);
|
RATE_HERB_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("HerbDropChanceMultiplier", 1);
|
||||||
RATE_RAID_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("RaidDropChanceMultiplier", 1);
|
RATE_RAID_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("RaidDropChanceMultiplier", 1);
|
||||||
|
|
||||||
@ -2098,6 +2087,13 @@ public final class Config
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DROP_ADENA_MIN_LEVEL_DIFFERENCE = RatesSettings.getInt("DropAdenaMinLevelDifference", 8);
|
||||||
|
DROP_ADENA_MAX_LEVEL_DIFFERENCE = RatesSettings.getInt("DropAdenaMaxLevelDifference", 15);
|
||||||
|
DROP_ADENA_MIN_LEVEL_GAP_CHANCE = RatesSettings.getDouble("DropAdenaMinLevelGapChance", 10);
|
||||||
|
DROP_ITEM_MIN_LEVEL_DIFFERENCE = RatesSettings.getInt("DropItemMinLevelDifference", 5);
|
||||||
|
DROP_ITEM_MAX_LEVEL_DIFFERENCE = RatesSettings.getInt("DropItemMaxLevelDifference", 10);
|
||||||
|
DROP_ITEM_MIN_LEVEL_GAP_CHANCE = RatesSettings.getDouble("DropItemMinLevelGapChance", 10);
|
||||||
|
|
||||||
// Load PvP config file (if exists)
|
// Load PvP config file (if exists)
|
||||||
final PropertiesParser PVPSettings = new PropertiesParser(PVP_CONFIG_FILE);
|
final PropertiesParser PVPSettings = new PropertiesParser(PVP_CONFIG_FILE);
|
||||||
|
|
||||||
@ -2497,11 +2493,6 @@ public final class Config
|
|||||||
OFFLINE_DISCONNECT_FINISHED = OfflineTrade.getBoolean("OfflineDisconnectFinished", true);
|
OFFLINE_DISCONNECT_FINISHED = OfflineTrade.getBoolean("OfflineDisconnectFinished", true);
|
||||||
STORE_OFFLINE_TRADE_IN_REALTIME = OfflineTrade.getBoolean("StoreOfflineTradeInRealtime", true);
|
STORE_OFFLINE_TRADE_IN_REALTIME = OfflineTrade.getBoolean("StoreOfflineTradeInRealtime", true);
|
||||||
|
|
||||||
// Load OldDropBehavior config file (if exists)
|
|
||||||
final PropertiesParser OldDropBehavior = new PropertiesParser(CUSTOM_OLD_DROP_BEHAVIOR_CONFIG_FILE);
|
|
||||||
|
|
||||||
OLD_DROP_BEHAVIOR = OldDropBehavior.getBoolean("OldDropBehavior", false);
|
|
||||||
|
|
||||||
// Load PasswordChange config file (if exists)
|
// Load PasswordChange config file (if exists)
|
||||||
final PropertiesParser PasswordChange = new PropertiesParser(CUSTOM_PASSWORD_CHANGE_CONFIG_FILE);
|
final PropertiesParser PasswordChange = new PropertiesParser(CUSTOM_PASSWORD_CHANGE_CONFIG_FILE);
|
||||||
|
|
||||||
|
@ -39,16 +39,14 @@ import com.l2jmobius.commons.util.CommonUtil;
|
|||||||
import com.l2jmobius.commons.util.IGameXmlReader;
|
import com.l2jmobius.commons.util.IGameXmlReader;
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||||
import com.l2jmobius.gameserver.enums.AISkillScope;
|
import com.l2jmobius.gameserver.enums.AISkillScope;
|
||||||
|
import com.l2jmobius.gameserver.enums.DropType;
|
||||||
import com.l2jmobius.gameserver.enums.MpRewardAffectType;
|
import com.l2jmobius.gameserver.enums.MpRewardAffectType;
|
||||||
import com.l2jmobius.gameserver.enums.MpRewardType;
|
import com.l2jmobius.gameserver.enums.MpRewardType;
|
||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||||
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.effects.L2EffectType;
|
import com.l2jmobius.gameserver.model.effects.L2EffectType;
|
||||||
|
import com.l2jmobius.gameserver.model.holders.DropHolder;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,7 +102,7 @@ public class NpcData implements IGameXmlReader
|
|||||||
Map<Integer, Skill> skills = null;
|
Map<Integer, Skill> skills = null;
|
||||||
Set<Integer> clans = null;
|
Set<Integer> clans = null;
|
||||||
Set<Integer> ignoreClanNpcIds = null;
|
Set<Integer> ignoreClanNpcIds = null;
|
||||||
Map<DropListScope, List<IDropItem>> dropLists = null;
|
List<DropHolder> dropLists = null;
|
||||||
set.set("id", npcId);
|
set.set("id", npcId);
|
||||||
set.set("displayId", parseInteger(attrs, "displayId"));
|
set.set("displayId", parseInteger(attrs, "displayId"));
|
||||||
set.set("level", parseByte(attrs, "level"));
|
set.set("level", parseByte(attrs, "level"));
|
||||||
@ -426,26 +424,39 @@ public class NpcData implements IGameXmlReader
|
|||||||
{
|
{
|
||||||
for (Node drop_lists_node = npc_node.getFirstChild(); drop_lists_node != null; drop_lists_node = drop_lists_node.getNextSibling())
|
for (Node drop_lists_node = npc_node.getFirstChild(); drop_lists_node != null; drop_lists_node = drop_lists_node.getNextSibling())
|
||||||
{
|
{
|
||||||
DropListScope dropListScope = null;
|
DropType dropType = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
dropListScope = Enum.valueOf(DropListScope.class, drop_lists_node.getNodeName().toUpperCase());
|
dropType = Enum.valueOf(DropType.class, drop_lists_node.getNodeName().toUpperCase());
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dropListScope != null)
|
if (dropType != null)
|
||||||
{
|
{
|
||||||
if (dropLists == null)
|
if (dropLists == null)
|
||||||
{
|
{
|
||||||
dropLists = new EnumMap<>(DropListScope.class);
|
dropLists = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<IDropItem> dropList = new ArrayList<>();
|
for (Node drop_node = drop_lists_node.getFirstChild(); drop_node != null; drop_node = drop_node.getNextSibling())
|
||||||
parseDropList(f, drop_lists_node, dropListScope, dropList);
|
{
|
||||||
dropLists.put(dropListScope, Collections.unmodifiableList(dropList));
|
final NamedNodeMap drop_attrs = drop_node.getAttributes();
|
||||||
|
if ("item".equals(drop_node.getNodeName().toLowerCase()))
|
||||||
|
{
|
||||||
|
final DropHolder dropItem = new DropHolder(dropType, parseInteger(drop_attrs, "id"), parseLong(drop_attrs, "min"), parseLong(drop_attrs, "max"), parseDouble(drop_attrs, "chance"));
|
||||||
|
if (ItemTable.getInstance().getTemplate(parseInteger(drop_attrs, "id")) == null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("DropListItem: Could not find item with id " + parseInteger(drop_attrs, "id") + ".");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dropLists.add(dropItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -611,7 +622,26 @@ public class NpcData implements IGameXmlReader
|
|||||||
template.setClans(clans);
|
template.setClans(clans);
|
||||||
template.setIgnoreClanNpcIds(ignoreClanNpcIds);
|
template.setIgnoreClanNpcIds(ignoreClanNpcIds);
|
||||||
|
|
||||||
template.setDropLists(dropLists);
|
if (dropLists != null)
|
||||||
|
{
|
||||||
|
for (DropHolder dropHolder : dropLists)
|
||||||
|
{
|
||||||
|
switch (dropHolder.getDropType())
|
||||||
|
{
|
||||||
|
case DROP:
|
||||||
|
case LUCKY_DROP: // TODO: Luck is added to death drops.
|
||||||
|
{
|
||||||
|
template.addDrop(dropHolder);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPOIL:
|
||||||
|
{
|
||||||
|
template.addSpoil(dropHolder);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!template.getParameters().getMinionList("Privates").isEmpty())
|
if (!template.getParameters().getMinionList("Privates").isEmpty())
|
||||||
{
|
{
|
||||||
@ -626,69 +656,6 @@ public class NpcData implements IGameXmlReader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseDropList(File f, Node drop_list_node, DropListScope dropListScope, List<IDropItem> drops)
|
|
||||||
{
|
|
||||||
for (Node drop_node = drop_list_node.getFirstChild(); drop_node != null; drop_node = drop_node.getNextSibling())
|
|
||||||
{
|
|
||||||
final NamedNodeMap attrs = drop_node.getAttributes();
|
|
||||||
switch (drop_node.getNodeName().toLowerCase())
|
|
||||||
{
|
|
||||||
case "group":
|
|
||||||
{
|
|
||||||
final GroupedGeneralDropItem dropItem = dropListScope.newGroupedDropItem(parseDouble(attrs, "chance"));
|
|
||||||
final List<IDropItem> groupedDropList = new ArrayList<>(2);
|
|
||||||
for (Node group_node = drop_node.getFirstChild(); group_node != null; group_node = group_node.getNextSibling())
|
|
||||||
{
|
|
||||||
parseDropListItem(group_node, dropListScope, groupedDropList);
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<GeneralDropItem> items = new ArrayList<>(groupedDropList.size());
|
|
||||||
for (IDropItem item : groupedDropList)
|
|
||||||
{
|
|
||||||
if (item instanceof GeneralDropItem)
|
|
||||||
{
|
|
||||||
items.add((GeneralDropItem) item);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOGGER.warning("[" + f + "] grouped general drop item supports only general drop item.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dropItem.setItems(items);
|
|
||||||
|
|
||||||
drops.add(dropItem);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
parseDropListItem(drop_node, dropListScope, drops);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void parseDropListItem(Node drop_list_item, DropListScope dropListScope, List<IDropItem> drops)
|
|
||||||
{
|
|
||||||
final NamedNodeMap attrs = drop_list_item.getAttributes();
|
|
||||||
switch (drop_list_item.getNodeName().toLowerCase())
|
|
||||||
{
|
|
||||||
case "item":
|
|
||||||
{
|
|
||||||
final IDropItem dropItem = dropListScope.newDropItem(parseInteger(attrs, "id"), parseLong(attrs, "min"), parseLong(attrs, "max"), parseDouble(attrs, "chance"));
|
|
||||||
if (ItemTable.getInstance().getTemplate(parseInteger(attrs, "id")) == null)
|
|
||||||
{
|
|
||||||
LOGGER.warning("DropListItem: Could not find item with id " + parseInteger(attrs, "id") + ".");
|
|
||||||
}
|
|
||||||
else if (dropItem != null)
|
|
||||||
{
|
|
||||||
drops.add(dropItem);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or creates a clan id if it doesnt exists.
|
* Gets or creates a clan id if it doesnt exists.
|
||||||
* @param clanName the clan name to get or create its id
|
* @param clanName the clan name to get or create its id
|
||||||
|
@ -1,36 +1,27 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the L2J Mobius project.
|
* This file is part of the L2J Mobius project.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.l2jmobius.gameserver.model.drops;
|
package com.l2jmobius.gameserver.enums;
|
||||||
|
|
||||||
import java.util.Collection;
|
/**
|
||||||
|
* @author Mobius
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
*/
|
||||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
public enum DropType
|
||||||
|
{
|
||||||
/**
|
DROP,
|
||||||
* @author NosBit
|
SPOIL,
|
||||||
*/
|
LUCKY_DROP;
|
||||||
public interface IDropItem
|
}
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Calculates drops of this drop item.
|
|
||||||
* @param victim the victim
|
|
||||||
* @param killer the killer
|
|
||||||
* @return {@code null} or empty collection if there are no drops, a collection containing all items to drop otherwise
|
|
||||||
*/
|
|
||||||
Collection<ItemHolder> calculateDrops(L2Character victim, L2Character killer);
|
|
||||||
}
|
|
@ -45,6 +45,7 @@ import com.l2jmobius.gameserver.datatables.EventDroplist;
|
|||||||
import com.l2jmobius.gameserver.datatables.EventDroplist.DateDrop;
|
import com.l2jmobius.gameserver.datatables.EventDroplist.DateDrop;
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||||
import com.l2jmobius.gameserver.enums.ChatType;
|
import com.l2jmobius.gameserver.enums.ChatType;
|
||||||
|
import com.l2jmobius.gameserver.enums.DropType;
|
||||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||||
import com.l2jmobius.gameserver.enums.Team;
|
import com.l2jmobius.gameserver.enums.Team;
|
||||||
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||||
@ -65,7 +66,6 @@ import com.l2jmobius.gameserver.model.actor.instance.L2ServitorInstance;
|
|||||||
import com.l2jmobius.gameserver.model.actor.status.AttackableStatus;
|
import com.l2jmobius.gameserver.model.actor.status.AttackableStatus;
|
||||||
import com.l2jmobius.gameserver.model.actor.tasks.attackable.CommandChannelTimer;
|
import com.l2jmobius.gameserver.model.actor.tasks.attackable.CommandChannelTimer;
|
||||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||||
import com.l2jmobius.gameserver.model.drops.DropListScope;
|
|
||||||
import com.l2jmobius.gameserver.model.entity.Hero;
|
import com.l2jmobius.gameserver.model.entity.Hero;
|
||||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnAttackableAggroRangeEnter;
|
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnAttackableAggroRangeEnter;
|
||||||
@ -978,10 +978,10 @@ public class L2Attackable extends L2Npc
|
|||||||
|
|
||||||
if (isSpoiled())
|
if (isSpoiled())
|
||||||
{
|
{
|
||||||
_sweepItems.set(npcTemplate.calculateDrops(DropListScope.CORPSE, this, player));
|
_sweepItems.set(npcTemplate.calculateDrops(DropType.SPOIL, this, player));
|
||||||
}
|
}
|
||||||
|
|
||||||
final Collection<ItemHolder> deathItems = npcTemplate.calculateDrops(DropListScope.DEATH, this, player);
|
final Collection<ItemHolder> deathItems = npcTemplate.calculateDrops(DropType.DROP, this, player);
|
||||||
if (deathItems != null)
|
if (deathItems != null)
|
||||||
{
|
{
|
||||||
for (ItemHolder drop : deathItems)
|
for (ItemHolder drop : deathItems)
|
||||||
|
@ -19,15 +19,17 @@ package com.l2jmobius.gameserver.model.actor.templates;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
import com.l2jmobius.Config;
|
||||||
|
import com.l2jmobius.commons.util.Rnd;
|
||||||
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
|
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
|
||||||
|
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||||
import com.l2jmobius.gameserver.enums.AISkillScope;
|
import com.l2jmobius.gameserver.enums.AISkillScope;
|
||||||
import com.l2jmobius.gameserver.enums.AIType;
|
import com.l2jmobius.gameserver.enums.AIType;
|
||||||
|
import com.l2jmobius.gameserver.enums.DropType;
|
||||||
import com.l2jmobius.gameserver.enums.MpRewardAffectType;
|
import com.l2jmobius.gameserver.enums.MpRewardAffectType;
|
||||||
import com.l2jmobius.gameserver.enums.MpRewardType;
|
import com.l2jmobius.gameserver.enums.MpRewardType;
|
||||||
import com.l2jmobius.gameserver.enums.Race;
|
import com.l2jmobius.gameserver.enums.Race;
|
||||||
@ -35,11 +37,13 @@ import com.l2jmobius.gameserver.enums.Sex;
|
|||||||
import com.l2jmobius.gameserver.model.StatsSet;
|
import com.l2jmobius.gameserver.model.StatsSet;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||||
import com.l2jmobius.gameserver.model.drops.DropListScope;
|
import com.l2jmobius.gameserver.model.holders.DropHolder;
|
||||||
import com.l2jmobius.gameserver.model.drops.IDropItem;
|
|
||||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||||
import com.l2jmobius.gameserver.model.interfaces.IIdentifiable;
|
import com.l2jmobius.gameserver.model.interfaces.IIdentifiable;
|
||||||
|
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
|
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||||
|
import com.l2jmobius.gameserver.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NPC template.
|
* NPC template.
|
||||||
@ -96,7 +100,8 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
|||||||
private Map<AISkillScope, List<Skill>> _aiSkillLists;
|
private Map<AISkillScope, List<Skill>> _aiSkillLists;
|
||||||
private Set<Integer> _clans;
|
private Set<Integer> _clans;
|
||||||
private Set<Integer> _ignoreClanNpcIds;
|
private Set<Integer> _ignoreClanNpcIds;
|
||||||
private Map<DropListScope, List<IDropItem>> _dropLists;
|
private List<DropHolder> _dropListDeath;
|
||||||
|
private List<DropHolder> _dropListSpoil;
|
||||||
private double _collisionRadiusGrown;
|
private double _collisionRadiusGrown;
|
||||||
private double _collisionHeightGrown;
|
private double _collisionHeightGrown;
|
||||||
private int _mpRewardValue;
|
private int _mpRewardValue;
|
||||||
@ -556,49 +561,222 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
|||||||
_ignoreClanNpcIds = ignoreClanNpcIds != null ? Collections.unmodifiableSet(ignoreClanNpcIds) : null;
|
_ignoreClanNpcIds = ignoreClanNpcIds != null ? Collections.unmodifiableSet(ignoreClanNpcIds) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<DropListScope, List<IDropItem>> getDropLists()
|
public void addDrop(DropHolder dropHolder)
|
||||||
{
|
{
|
||||||
return _dropLists;
|
if (_dropListDeath == null)
|
||||||
|
{
|
||||||
|
_dropListDeath = new ArrayList<>();
|
||||||
|
}
|
||||||
|
_dropListDeath.add(dropHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDropLists(Map<DropListScope, List<IDropItem>> dropLists)
|
public void addSpoil(DropHolder dropHolder)
|
||||||
{
|
{
|
||||||
_dropLists = dropLists != null ? Collections.unmodifiableMap(dropLists) : null;
|
if (_dropListSpoil == null)
|
||||||
|
{
|
||||||
|
_dropListSpoil = new ArrayList<>();
|
||||||
|
}
|
||||||
|
_dropListSpoil.add(dropHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IDropItem> getDropList(DropListScope dropListScope)
|
public List<DropHolder> getDropList(DropType dropType)
|
||||||
{
|
{
|
||||||
return _dropLists != null ? _dropLists.get(dropListScope) : null;
|
switch (dropType)
|
||||||
|
{
|
||||||
|
case DROP:
|
||||||
|
case LUCKY_DROP: // never happens
|
||||||
|
{
|
||||||
|
return _dropListDeath;
|
||||||
|
}
|
||||||
|
case SPOIL:
|
||||||
|
{
|
||||||
|
return _dropListSpoil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<ItemHolder> calculateDrops(DropListScope dropListScope, L2Character victim, L2Character killer)
|
public Collection<ItemHolder> calculateDrops(DropType dropType, L2Character victim, L2Character killer)
|
||||||
{
|
{
|
||||||
final List<IDropItem> dropList = getDropList(dropListScope);
|
final List<DropHolder> dropList = getDropList(dropType);
|
||||||
if (dropList == null)
|
if (dropList == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int levelDifference = victim.getLevel() - killer.getLevel();
|
||||||
Collection<ItemHolder> calculatedDrops = null;
|
Collection<ItemHolder> calculatedDrops = null;
|
||||||
for (IDropItem dropItem : dropList)
|
for (DropHolder dropItem : dropList)
|
||||||
{
|
{
|
||||||
final Collection<ItemHolder> drops = dropItem.calculateDrops(victim, killer);
|
// check level gap that may prevent drop this item
|
||||||
if ((drops == null) || drops.isEmpty())
|
final double levelGapChanceToDrop;
|
||||||
|
if (dropItem.getItemId() == Inventory.ADENA_ID)
|
||||||
|
{
|
||||||
|
levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ADENA_MAX_LEVEL_DIFFERENCE, -Config.DROP_ADENA_MIN_LEVEL_DIFFERENCE, Config.DROP_ADENA_MIN_LEVEL_GAP_CHANCE, 100.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ITEM_MAX_LEVEL_DIFFERENCE, -Config.DROP_ITEM_MIN_LEVEL_DIFFERENCE, Config.DROP_ITEM_MIN_LEVEL_GAP_CHANCE, 100.0);
|
||||||
|
}
|
||||||
|
if ((Rnd.nextDouble() * 100) > levelGapChanceToDrop)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (calculatedDrops == null)
|
// calculate chances
|
||||||
|
final ItemHolder drop = calculateDrop(dropItem, victim, killer);
|
||||||
|
if (drop == null)
|
||||||
{
|
{
|
||||||
calculatedDrops = new LinkedList<>();
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
calculatedDrops.addAll(drops);
|
// create list
|
||||||
|
if (calculatedDrops == null)
|
||||||
|
{
|
||||||
|
calculatedDrops = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally
|
||||||
|
calculatedDrops.add(drop);
|
||||||
}
|
}
|
||||||
|
|
||||||
return calculatedDrops;
|
return calculatedDrops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All item drop chance calculations are done by this method.
|
||||||
|
* @param dropItem
|
||||||
|
* @param victim
|
||||||
|
* @param killer
|
||||||
|
* @return ItemHolder
|
||||||
|
*/
|
||||||
|
private ItemHolder calculateDrop(DropHolder dropItem, L2Character victim, L2Character killer)
|
||||||
|
{
|
||||||
|
switch (dropItem.getDropType())
|
||||||
|
{
|
||||||
|
case DROP:
|
||||||
|
case LUCKY_DROP:
|
||||||
|
{
|
||||||
|
final L2Item item = ItemTable.getInstance().getTemplate(dropItem.getItemId());
|
||||||
|
|
||||||
|
// chance
|
||||||
|
double rateChance = 1;
|
||||||
|
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 (victim.isRaid())
|
||||||
|
{
|
||||||
|
rateChance *= Config.RATE_RAID_DROP_CHANCE_MULTIPLIER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rateChance *= Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// premium chance
|
||||||
|
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
|
||||||
|
{
|
||||||
|
if (Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId()) != null)
|
||||||
|
{
|
||||||
|
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId());
|
||||||
|
}
|
||||||
|
else if (item.hasExImmediateEffect())
|
||||||
|
{
|
||||||
|
// TODO: Premium herb chance? :)
|
||||||
|
}
|
||||||
|
else if (victim.isRaid())
|
||||||
|
{
|
||||||
|
// TODO: Premium raid chance? :)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate if item will drop
|
||||||
|
if ((Rnd.nextDouble() * 100) < (dropItem.getChance() * rateChance))
|
||||||
|
{
|
||||||
|
// amount is calculated after chance returned success
|
||||||
|
double rateAmount = 1;
|
||||||
|
if (Config.RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
|
||||||
|
{
|
||||||
|
rateAmount *= Config.RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId());
|
||||||
|
}
|
||||||
|
else if (item.hasExImmediateEffect())
|
||||||
|
{
|
||||||
|
rateAmount *= Config.RATE_HERB_DROP_AMOUNT_MULTIPLIER;
|
||||||
|
}
|
||||||
|
else if (victim.isRaid())
|
||||||
|
{
|
||||||
|
rateAmount *= Config.RATE_RAID_DROP_AMOUNT_MULTIPLIER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rateAmount *= Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// premium chance
|
||||||
|
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
|
||||||
|
{
|
||||||
|
if (Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
|
||||||
|
{
|
||||||
|
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId());
|
||||||
|
}
|
||||||
|
else if (item.hasExImmediateEffect())
|
||||||
|
{
|
||||||
|
// TODO: Premium herb amount? :)
|
||||||
|
}
|
||||||
|
else if (victim.isRaid())
|
||||||
|
{
|
||||||
|
// TODO: Premium raid amount? :)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally
|
||||||
|
return new ItemHolder(dropItem.getItemId(), (long) (Rnd.get(dropItem.getMin(), dropItem.getMax()) * rateAmount));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPOIL:
|
||||||
|
{
|
||||||
|
// chance
|
||||||
|
double rateChance = Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER;
|
||||||
|
// premium chance
|
||||||
|
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
|
||||||
|
{
|
||||||
|
rateChance *= Config.PREMIUM_RATE_SPOIL_CHANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate if item will be rewarded
|
||||||
|
if ((Rnd.nextDouble() * 100) < (dropItem.getChance() * rateChance))
|
||||||
|
{
|
||||||
|
// amount is calculated after chance returned success
|
||||||
|
double rateAmount = Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER;
|
||||||
|
// premium amount
|
||||||
|
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
|
||||||
|
{
|
||||||
|
rateAmount *= Config.PREMIUM_RATE_SPOIL_AMOUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally
|
||||||
|
return new ItemHolder(dropItem.getItemId(), (long) (Rnd.get(dropItem.getMin(), dropItem.getMax()) * rateAmount));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public double getCollisionRadiusGrown()
|
public double getCollisionRadiusGrown()
|
||||||
{
|
{
|
||||||
return _collisionRadiusGrown;
|
return _collisionRadiusGrown;
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.l2jmobius.gameserver.model.drops;
|
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author NosBit
|
|
||||||
*/
|
|
||||||
public class CorpseDropItem extends GeneralDropItem
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param itemId the item id
|
|
||||||
* @param min the min count
|
|
||||||
* @param max the max count
|
|
||||||
* @param chance the chance of this drop item
|
|
||||||
*/
|
|
||||||
public CorpseDropItem(int itemId, long min, long max, double chance)
|
|
||||||
{
|
|
||||||
super(itemId, min, max, chance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.l2jmobius.gameserver.model.drops.GeneralDropItem#getGlobalAmountMultiplier()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected double getGlobalAmountMultiplier(boolean isPremium)
|
|
||||||
{
|
|
||||||
return isPremium ? Config.PREMIUM_RATE_SPOIL_AMOUNT * Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER : Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.l2jmobius.gameserver.model.drops.GeneralDropItem#getGlobalChanceMultiplier()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected double getGlobalChanceMultiplier(boolean isPremium)
|
|
||||||
{
|
|
||||||
return isPremium ? Config.PREMIUM_RATE_SPOIL_CHANCE * Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER : Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.l2jmobius.gameserver.model.drops;
|
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author NosBit
|
|
||||||
*/
|
|
||||||
public class DeathDropItem extends GeneralDropItem
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param itemId the item id
|
|
||||||
* @param min the min count
|
|
||||||
* @param max the max count
|
|
||||||
* @param chance the chance of this drop item
|
|
||||||
*/
|
|
||||||
public DeathDropItem(int itemId, long min, long max, double chance)
|
|
||||||
{
|
|
||||||
super(itemId, min, max, chance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.l2jmobius.gameserver.model.drops.GeneralDropItem#getGlobalAmountMultiplier()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected double getGlobalAmountMultiplier(boolean isPremium)
|
|
||||||
{
|
|
||||||
return isPremium ? Config.PREMIUM_RATE_DROP_AMOUNT * Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER : Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.l2jmobius.gameserver.model.drops.GeneralDropItem#getGlobalChanceMultiplier()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected double getGlobalChanceMultiplier(boolean isPremium)
|
|
||||||
{
|
|
||||||
return isPremium ? Config.PREMIUM_RATE_DROP_CHANCE * Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER : Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.l2jmobius.gameserver.model.drops;
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author NosBit
|
|
||||||
*/
|
|
||||||
public enum DropListScope
|
|
||||||
{
|
|
||||||
DEATH(DeathDropItem.class, GroupedDeathDropItem.class),
|
|
||||||
CORPSE(CorpseDropItem.class, GroupedCorpseDropItem.class);
|
|
||||||
|
|
||||||
private static final Logger _log = Logger.getLogger(DropListScope.class.getName());
|
|
||||||
|
|
||||||
private final Class<? extends GeneralDropItem> _dropItemClass;
|
|
||||||
private final Class<? extends GroupedGeneralDropItem> _groupedDropItemClass;
|
|
||||||
|
|
||||||
private DropListScope(Class<? extends GeneralDropItem> dropItemClass, Class<? extends GroupedGeneralDropItem> groupedDropItemClass)
|
|
||||||
{
|
|
||||||
_dropItemClass = dropItemClass;
|
|
||||||
_groupedDropItemClass = groupedDropItemClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDropItem newDropItem(int itemId, long min, long max, double chance)
|
|
||||||
{
|
|
||||||
final Constructor<? extends GeneralDropItem> constructor;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
constructor = _dropItemClass.getConstructor(int.class, long.class, long.class, double.class);
|
|
||||||
}
|
|
||||||
catch (NoSuchMethodException | SecurityException e)
|
|
||||||
{
|
|
||||||
_log.log(Level.SEVERE, "Constructor(int, long, long, double) not found for " + _dropItemClass.getSimpleName(), e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return constructor.newInstance(itemId, min, max, chance);
|
|
||||||
}
|
|
||||||
catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
|
||||||
{
|
|
||||||
_log.log(Level.SEVERE, "", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupedGeneralDropItem newGroupedDropItem(double chance)
|
|
||||||
{
|
|
||||||
final Constructor<? extends GroupedGeneralDropItem> constructor;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
constructor = _groupedDropItemClass.getConstructor(double.class);
|
|
||||||
}
|
|
||||||
catch (NoSuchMethodException | SecurityException e)
|
|
||||||
{
|
|
||||||
_log.log(Level.SEVERE, "Constructor(double) not found for " + _groupedDropItemClass.getSimpleName(), e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return constructor.newInstance(chance);
|
|
||||||
}
|
|
||||||
catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
|
||||||
{
|
|
||||||
_log.log(Level.SEVERE, "", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,287 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.l2jmobius.gameserver.model.drops;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
|
||||||
import com.l2jmobius.commons.util.Rnd;
|
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
|
||||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
|
||||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
|
||||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author NosBit
|
|
||||||
*/
|
|
||||||
public class GeneralDropItem implements IDropItem
|
|
||||||
{
|
|
||||||
private final int _itemId;
|
|
||||||
private final long _min;
|
|
||||||
private final long _max;
|
|
||||||
private final double _chance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param itemId the item id
|
|
||||||
* @param min the min count
|
|
||||||
* @param max the max count
|
|
||||||
* @param chance the chance of this drop item
|
|
||||||
*/
|
|
||||||
public GeneralDropItem(int itemId, long min, long max, double chance)
|
|
||||||
{
|
|
||||||
_itemId = itemId;
|
|
||||||
_min = min;
|
|
||||||
_max = max;
|
|
||||||
_chance = chance;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getGlobalChanceMultiplier(boolean isPremium)
|
|
||||||
{
|
|
||||||
return 1.;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getGlobalAmountMultiplier(boolean isPremium)
|
|
||||||
{
|
|
||||||
return 1.;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final long getMinMax(L2Character victim, L2Character killer, long val)
|
|
||||||
{
|
|
||||||
double multiplier = 1;
|
|
||||||
|
|
||||||
// individual drop amount
|
|
||||||
Float individualDropAmountMultiplier = null;
|
|
||||||
if (killer.getActingPlayer().hasPremiumStatus())
|
|
||||||
{
|
|
||||||
final Float normalMultiplier = Config.RATE_DROP_AMOUNT_BY_ID.get(getItemId());
|
|
||||||
final Float premiumMultiplier = Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(getItemId());
|
|
||||||
if ((normalMultiplier != null) && (premiumMultiplier != null))
|
|
||||||
{
|
|
||||||
individualDropAmountMultiplier = normalMultiplier * premiumMultiplier;
|
|
||||||
}
|
|
||||||
else if (normalMultiplier != null)
|
|
||||||
{
|
|
||||||
individualDropAmountMultiplier = normalMultiplier;
|
|
||||||
}
|
|
||||||
else if (premiumMultiplier != null)
|
|
||||||
{
|
|
||||||
individualDropAmountMultiplier = premiumMultiplier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
individualDropAmountMultiplier = Config.RATE_DROP_AMOUNT_BY_ID.get(getItemId());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (individualDropAmountMultiplier != null)
|
|
||||||
{
|
|
||||||
// individual amount list multiplier
|
|
||||||
multiplier *= individualDropAmountMultiplier;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final L2Item item = ItemTable.getInstance().getTemplate(getItemId());
|
|
||||||
// global amount multiplier
|
|
||||||
if ((item != null) && item.hasExImmediateEffect())
|
|
||||||
{
|
|
||||||
// global herb amount multiplier
|
|
||||||
multiplier *= Config.RATE_HERB_DROP_AMOUNT_MULTIPLIER;
|
|
||||||
}
|
|
||||||
else if (victim.isRaid())
|
|
||||||
{
|
|
||||||
// global raid amount multiplier
|
|
||||||
multiplier *= Config.RATE_RAID_DROP_AMOUNT_MULTIPLIER;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// drop type specific amount multiplier
|
|
||||||
multiplier *= getGlobalAmountMultiplier(killer.getActingPlayer().hasPremiumStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// global champions amount multiplier
|
|
||||||
if (victim.isChampion())
|
|
||||||
{
|
|
||||||
multiplier *= getItemId() != Inventory.ADENA_ID ? Config.CHAMPION_REWARDS_AMOUNT : Config.CHAMPION_ADENAS_REWARDS_AMOUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (long) (val * multiplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the item id
|
|
||||||
* @return the item id
|
|
||||||
*/
|
|
||||||
public int getItemId()
|
|
||||||
{
|
|
||||||
return _itemId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the min drop count
|
|
||||||
* @return the min
|
|
||||||
*/
|
|
||||||
public long getMin()
|
|
||||||
{
|
|
||||||
return _min;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the min drop count
|
|
||||||
* @param victim the victim
|
|
||||||
* @param killer the killer
|
|
||||||
* @return the min modified by any rates.
|
|
||||||
*/
|
|
||||||
public long getMin(L2Character victim, L2Character killer)
|
|
||||||
{
|
|
||||||
return getMinMax(victim, killer, getMin());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the max drop count
|
|
||||||
* @return the max
|
|
||||||
*/
|
|
||||||
public long getMax()
|
|
||||||
{
|
|
||||||
return _max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the max drop count
|
|
||||||
* @param victim the victim
|
|
||||||
* @param killer the killer
|
|
||||||
* @return the max modified by any rates.
|
|
||||||
*/
|
|
||||||
public long getMax(L2Character victim, L2Character killer)
|
|
||||||
{
|
|
||||||
return getMinMax(victim, killer, getMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the chance of this drop item.
|
|
||||||
* @return the chance
|
|
||||||
*/
|
|
||||||
public double getChance()
|
|
||||||
{
|
|
||||||
return _chance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the chance of this drop item.
|
|
||||||
* @param victim the victim
|
|
||||||
* @param killer the killer
|
|
||||||
* @return the chance modified by any rates.
|
|
||||||
*/
|
|
||||||
public double getChance(L2Character victim, L2Character killer)
|
|
||||||
{
|
|
||||||
double multiplier = 1;
|
|
||||||
|
|
||||||
// individual drop chance
|
|
||||||
Float individualDropChanceMultiplier = null;
|
|
||||||
if (killer.getActingPlayer().hasPremiumStatus())
|
|
||||||
{
|
|
||||||
final Float normalMultiplier = Config.RATE_DROP_CHANCE_BY_ID.get(getItemId());
|
|
||||||
final Float premiumMultiplier = Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(getItemId());
|
|
||||||
if ((normalMultiplier != null) && (premiumMultiplier != null))
|
|
||||||
{
|
|
||||||
individualDropChanceMultiplier = normalMultiplier * premiumMultiplier;
|
|
||||||
}
|
|
||||||
else if (normalMultiplier != null)
|
|
||||||
{
|
|
||||||
individualDropChanceMultiplier = normalMultiplier;
|
|
||||||
}
|
|
||||||
else if (premiumMultiplier != null)
|
|
||||||
{
|
|
||||||
individualDropChanceMultiplier = premiumMultiplier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
individualDropChanceMultiplier = Config.RATE_DROP_CHANCE_BY_ID.get(getItemId());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (individualDropChanceMultiplier != null)
|
|
||||||
{
|
|
||||||
multiplier *= individualDropChanceMultiplier;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final L2Item item = ItemTable.getInstance().getTemplate(getItemId());
|
|
||||||
if ((item != null) && item.hasExImmediateEffect())
|
|
||||||
{
|
|
||||||
multiplier *= Config.RATE_HERB_DROP_CHANCE_MULTIPLIER;
|
|
||||||
}
|
|
||||||
else if (victim.isRaid())
|
|
||||||
{
|
|
||||||
// global raid chance multiplier
|
|
||||||
multiplier *= Config.RATE_RAID_DROP_CHANCE_MULTIPLIER;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
multiplier *= getGlobalChanceMultiplier(killer.getActingPlayer().hasPremiumStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (victim.isChampion())
|
|
||||||
{
|
|
||||||
multiplier *= getItemId() != Inventory.ADENA_ID ? Config.CHAMPION_REWARDS_CHANCE : Config.CHAMPION_ADENAS_REWARDS_CHANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (getChance() * multiplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.l2jmobius.gameserver.model.drop.IDropItem#calculateDrops(com.l2jmobius.gameserver.model.actor.L2Character, com.l2jmobius.gameserver.model.actor.L2Character)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Collection<ItemHolder> calculateDrops(L2Character victim, L2Character killer)
|
|
||||||
{
|
|
||||||
final int levelDifference = victim.getLevel() - killer.getLevel();
|
|
||||||
final double levelGapChanceToDrop;
|
|
||||||
if (getItemId() == Inventory.ADENA_ID)
|
|
||||||
{
|
|
||||||
levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ADENA_MAX_LEVEL_DIFFERENCE, -Config.DROP_ADENA_MIN_LEVEL_DIFFERENCE, Config.DROP_ADENA_MIN_LEVEL_GAP_CHANCE, 100.0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ITEM_MAX_LEVEL_DIFFERENCE, -Config.DROP_ITEM_MIN_LEVEL_DIFFERENCE, Config.DROP_ITEM_MIN_LEVEL_GAP_CHANCE, 100.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is a chance of level gap that it wont drop this item
|
|
||||||
if (levelGapChanceToDrop < (Rnd.nextDouble() * 100))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final double chance = getChance(victim, killer);
|
|
||||||
final boolean successes = chance > (Rnd.nextDouble() * 100);
|
|
||||||
if (successes)
|
|
||||||
{
|
|
||||||
final Collection<ItemHolder> items = new ArrayList<>(1);
|
|
||||||
final long baseDropCount = Rnd.get(getMin(victim, killer), getMax(victim, killer));
|
|
||||||
final long finaldropCount = (long) (Config.OLD_DROP_BEHAVIOR ? (baseDropCount * Math.max(1, chance / 100)) + (chance > 100 ? (chance % 100) > (Rnd.nextDouble() * 100) ? baseDropCount : 0 : 0) : baseDropCount);
|
|
||||||
items.add(new ItemHolder(getItemId(), finaldropCount));
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.l2jmobius.gameserver.model.drops;
|
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author NosBit
|
|
||||||
*/
|
|
||||||
public class GroupedCorpseDropItem extends GroupedGeneralDropItem
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param chance the chance of this drop item.
|
|
||||||
*/
|
|
||||||
public GroupedCorpseDropItem(double chance)
|
|
||||||
{
|
|
||||||
super(chance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem#getGlobalChanceMultiplier()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected double getGlobalChanceMultiplier()
|
|
||||||
{
|
|
||||||
return Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.l2jmobius.gameserver.model.drops;
|
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author NosBit
|
|
||||||
*/
|
|
||||||
public class GroupedDeathDropItem extends GroupedGeneralDropItem
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param chance the chance of this drop item.
|
|
||||||
*/
|
|
||||||
public GroupedDeathDropItem(double chance)
|
|
||||||
{
|
|
||||||
super(chance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem#getGlobalChanceMultiplier()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected double getGlobalChanceMultiplier()
|
|
||||||
{
|
|
||||||
return Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,179 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the L2J Mobius project.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.l2jmobius.gameserver.model.drops;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.l2jmobius.Config;
|
|
||||||
import com.l2jmobius.commons.util.Rnd;
|
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2RaidBossInstance;
|
|
||||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
|
||||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
|
||||||
import com.l2jmobius.gameserver.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author NosBit
|
|
||||||
*/
|
|
||||||
public class GroupedGeneralDropItem implements IDropItem
|
|
||||||
{
|
|
||||||
private final double _chance;
|
|
||||||
private List<GeneralDropItem> _items;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param chance the chance of this drop item.
|
|
||||||
*/
|
|
||||||
public GroupedGeneralDropItem(double chance)
|
|
||||||
{
|
|
||||||
_chance = chance;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getGlobalChanceMultiplier()
|
|
||||||
{
|
|
||||||
return 1.;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the chance of this drop item.
|
|
||||||
* @return the chance
|
|
||||||
*/
|
|
||||||
public double getChance()
|
|
||||||
{
|
|
||||||
return _chance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the chance of this drop item.
|
|
||||||
* @param victim the victim
|
|
||||||
* @param killer the killer
|
|
||||||
* @return the chance modified by any rates.
|
|
||||||
*/
|
|
||||||
public double getChance(L2Character victim, L2Character killer)
|
|
||||||
{
|
|
||||||
for (GeneralDropItem gdi : getItems())
|
|
||||||
{
|
|
||||||
final L2Item item = ItemTable.getInstance().getTemplate(gdi.getItemId());
|
|
||||||
if (item == null)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!item.hasExImmediateEffect())
|
|
||||||
{
|
|
||||||
// individual chance
|
|
||||||
Float individualDropChanceMultiplier = null;
|
|
||||||
if (killer.getActingPlayer().hasPremiumStatus())
|
|
||||||
{
|
|
||||||
final Float normalMultiplier = Config.RATE_DROP_CHANCE_BY_ID.get(item.getId());
|
|
||||||
final Float premiumMultiplier = Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(item.getId());
|
|
||||||
if ((normalMultiplier != null) && (premiumMultiplier != null))
|
|
||||||
{
|
|
||||||
individualDropChanceMultiplier = normalMultiplier * premiumMultiplier;
|
|
||||||
}
|
|
||||||
else if (normalMultiplier != null)
|
|
||||||
{
|
|
||||||
individualDropChanceMultiplier = normalMultiplier;
|
|
||||||
}
|
|
||||||
else if (premiumMultiplier != null)
|
|
||||||
{
|
|
||||||
individualDropChanceMultiplier = premiumMultiplier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
individualDropChanceMultiplier = Config.RATE_DROP_CHANCE_BY_ID.get(item.getId());
|
|
||||||
}
|
|
||||||
if (individualDropChanceMultiplier != null)
|
|
||||||
{
|
|
||||||
return getChance() * individualDropChanceMultiplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getChance() * getGlobalChanceMultiplier();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return getChance() * Config.RATE_HERB_DROP_CHANCE_MULTIPLIER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the items.
|
|
||||||
* @return the items
|
|
||||||
*/
|
|
||||||
public List<GeneralDropItem> getItems()
|
|
||||||
{
|
|
||||||
return _items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets an item list to this drop item.
|
|
||||||
* @param items the item list
|
|
||||||
*/
|
|
||||||
public void setItems(List<GeneralDropItem> items)
|
|
||||||
{
|
|
||||||
_items = Collections.unmodifiableList(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.l2jmobius.gameserver.model.drop.IDropItem#calculateDrops(com.l2jmobius.gameserver.model.actor.L2Character, com.l2jmobius.gameserver.model.actor.L2Character)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Collection<ItemHolder> calculateDrops(L2Character victim, L2Character killer)
|
|
||||||
{
|
|
||||||
final int levelDifference = victim.getLevel() - killer.getLevel();
|
|
||||||
double chanceModifier;
|
|
||||||
if (victim instanceof L2RaidBossInstance)
|
|
||||||
{
|
|
||||||
chanceModifier = Math.max(0, Math.min(1, (levelDifference * 0.15) + 1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
chanceModifier = 1;
|
|
||||||
if (Util.map(levelDifference, -Config.DROP_ITEM_MAX_LEVEL_DIFFERENCE, -Config.DROP_ITEM_MIN_LEVEL_DIFFERENCE, Config.DROP_ITEM_MIN_LEVEL_GAP_CHANCE, 100.0) < (Rnd.nextDouble() * 100))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final double chance = getChance(victim, killer) * chanceModifier;
|
|
||||||
final boolean successes = chance > (Rnd.nextDouble() * 100);
|
|
||||||
|
|
||||||
if (successes)
|
|
||||||
{
|
|
||||||
double totalChance = 0;
|
|
||||||
final double random = (Rnd.nextDouble() * 100);
|
|
||||||
for (GeneralDropItem item : getItems())
|
|
||||||
{
|
|
||||||
// Grouped item chance rates should not be modified.
|
|
||||||
totalChance += item.getChance(victim, killer);
|
|
||||||
if (totalChance > random)
|
|
||||||
{
|
|
||||||
final Collection<ItemHolder> items = new ArrayList<>(1);
|
|
||||||
final long baseDropCount = Rnd.get(item.getMin(victim, killer), item.getMax(victim, killer));
|
|
||||||
final long finaldropCount = (long) (Config.OLD_DROP_BEHAVIOR ? (baseDropCount * Math.max(1, chance / 100)) + ((chance > 100) && ((chance % 100) > (Rnd.nextDouble() * 100)) ? baseDropCount : 0) : baseDropCount);
|
|
||||||
items.add(new ItemHolder(item.getItemId(), finaldropCount));
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the L2J Mobius project.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.l2jmobius.gameserver.model.holders;
|
||||||
|
|
||||||
|
import com.l2jmobius.gameserver.enums.DropType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mobius
|
||||||
|
*/
|
||||||
|
public class DropHolder
|
||||||
|
{
|
||||||
|
private final DropType _dropType;
|
||||||
|
private final int _itemId;
|
||||||
|
private final long _min;
|
||||||
|
private final long _max;
|
||||||
|
private final double _chance;
|
||||||
|
|
||||||
|
public DropHolder(DropType dropType, int itemId, long min, long max, double chance)
|
||||||
|
{
|
||||||
|
_dropType = dropType;
|
||||||
|
_itemId = itemId;
|
||||||
|
_min = min;
|
||||||
|
_max = max;
|
||||||
|
_chance = chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DropType getDropType()
|
||||||
|
{
|
||||||
|
return _dropType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getItemId()
|
||||||
|
{
|
||||||
|
return _itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMin()
|
||||||
|
{
|
||||||
|
return _min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMax()
|
||||||
|
{
|
||||||
|
return _max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getChance()
|
||||||
|
{
|
||||||
|
return _chance;
|
||||||
|
}
|
||||||
|
}
|
@ -36,7 +36,7 @@ import com.l2jmobius.gameserver.datatables.ItemTable;
|
|||||||
import com.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
import com.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||||
import com.l2jmobius.gameserver.model.Location;
|
import com.l2jmobius.gameserver.model.Location;
|
||||||
import com.l2jmobius.gameserver.model.announce.EventAnnouncement;
|
import com.l2jmobius.gameserver.model.announce.EventAnnouncement;
|
||||||
import com.l2jmobius.gameserver.model.drops.GeneralDropItem;
|
import com.l2jmobius.gameserver.model.holders.DropHolder;
|
||||||
import com.l2jmobius.gameserver.script.DateRange;
|
import com.l2jmobius.gameserver.script.DateRange;
|
||||||
import com.l2jmobius.gameserver.util.Broadcast;
|
import com.l2jmobius.gameserver.util.Broadcast;
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ public class LongTimeEvent extends Quest
|
|||||||
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
protected final List<NpcSpawn> _spawnList = new ArrayList<>();
|
||||||
|
|
||||||
// Drop data for event
|
// Drop data for event
|
||||||
protected final List<GeneralDropItem> _dropList = new ArrayList<>();
|
protected final List<DropHolder> _dropList = new ArrayList<>();
|
||||||
|
|
||||||
protected class NpcSpawn
|
protected class NpcSpawn
|
||||||
{
|
{
|
||||||
@ -195,7 +195,7 @@ public class LongTimeEvent extends Quest
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_dropList.add(new GeneralDropItem(itemId, minCount, maxCount, finalChance));
|
_dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance));
|
||||||
}
|
}
|
||||||
catch (NumberFormatException nfe)
|
catch (NumberFormatException nfe)
|
||||||
{
|
{
|
||||||
@ -272,7 +272,7 @@ public class LongTimeEvent extends Quest
|
|||||||
// Add drop
|
// Add drop
|
||||||
if (_dropList != null)
|
if (_dropList != null)
|
||||||
{
|
{
|
||||||
for (GeneralDropItem drop : _dropList)
|
for (DropHolder drop : _dropList)
|
||||||
{
|
{
|
||||||
EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod);
|
EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod);
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@ Others:
|
|||||||
-Reworked tax system
|
-Reworked tax system
|
||||||
-Reworked quest system
|
-Reworked quest system
|
||||||
-Reworked spawn system
|
-Reworked spawn system
|
||||||
|
-Reworked drop system
|
||||||
-Skill system from L2jUnity
|
-Skill system from L2jUnity
|
||||||
-GeoEngine from aCis
|
-GeoEngine from aCis
|
||||||
-Threadpool manager from aCis
|
-Threadpool manager from aCis
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Old Drop Behavior
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Enables L2J old drop behavior
|
|
||||||
# The old L2J system used to add amount of items drop per 100% range of chance.
|
|
||||||
# For example, if chance is 230% when rate are applied, it will do :
|
|
||||||
# amount dropped = (2 * getRandomAmount(min,max)) + 30% chance to get ad additional getRandomAmount(min,max)
|
|
||||||
# Default : False
|
|
||||||
OldDropBehavior = False
|
|
@ -229,11 +229,6 @@ AutoDeleteInvalidQuestData = False
|
|||||||
# Retail: True
|
# Retail: True
|
||||||
StoryQuestRewardBuff = True
|
StoryQuestRewardBuff = True
|
||||||
|
|
||||||
# If True, allows a special handling for drops when chance raises over 100% (eg. when applying chance rates).
|
|
||||||
# True value causes better drop handling at higher rates.
|
|
||||||
# Default: True
|
|
||||||
PreciseDropCalculation = True
|
|
||||||
|
|
||||||
# Allow creating multiple non-stackable items at one time?
|
# Allow creating multiple non-stackable items at one time?
|
||||||
# Default: True
|
# Default: True
|
||||||
MultipleItemDrop = True
|
MultipleItemDrop = True
|
||||||
|
@ -174,36 +174,6 @@ GrandChaosTime = 10
|
|||||||
MinionChaosTime = 10
|
MinionChaosTime = 10
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Drops
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# The min and max level difference used for level gap calculation
|
|
||||||
# this is only for how many levels higher the player is than the monster
|
|
||||||
# Default: 8
|
|
||||||
DropAdenaMinLevelDifference = 8
|
|
||||||
# Default: 15
|
|
||||||
DropAdenaMaxLevelDifference = 15
|
|
||||||
|
|
||||||
# This is the minimum level gap chance meaning for 10 that the monster will have 10% chance
|
|
||||||
# to allow dropping the item if level difference is bigger than DropAdenaMaxLevelDifference
|
|
||||||
# Note: This value is scalling from 100 to the specified value for DropAdenaMinLevelDifference to DropAdenaMaxLevelDifference limits
|
|
||||||
# Default: 10
|
|
||||||
DropAdenaMinLevelGapChance = 10
|
|
||||||
|
|
||||||
# The min and max level difference used for level gap calculation
|
|
||||||
# this is only for how many levels higher the player is than the monster
|
|
||||||
# Default: 5
|
|
||||||
DropItemMinLevelDifference = 5
|
|
||||||
# Default: 10
|
|
||||||
DropItemMaxLevelDifference = 10
|
|
||||||
|
|
||||||
# This is the minimum level gap chance meaning for 10 that the monster will have 10% chance
|
|
||||||
# to allow dropping the item if level difference is bigger than DropAdenaMaxLevelDifference
|
|
||||||
# Note: This value is scalling from 100 to the specified value for DropAdenaMinLevelDifference to DropAdenaMaxLevelDifference limits
|
|
||||||
# Default: 10
|
|
||||||
DropItemMinLevelGapChance = 10
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Vitality
|
# Vitality
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
@ -5,39 +5,6 @@
|
|||||||
# Warning:
|
# Warning:
|
||||||
# Please take extreme caution when changing anything. Also please understand what you are changing before you do so on a live server.
|
# Please take extreme caution when changing anything. Also please understand what you are changing before you do so on a live server.
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Item Rates
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Warning: to achieve old l2j behavior before drops rework you need to enable OldDropBehavior in Custom.ini
|
|
||||||
# and increase only chance multipliers! Remember if you increase both chance and amount you will have higher rates than expected
|
|
||||||
# Example: if amount multiplier is 5 and chance multiplier is 5 you will end up with 5*5 = 25 drop rates so be careful!
|
|
||||||
|
|
||||||
# Multiplies the amount of items dropped from monster on ground when it dies.
|
|
||||||
DeathDropAmountMultiplier = 1
|
|
||||||
# Multiplies the amount of items looted from monster when a skill like Sweeper(Spoil) is used.
|
|
||||||
CorpseDropAmountMultiplier = 1
|
|
||||||
# Multiplies the amount of items dropped from monster on ground when it dies.
|
|
||||||
HerbDropAmountMultiplier = 1
|
|
||||||
RaidDropAmountMultiplier = 1
|
|
||||||
|
|
||||||
# Multiplies the chance of items that can be dropped from monster on ground when it dies.
|
|
||||||
DeathDropChanceMultiplier = 1
|
|
||||||
# Multiplies the chance of items that can be looted from monster when a skill like Sweeper(Spoil) is used.
|
|
||||||
CorpseDropChanceMultiplier = 1
|
|
||||||
# Multiplies the chance of items that can be dropped from monster on ground when it dies.
|
|
||||||
HerbDropChanceMultiplier = 1
|
|
||||||
RaidDropChanceMultiplier = 1
|
|
||||||
|
|
||||||
# List of items affected by custom drop rate by id, used now for Adena rate too.
|
|
||||||
# Usage: itemId1,multiplier1;itemId2,multiplier2;...
|
|
||||||
# Note: Make sure the lists do NOT CONTAIN trailing spaces or spaces between the numbers!
|
|
||||||
# Example for Raid boss 1x jewelry: 6656,1;6657,1;6658,1;6659,1;6660,1;6661,1;6662,1;8191,1;10170,1;10314,1;
|
|
||||||
# Default: 57,1
|
|
||||||
DropAmountMultiplierByItemId = 57,1
|
|
||||||
DropChanceMultiplierByItemId = 57,1
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Standard Settings (Retail value = 1)
|
# Standard Settings (Retail value = 1)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@ -109,6 +76,68 @@ RateQuestRewardRecipe = 1
|
|||||||
RateQuestRewardMaterial = 1
|
RateQuestRewardMaterial = 1
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Item Drop Rates
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Remember if you increase both chance and amount you will have higher rates than expected.
|
||||||
|
# Example: if amount multiplier is 5 and chance multiplier is 5 you will end up with 5*5 = 25 drop rates so be careful!
|
||||||
|
|
||||||
|
# Multiplies the amount of items rewarded from monsters when they die.
|
||||||
|
DeathDropAmountMultiplier = 1
|
||||||
|
# Multiplies the amount of items rewarded from monsters when a Spoil skill is used.
|
||||||
|
SpoilDropAmountMultiplier = 1
|
||||||
|
# Multiplies the amount of items rewarded from monsters when they die.
|
||||||
|
HerbDropAmountMultiplier = 1
|
||||||
|
RaidDropAmountMultiplier = 1
|
||||||
|
|
||||||
|
# Multiplies the chance of items that can be rewarded from monsters when they die.
|
||||||
|
DeathDropChanceMultiplier = 1
|
||||||
|
# Multiplies the chance of items that can be rewarded from monsters when a Spoil skill is used.
|
||||||
|
SpoilDropChanceMultiplier = 1
|
||||||
|
# Multiplies the chance of items that can be rewarded from monsters when they die.
|
||||||
|
HerbDropChanceMultiplier = 1
|
||||||
|
RaidDropChanceMultiplier = 1
|
||||||
|
|
||||||
|
# List of items affected by custom drop rate by id, used now for Adena rate too.
|
||||||
|
# Usage: itemId1,multiplier1;itemId2,multiplier2;...
|
||||||
|
# Note: Make sure the lists do NOT CONTAIN trailing spaces or spaces between the numbers!
|
||||||
|
# Example for Raid boss 1x jewelry: 6656,1;6657,1;6658,1;6659,1;6660,1;6661,1;6662,1;8191,1;10170,1;10314,1;
|
||||||
|
# Default: 57,1
|
||||||
|
DropAmountMultiplierByItemId = 57,1
|
||||||
|
DropChanceMultiplierByItemId = 57,1
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Item Drop Level Difference Settings
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# The min and max level difference used for level gap calculation
|
||||||
|
# this is only for how many levels higher the player is than the monster
|
||||||
|
# Default: 8
|
||||||
|
DropAdenaMinLevelDifference = 8
|
||||||
|
# Default: 15
|
||||||
|
DropAdenaMaxLevelDifference = 15
|
||||||
|
|
||||||
|
# This is the minimum level gap chance meaning for 10 that the monster will have 10% chance
|
||||||
|
# to allow dropping the item if level difference is bigger than DropAdenaMaxLevelDifference
|
||||||
|
# Note: This value is scalling from 100 to the specified value for DropAdenaMinLevelDifference to DropAdenaMaxLevelDifference limits
|
||||||
|
# Default: 10
|
||||||
|
DropAdenaMinLevelGapChance = 10
|
||||||
|
|
||||||
|
# The min and max level difference used for level gap calculation
|
||||||
|
# this is only for how many levels higher the player is than the monster
|
||||||
|
# Default: 5
|
||||||
|
DropItemMinLevelDifference = 5
|
||||||
|
# Default: 10
|
||||||
|
DropItemMaxLevelDifference = 10
|
||||||
|
|
||||||
|
# This is the minimum level gap chance meaning for 10 that the monster will have 10% chance
|
||||||
|
# to allow dropping the item if level difference is bigger than DropAdenaMaxLevelDifference
|
||||||
|
# Note: This value is scalling from 100 to the specified value for DropAdenaMinLevelDifference to DropAdenaMaxLevelDifference limits
|
||||||
|
# Default: 10
|
||||||
|
DropItemMinLevelGapChance = 10
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Vitality system rates. Works only if EnableVitality = True
|
# Vitality system rates. Works only if EnableVitality = True
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
@ -265,7 +265,7 @@ public class AdminAdmin implements IAdminCommandHandler
|
|||||||
}
|
}
|
||||||
case "RateDropSpoil":
|
case "RateDropSpoil":
|
||||||
{
|
{
|
||||||
Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER = Float.valueOf(pValue);
|
Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER = Float.valueOf(pValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "EnchantChanceElementStone":
|
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=\"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 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 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 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=\"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>");
|
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>");
|
||||||
|
@ -18,14 +18,15 @@ package handlers.bypasshandlers;
|
|||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.util.CommonUtil;
|
import com.l2jmobius.commons.util.CommonUtil;
|
||||||
import com.l2jmobius.gameserver.cache.HtmCache;
|
import com.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||||
import com.l2jmobius.gameserver.enums.AttributeType;
|
import com.l2jmobius.gameserver.enums.AttributeType;
|
||||||
|
import com.l2jmobius.gameserver.enums.DropType;
|
||||||
import com.l2jmobius.gameserver.handler.IBypassHandler;
|
import com.l2jmobius.gameserver.handler.IBypassHandler;
|
||||||
import com.l2jmobius.gameserver.model.L2Object;
|
import com.l2jmobius.gameserver.model.L2Object;
|
||||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
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.L2Character;
|
||||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.drops.DropListScope;
|
import com.l2jmobius.gameserver.model.holders.DropHolder;
|
||||||
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.items.L2Item;
|
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||||
import com.l2jmobius.gameserver.util.HtmlUtil;
|
import com.l2jmobius.gameserver.util.HtmlUtil;
|
||||||
@ -106,10 +104,10 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String dropListScopeString = st.nextToken();
|
final String dropListTypeString = st.nextToken();
|
||||||
try
|
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 L2Object target = L2World.getInstance().findObject(Integer.parseInt(st.nextToken()));
|
||||||
final L2Npc npc = target instanceof L2Npc ? (L2Npc) target : null;
|
final L2Npc npc = target instanceof L2Npc ? (L2Npc) target : null;
|
||||||
if (npc == null)
|
if (npc == null)
|
||||||
@ -117,7 +115,7 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final int page = st.hasMoreElements() ? Integer.parseInt(st.nextToken()) : 0;
|
final int page = st.hasMoreElements() ? Integer.parseInt(st.nextToken()) : 0;
|
||||||
sendNpcDropList(activeChar, npc, dropListScope, page);
|
sendNpcDropList(activeChar, npc, dropListType, page);
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e)
|
catch (NumberFormatException e)
|
||||||
{
|
{
|
||||||
@ -125,7 +123,7 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (IllegalArgumentException e)
|
||||||
{
|
{
|
||||||
_log.warning("Bypass[NpcViewMod] unknown drop list scope: " + dropListScopeString);
|
_log.warning("Bypass[NpcViewMod] unknown drop list scope: " + dropListTypeString);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -336,21 +334,22 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
activeChar.sendPacket(html);
|
activeChar.sendPacket(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDropListButtons(L2Npc npc)
|
private static String getDropListButtons(L2Npc npc)
|
||||||
{
|
{
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
final Map<DropListScope, List<IDropItem>> dropLists = npc.getTemplate().getDropLists();
|
final List<DropHolder> dropListDeath = npc.getTemplate().getDropList(DropType.DROP);
|
||||||
if ((dropLists != null) && !dropLists.isEmpty() && (dropLists.containsKey(DropListScope.DEATH) || dropLists.containsKey(DropListScope.CORPSE)))
|
final List<DropHolder> dropListSpoil = npc.getTemplate().getDropList(DropType.SPOIL);
|
||||||
|
if ((dropListDeath != null) || (dropListSpoil != null))
|
||||||
{
|
{
|
||||||
sb.append("<table width=275 cellpadding=0 cellspacing=0><tr>");
|
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>");
|
sb.append("</tr></table>");
|
||||||
@ -358,10 +357,10 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
return sb.toString();
|
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);
|
final List<DropHolder> dropList = npc.getTemplate().getDropList(dropType);
|
||||||
if ((dropList == null) || dropList.isEmpty())
|
if (dropList == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -378,7 +377,7 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
pagesSb.append("<table><tr>");
|
pagesSb.append("<table><tr>");
|
||||||
for (int i = 0; i < pages; i++)
|
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>");
|
pagesSb.append("</tr></table>");
|
||||||
}
|
}
|
||||||
@ -409,124 +408,126 @@ public class NpcViewMod implements IBypassHandler
|
|||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
int height = 64;
|
int height = 64;
|
||||||
final IDropItem dropItem = dropList.get(i);
|
final DropHolder dropItem = dropList.get(i);
|
||||||
if (dropItem instanceof GeneralDropItem)
|
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;
|
rateChance = Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER;
|
||||||
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
|
rateAmount = Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER;
|
||||||
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);
|
// also check premium rates if available
|
||||||
final long max = generalDropItem.getMax(npc, activeChar);
|
if (Config.PREMIUM_SYSTEM_ENABLED && activeChar.hasPremiumStatus())
|
||||||
if (min == max)
|
|
||||||
{
|
{
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
sb.append(amountFormat.format(min));
|
rateChance *= Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
|
||||||
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>");
|
if (Config.RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
|
||||||
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> </td></tr></table>");
|
|
||||||
}
|
|
||||||
else if (dropItem instanceof GroupedGeneralDropItem)
|
|
||||||
{
|
|
||||||
final GroupedGeneralDropItem generalGroupedDropItem = (GroupedGeneralDropItem) dropItem;
|
|
||||||
if (generalGroupedDropItem.getItems().size() == 1)
|
|
||||||
{
|
{
|
||||||
final GeneralDropItem generalDropItem = generalGroupedDropItem.getItems().get(0);
|
rateAmount *= Config.RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId());
|
||||||
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
|
}
|
||||||
sb.append("<table width=332 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
|
else if (item.hasExImmediateEffect())
|
||||||
sb.append("<tr><td width=32 valign=top>");
|
{
|
||||||
sb.append("<img src=\"" + item.getIcon() + "\" width=32 height=32>");
|
rateAmount *= Config.RATE_HERB_DROP_AMOUNT_MULTIPLIER;
|
||||||
sb.append("</td><td fixwidth=300 align=center><font name=\"hs9\" color=\"CD9000\">");
|
}
|
||||||
sb.append(item.getName());
|
else if (npc.isRaid())
|
||||||
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>");
|
rateAmount *= Config.RATE_RAID_DROP_AMOUNT_MULTIPLIER;
|
||||||
sb.append("<td width=247 align=center>");
|
}
|
||||||
|
else
|
||||||
final long min = generalDropItem.getMin(npc, activeChar);
|
{
|
||||||
final long max = generalDropItem.getMax(npc, activeChar);
|
rateAmount *= Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
|
||||||
if (min == max)
|
}
|
||||||
|
|
||||||
|
// 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
|
else
|
||||||
{
|
{
|
||||||
sb.append(amountFormat.format(min));
|
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE;
|
||||||
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>");
|
if (Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
|
||||||
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> </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())
|
|
||||||
{
|
{
|
||||||
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
|
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.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>");
|
else if (item.hasExImmediateEffect())
|
||||||
String icon = item.getIcon();
|
{
|
||||||
if (icon == null)
|
// TODO: Premium herb amount? :)
|
||||||
{
|
}
|
||||||
icon = "icon.etc_question_mark_i00";
|
else if (npc.isRaid())
|
||||||
}
|
{
|
||||||
sb.append("<img src=\"" + icon + "\" width=32 height=32>");
|
// TODO: Premium raid amount? :)
|
||||||
sb.append("</td><td fixwidth=259 align=center><font name=\"hs9\" color=\"CD9000\">");
|
}
|
||||||
sb.append(item.getName());
|
else
|
||||||
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>");
|
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT;
|
||||||
|
|
||||||
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> </td></tr></table>");
|
|
||||||
|
|
||||||
height += 64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append("</td></tr><tr><td width=32></td><td width=300> </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> </td></tr></table>");
|
||||||
|
|
||||||
if ((sb.length() + rightSb.length() + leftSb.length()) < 16000) // limit of 32766?
|
if ((sb.length() + rightSb.length() + leftSb.length()) < 16000) // limit of 32766?
|
||||||
{
|
{
|
||||||
if (leftHeight >= (rightHeight + height))
|
if (leftHeight >= (rightHeight + height))
|
||||||
|
@ -22,23 +22,21 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
import com.l2jmobius.Config;
|
||||||
import com.l2jmobius.commons.util.Rnd;
|
import com.l2jmobius.commons.util.Rnd;
|
||||||
import com.l2jmobius.gameserver.cache.HtmCache;
|
import com.l2jmobius.gameserver.cache.HtmCache;
|
||||||
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
|
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
|
||||||
import com.l2jmobius.gameserver.data.xml.impl.SpawnsData;
|
import com.l2jmobius.gameserver.data.xml.impl.SpawnsData;
|
||||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||||
|
import com.l2jmobius.gameserver.enums.DropType;
|
||||||
import com.l2jmobius.gameserver.handler.CommunityBoardHandler;
|
import com.l2jmobius.gameserver.handler.CommunityBoardHandler;
|
||||||
import com.l2jmobius.gameserver.handler.IParseBoardHandler;
|
import com.l2jmobius.gameserver.handler.IParseBoardHandler;
|
||||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||||
import com.l2jmobius.gameserver.model.drops.DropListScope;
|
import com.l2jmobius.gameserver.model.holders.DropHolder;
|
||||||
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.itemcontainer.Inventory;
|
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||||
import com.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
|
import com.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
|
||||||
@ -56,40 +54,40 @@ public class DropSearchBoard implements IParseBoardHandler
|
|||||||
"_bbs_npc_trace"
|
"_bbs_npc_trace"
|
||||||
};
|
};
|
||||||
|
|
||||||
class DropHolder
|
class CBDropHolder
|
||||||
{
|
{
|
||||||
int itemId;
|
int itemId;
|
||||||
int npcId;
|
int npcId;
|
||||||
byte npcLevel;
|
byte npcLevel;
|
||||||
long basemin;
|
long min;
|
||||||
long basemax;
|
long max;
|
||||||
double baseGroupChance;
|
double chance;
|
||||||
double basechance;
|
boolean isSpoil;
|
||||||
boolean isSweep;
|
boolean isRaid;
|
||||||
|
|
||||||
public DropHolder(L2NpcTemplate npc, GeneralDropItem item, double groupChance, boolean isSweep)
|
public CBDropHolder(L2NpcTemplate npcTemplate, DropHolder dropHolder)
|
||||||
{
|
{
|
||||||
itemId = item.getItemId();
|
isSpoil = dropHolder.getDropType() == DropType.SPOIL;
|
||||||
npcId = npc.getId();
|
itemId = dropHolder.getItemId();
|
||||||
npcLevel = npc.getLevel();
|
npcId = npcTemplate.getId();
|
||||||
basemin = item.getMin();
|
npcLevel = npcTemplate.getLevel();
|
||||||
basemax = item.getMax();
|
min = dropHolder.getMin();
|
||||||
baseGroupChance = groupChance;
|
max = dropHolder.getMax();
|
||||||
basechance = item.getChance();
|
chance = dropHolder.getChance();
|
||||||
this.isSweep = isSweep;
|
isRaid = npcTemplate.getType().equals("L2RaidBoss") || npcTemplate.getType().equals("L2GrandBoss");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* only for debug'/;
|
* only for debug
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
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
|
// nonsupport items
|
||||||
private final Set<Integer> BLOCK_ID = new HashSet<>();
|
private final Set<Integer> BLOCK_ID = new HashSet<>();
|
||||||
@ -104,44 +102,39 @@ public class DropSearchBoard implements IParseBoardHandler
|
|||||||
|
|
||||||
private void buildDropIndex()
|
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 ->
|
addToDropList(npcTemplate, dropHolder);
|
||||||
{
|
}
|
||||||
if (idrop instanceof GroupedGeneralDropItem)
|
});
|
||||||
{
|
NpcData.getInstance().getTemplates(npc -> npc.getDropList(DropType.SPOIL) != null).forEach(npcTemplate ->
|
||||||
GroupedGeneralDropItem ggd = (GroupedGeneralDropItem) idrop;
|
{
|
||||||
ggd.getItems().stream().forEach(gd -> addToDropList(npcTemplate, gd, ggd.getChance(), entry.getKey() == DropListScope.CORPSE));
|
for (DropHolder dropHolder : npcTemplate.getDropList(DropType.SPOIL))
|
||||||
}
|
{
|
||||||
else
|
addToDropList(npcTemplate, dropHolder);
|
||||||
{
|
|
||||||
GeneralDropItem gd = (GeneralDropItem) idrop;
|
|
||||||
addToDropList(npcTemplate, gd, 100.0, entry.getKey() == DropListScope.CORPSE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
DROP_INDEX_CACHE.values().stream().forEach(l -> l.sort((d1, d2) -> Byte.valueOf(d1.npcLevel).compareTo(Byte.valueOf(d2.npcLevel))));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DropHolder> dropList = DROP_INDEX_CACHE.get(gd.getItemId());
|
List<CBDropHolder> dropList = DROP_INDEX_CACHE.get(dropHolder.getItemId());
|
||||||
if (dropList == null)
|
if (dropList == null)
|
||||||
{
|
{
|
||||||
dropList = new ArrayList<>();
|
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
|
@Override
|
||||||
@ -164,7 +157,7 @@ public class DropSearchBoard implements IParseBoardHandler
|
|||||||
final DecimalFormat chanceFormat = new DecimalFormat("0.00##");
|
final DecimalFormat chanceFormat = new DecimalFormat("0.00##");
|
||||||
int itemId = Integer.parseInt(params[1]);
|
int itemId = Integer.parseInt(params[1]);
|
||||||
int page = Integer.parseInt(params[2]);
|
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;
|
int pages = list.size() / 14;
|
||||||
if (pages == 0)
|
if (pages == 0)
|
||||||
{
|
{
|
||||||
@ -176,13 +169,106 @@ public class DropSearchBoard implements IParseBoardHandler
|
|||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for (int index = start; index <= end; index++)
|
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("<tr>");
|
||||||
builder.append("<td width=30>").append(dropHolder.npcLevel).append("</td>");
|
builder.append("<td width=30>").append(cbDropHolder.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=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(dropHolder.basemin).append("-").append(dropHolder.basemax).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((dropHolder.basechance * dropHolder.baseGroupChance) / 100)).append("%").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(dropHolder.isSweep ? "Sweep" : "Drop").append("</td>");
|
builder.append("<td width=50 align=CENTER>").append(cbDropHolder.isSpoil ? "Spoil" : "Drop").append("</td>");
|
||||||
builder.append("</tr>");
|
builder.append("</tr>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +290,7 @@ public class DropSearchBoard implements IParseBoardHandler
|
|||||||
List<NpcSpawnTemplate> spawnList = SpawnsData.getInstance().getNpcSpawns(npc -> npc.getId() == npcId);
|
List<NpcSpawnTemplate> spawnList = SpawnsData.getInstance().getNpcSpawns(npc -> npc.getId() == npcId);
|
||||||
if (spawnList.isEmpty())
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -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>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 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>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 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_CORPSE_DROP_AMOUNT_MULTIPLIER + "<br><br></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><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 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>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 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>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 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_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + "<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\">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\">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>");
|
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>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 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>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 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_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + " <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>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>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>");
|
html.append("<tr><td><center>Premium Info & Rules<br></center></td></tr>");
|
||||||
|
@ -48,38 +48,26 @@
|
|||||||
</clan_list>
|
</clan_list>
|
||||||
</ai>
|
</ai>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<group chance="42">
|
<item id="8600" min="1" max="1" chance="8.4" /> <!-- Herb of Life -->
|
||||||
<item id="8600" min="1" max="1" chance="20" /> <!-- Herb of Life -->
|
<item id="8601" min="1" max="1" chance="18.9" /> <!-- Major Herb of Life -->
|
||||||
<item id="8601" min="1" max="1" chance="45" /> <!-- Major Herb of Life -->
|
<item id="8602" min="1" max="1" chance="14.7" /> <!-- Superior Herb of Life -->
|
||||||
<item id="8602" min="1" max="1" chance="35" /> <!-- Superior Herb of Life -->
|
<item id="8603" min="1" max="1" chance="1.1" /> <!-- Herb of Mana -->
|
||||||
</group>
|
<item id="8604" min="1" max="1" chance="5.94" /> <!-- Major Herb of Mana -->
|
||||||
<group chance="11">
|
<item id="8605" min="1" max="1" chance="3.96" /> <!-- Superior Herb of Mana -->
|
||||||
<item id="8603" min="1" max="1" chance="10" /> <!-- Herb of Mana -->
|
<item id="8606" min="1" max="1" chance="5" /> <!-- Herb of Power -->
|
||||||
<item id="8604" min="1" max="1" chance="54" /> <!-- Major Herb of Mana -->
|
<item id="8608" min="1" max="1" chance="5" /> <!-- Haste Herb -->
|
||||||
<item id="8605" min="1" max="1" chance="36" /> <!-- Superior Herb of Mana -->
|
<item id="8610" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Probability -->
|
||||||
</group>
|
<item id="10655" min="1" max="1" chance="5" /> <!-- Herb of HP Drain -->
|
||||||
<group chance="25">
|
<item id="10656" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Power -->
|
||||||
<item id="8606" min="1" max="1" chance="20" /> <!-- Herb of Power -->
|
<item id="8607" min="1" max="1" chance="5" /> <!-- Herb of Magic -->
|
||||||
<item id="8608" min="1" max="1" chance="20" /> <!-- Haste Herb -->
|
<item id="8609" min="1" max="1" chance="5" /> <!-- Herb of Casting Spd. -->
|
||||||
<item id="8610" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Probability -->
|
<item id="8612" min="1" max="1" chance="0.33" /> <!-- Herb of the Warrior -->
|
||||||
<item id="10655" min="1" max="1" chance="20" /> <!-- Herb of HP Drain -->
|
<item id="8613" min="1" max="1" chance="0.33" /> <!-- Wizard Herb -->
|
||||||
<item id="10656" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Power -->
|
<item id="8614" min="1" max="1" chance="0.34" /> <!-- Herb of Recovery -->
|
||||||
</group>
|
<item id="8611" min="1" max="1" chance="10.34" /> <!-- Wind Walk Herb -->
|
||||||
<group chance="10">
|
<item id="10657" min="1" max="1" chance="0.66" /> <!-- Mysterious Herb -->
|
||||||
<item id="8607" min="1" max="1" chance="50" /> <!-- Herb of Magic -->
|
</drop>
|
||||||
<item id="8609" min="1" max="1" chance="50" /> <!-- Herb of Casting Spd. -->
|
|
||||||
</group>
|
|
||||||
<group chance="1">
|
|
||||||
<item id="8612" min="1" max="1" chance="33" /> <!-- Herb of the Warrior -->
|
|
||||||
<item id="8613" min="1" max="1" chance="33" /> <!-- Wizard Herb -->
|
|
||||||
<item id="8614" min="1" max="1" chance="34" /> <!-- Herb of Recovery -->
|
|
||||||
</group>
|
|
||||||
<group chance="11">
|
|
||||||
<item id="8611" min="1" max="1" chance="94" /> <!-- Wind Walk Herb -->
|
|
||||||
<item id="10657" min="1" max="1" chance="6" /> <!-- Mysterious Herb -->
|
|
||||||
</group>
|
|
||||||
</death>
|
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
<status undying="false" />
|
<status undying="false" />
|
||||||
<collision>
|
<collision>
|
||||||
@ -138,38 +126,26 @@
|
|||||||
</clan_list>
|
</clan_list>
|
||||||
</ai>
|
</ai>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<group chance="42">
|
<item id="8600" min="1" max="1" chance="8.4" /> <!-- Herb of Life -->
|
||||||
<item id="8600" min="1" max="1" chance="20" /> <!-- Herb of Life -->
|
<item id="8601" min="1" max="1" chance="18.9" /> <!-- Major Herb of Life -->
|
||||||
<item id="8601" min="1" max="1" chance="45" /> <!-- Major Herb of Life -->
|
<item id="8602" min="1" max="1" chance="14.7" /> <!-- Superior Herb of Life -->
|
||||||
<item id="8602" min="1" max="1" chance="35" /> <!-- Superior Herb of Life -->
|
<item id="8603" min="1" max="1" chance="1.1" /> <!-- Herb of Mana -->
|
||||||
</group>
|
<item id="8604" min="1" max="1" chance="5.94" /> <!-- Major Herb of Mana -->
|
||||||
<group chance="11">
|
<item id="8605" min="1" max="1" chance="3.96" /> <!-- Superior Herb of Mana -->
|
||||||
<item id="8603" min="1" max="1" chance="10" /> <!-- Herb of Mana -->
|
<item id="8606" min="1" max="1" chance="5" /> <!-- Herb of Power -->
|
||||||
<item id="8604" min="1" max="1" chance="54" /> <!-- Major Herb of Mana -->
|
<item id="8608" min="1" max="1" chance="5" /> <!-- Haste Herb -->
|
||||||
<item id="8605" min="1" max="1" chance="36" /> <!-- Superior Herb of Mana -->
|
<item id="8610" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Probability -->
|
||||||
</group>
|
<item id="10655" min="1" max="1" chance="5" /> <!-- Herb of HP Drain -->
|
||||||
<group chance="25">
|
<item id="10656" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Power -->
|
||||||
<item id="8606" min="1" max="1" chance="20" /> <!-- Herb of Power -->
|
<item id="8607" min="1" max="1" chance="5" /> <!-- Herb of Magic -->
|
||||||
<item id="8608" min="1" max="1" chance="20" /> <!-- Haste Herb -->
|
<item id="8609" min="1" max="1" chance="5" /> <!-- Herb of Casting Spd. -->
|
||||||
<item id="8610" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Probability -->
|
<item id="8612" min="1" max="1" chance="0.33" /> <!-- Herb of the Warrior -->
|
||||||
<item id="10655" min="1" max="1" chance="20" /> <!-- Herb of HP Drain -->
|
<item id="8613" min="1" max="1" chance="0.33" /> <!-- Wizard Herb -->
|
||||||
<item id="10656" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Power -->
|
<item id="8614" min="1" max="1" chance="0.34" /> <!-- Herb of Recovery -->
|
||||||
</group>
|
<item id="8611" min="1" max="1" chance="10.34" /> <!-- Wind Walk Herb -->
|
||||||
<group chance="10">
|
<item id="10657" min="1" max="1" chance="0.66" /> <!-- Mysterious Herb -->
|
||||||
<item id="8607" min="1" max="1" chance="50" /> <!-- Herb of Magic -->
|
</drop>
|
||||||
<item id="8609" min="1" max="1" chance="50" /> <!-- Herb of Casting Spd. -->
|
|
||||||
</group>
|
|
||||||
<group chance="1">
|
|
||||||
<item id="8612" min="1" max="1" chance="33" /> <!-- Herb of the Warrior -->
|
|
||||||
<item id="8613" min="1" max="1" chance="33" /> <!-- Wizard Herb -->
|
|
||||||
<item id="8614" min="1" max="1" chance="34" /> <!-- Herb of Recovery -->
|
|
||||||
</group>
|
|
||||||
<group chance="11">
|
|
||||||
<item id="8611" min="1" max="1" chance="94" /> <!-- Wind Walk Herb -->
|
|
||||||
<item id="10657" min="1" max="1" chance="6" /> <!-- Mysterious Herb -->
|
|
||||||
</group>
|
|
||||||
</death>
|
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
<status undying="false" />
|
<status undying="false" />
|
||||||
<collision>
|
<collision>
|
||||||
@ -230,38 +206,26 @@
|
|||||||
</clan_list>
|
</clan_list>
|
||||||
</ai>
|
</ai>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<group chance="42">
|
<item id="8600" min="1" max="1" chance="8.4" /> <!-- Herb of Life -->
|
||||||
<item id="8600" min="1" max="1" chance="20" /> <!-- Herb of Life -->
|
<item id="8601" min="1" max="1" chance="18.9" /> <!-- Major Herb of Life -->
|
||||||
<item id="8601" min="1" max="1" chance="45" /> <!-- Major Herb of Life -->
|
<item id="8602" min="1" max="1" chance="14.7" /> <!-- Superior Herb of Life -->
|
||||||
<item id="8602" min="1" max="1" chance="35" /> <!-- Superior Herb of Life -->
|
<item id="8603" min="1" max="1" chance="1.1" /> <!-- Herb of Mana -->
|
||||||
</group>
|
<item id="8604" min="1" max="1" chance="5.94" /> <!-- Major Herb of Mana -->
|
||||||
<group chance="11">
|
<item id="8605" min="1" max="1" chance="3.96" /> <!-- Superior Herb of Mana -->
|
||||||
<item id="8603" min="1" max="1" chance="10" /> <!-- Herb of Mana -->
|
<item id="8606" min="1" max="1" chance="5" /> <!-- Herb of Power -->
|
||||||
<item id="8604" min="1" max="1" chance="54" /> <!-- Major Herb of Mana -->
|
<item id="8608" min="1" max="1" chance="5" /> <!-- Haste Herb -->
|
||||||
<item id="8605" min="1" max="1" chance="36" /> <!-- Superior Herb of Mana -->
|
<item id="8610" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Probability -->
|
||||||
</group>
|
<item id="10655" min="1" max="1" chance="5" /> <!-- Herb of HP Drain -->
|
||||||
<group chance="25">
|
<item id="10656" min="1" max="1" chance="5" /> <!-- Herb of Critical Attack - Power -->
|
||||||
<item id="8606" min="1" max="1" chance="20" /> <!-- Herb of Power -->
|
<item id="8607" min="1" max="1" chance="5" /> <!-- Herb of Magic -->
|
||||||
<item id="8608" min="1" max="1" chance="20" /> <!-- Haste Herb -->
|
<item id="8609" min="1" max="1" chance="5" /> <!-- Herb of Casting Spd. -->
|
||||||
<item id="8610" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Probability -->
|
<item id="8612" min="1" max="1" chance="0.33" /> <!-- Herb of the Warrior -->
|
||||||
<item id="10655" min="1" max="1" chance="20" /> <!-- Herb of HP Drain -->
|
<item id="8613" min="1" max="1" chance="0.33" /> <!-- Wizard Herb -->
|
||||||
<item id="10656" min="1" max="1" chance="20" /> <!-- Herb of Critical Attack - Power -->
|
<item id="8614" min="1" max="1" chance="0.34" /> <!-- Herb of Recovery -->
|
||||||
</group>
|
<item id="8611" min="1" max="1" chance="10.34" /> <!-- Wind Walk Herb -->
|
||||||
<group chance="10">
|
<item id="10657" min="1" max="1" chance="0.66" /> <!-- Mysterious Herb -->
|
||||||
<item id="8607" min="1" max="1" chance="50" /> <!-- Herb of Magic -->
|
</drop>
|
||||||
<item id="8609" min="1" max="1" chance="50" /> <!-- Herb of Casting Spd. -->
|
|
||||||
</group>
|
|
||||||
<group chance="1">
|
|
||||||
<item id="8612" min="1" max="1" chance="33" /> <!-- Herb of the Warrior -->
|
|
||||||
<item id="8613" min="1" max="1" chance="33" /> <!-- Wizard Herb -->
|
|
||||||
<item id="8614" min="1" max="1" chance="34" /> <!-- Herb of Recovery -->
|
|
||||||
</group>
|
|
||||||
<group chance="11">
|
|
||||||
<item id="8611" min="1" max="1" chance="94" /> <!-- Wind Walk Herb -->
|
|
||||||
<item id="10657" min="1" max="1" chance="6" /> <!-- Mysterious Herb -->
|
|
||||||
</group>
|
|
||||||
</death>
|
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
<status undying="false" />
|
<status undying="false" />
|
||||||
<collision>
|
<collision>
|
||||||
|
@ -2771,7 +2771,7 @@
|
|||||||
<height normal="68" />
|
<height normal="68" />
|
||||||
</collision>
|
</collision>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<item id="17404" min="1" max="1" chance="1.074" /> <!-- Seraph Leather Leggings -->
|
<item id="17404" min="1" max="1" chance="1.074" /> <!-- Seraph Leather Leggings -->
|
||||||
<item id="17398" min="1" max="1" chance="1.043" /> <!-- Seraph Gaiters -->
|
<item id="17398" min="1" max="1" chance="1.043" /> <!-- Seraph Gaiters -->
|
||||||
<item id="17409" min="1" max="1" chance="0.974" /> <!-- Seraph Stockings -->
|
<item id="17409" min="1" max="1" chance="0.974" /> <!-- Seraph Stockings -->
|
||||||
@ -2821,7 +2821,7 @@
|
|||||||
<item id="35438" min="1" max="1" chance="0.3" /> <!-- Recipe: Seraph Leather Armor (60%) -->
|
<item id="35438" min="1" max="1" chance="0.3" /> <!-- Recipe: Seraph Leather Armor (60%) -->
|
||||||
<item id="35439" min="1" max="1" chance="0.3" /> <!-- Recipe: Seraph Leather Leggings (60%) -->
|
<item id="35439" min="1" max="1" chance="0.3" /> <!-- Recipe: Seraph Leather Leggings (60%) -->
|
||||||
<item id="35430" min="1" max="1" chance="0.3" /> <!-- Recipe: Specter Retributer (60%) -->
|
<item id="35430" min="1" max="1" chance="0.3" /> <!-- Recipe: Specter Retributer (60%) -->
|
||||||
</death>
|
</drop>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
</npc>
|
</npc>
|
||||||
<npc id="3474" level="95" type="L2Monster" name="Super Kat the Cat" title="">
|
<npc id="3474" level="95" type="L2Monster" name="Super Kat the Cat" title="">
|
||||||
@ -3003,7 +3003,7 @@
|
|||||||
<height normal="37.5" />
|
<height normal="37.5" />
|
||||||
</collision>
|
</collision>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<item id="17308" min="1" max="1" chance="23.3" /> <!-- Immortal Boots -->
|
<item id="17308" min="1" max="1" chance="23.3" /> <!-- Immortal Boots -->
|
||||||
<item id="17318" min="1" max="1" chance="22.9" /> <!-- Immortal Gloves -->
|
<item id="17318" min="1" max="1" chance="22.9" /> <!-- Immortal Gloves -->
|
||||||
<item id="17304" min="1" max="1" chance="16.58" /> <!-- Immortal Helmet -->
|
<item id="17304" min="1" max="1" chance="16.58" /> <!-- Immortal Helmet -->
|
||||||
@ -3016,7 +3016,7 @@
|
|||||||
<item id="17291" min="1" max="1" chance="1.482" /> <!-- Requiem Cutter -->
|
<item id="17291" min="1" max="1" chance="1.482" /> <!-- Requiem Cutter -->
|
||||||
<item id="17527" min="1" max="1" chance="46.38" /> <!-- Scroll: Enchant Armor (R-grade) -->
|
<item id="17527" min="1" max="1" chance="46.38" /> <!-- Scroll: Enchant Armor (R-grade) -->
|
||||||
<item id="17526" min="1" max="1" chance="3.604" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
<item id="17526" min="1" max="1" chance="3.604" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
||||||
</death>
|
</drop>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
</npc>
|
</npc>
|
||||||
<npc id="3478" level="87" type="L2Monster" name="Reinforced Kat the Cat" title="">
|
<npc id="3478" level="87" type="L2Monster" name="Reinforced Kat the Cat" title="">
|
||||||
@ -3112,7 +3112,7 @@
|
|||||||
<height normal="37.5" />
|
<height normal="37.5" />
|
||||||
</collision>
|
</collision>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<item id="17343" min="1" max="1" chance="66.6" /> <!-- Twilight Shield -->
|
<item id="17343" min="1" max="1" chance="66.6" /> <!-- Twilight Shield -->
|
||||||
<item id="17339" min="1" max="1" chance="17.44" /> <!-- Twilight Breastplate -->
|
<item id="17339" min="1" max="1" chance="17.44" /> <!-- Twilight Breastplate -->
|
||||||
<item id="17350" min="1" max="1" chance="16.67" /> <!-- Twilight Tunic -->
|
<item id="17350" min="1" max="1" chance="16.67" /> <!-- Twilight Tunic -->
|
||||||
@ -3120,7 +3120,7 @@
|
|||||||
<item id="17330" min="1" max="1" chance="0.75" /> <!-- Apocalypse Thrower -->
|
<item id="17330" min="1" max="1" chance="0.75" /> <!-- Apocalypse Thrower -->
|
||||||
<item id="17527" min="1" max="1" chance="46.65" /> <!-- Scroll: Enchant Armor (R-grade) -->
|
<item id="17527" min="1" max="1" chance="46.65" /> <!-- Scroll: Enchant Armor (R-grade) -->
|
||||||
<item id="17526" min="1" max="1" chance="3.631" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
<item id="17526" min="1" max="1" chance="3.631" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
||||||
</death>
|
</drop>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
</npc>
|
</npc>
|
||||||
<npc id="3480" level="91" type="L2Monster" name="Mind-controlling Feline Queen" title="">
|
<npc id="3480" level="91" type="L2Monster" name="Mind-controlling Feline Queen" title="">
|
||||||
@ -3216,13 +3216,13 @@
|
|||||||
<height normal="37.5" />
|
<height normal="37.5" />
|
||||||
</collision>
|
</collision>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<item id="17352" min="1" max="1" chance="91.435" /> <!-- Twilight Gloves -->
|
<item id="17352" min="1" max="1" chance="91.435" /> <!-- Twilight Gloves -->
|
||||||
<item id="17347" min="1" max="1" chance="19.86" /> <!-- Twilight Leather Gloves -->
|
<item id="17347" min="1" max="1" chance="19.86" /> <!-- Twilight Leather Gloves -->
|
||||||
<item id="17330" min="1" max="1" chance="7.489" /> <!-- Apocalypse Thrower -->
|
<item id="17330" min="1" max="1" chance="7.489" /> <!-- Apocalypse Thrower -->
|
||||||
<item id="17334" min="1" max="1" chance="1.587" /> <!-- Apocalypse Retributer -->
|
<item id="17334" min="1" max="1" chance="1.587" /> <!-- Apocalypse Retributer -->
|
||||||
<item id="17526" min="1" max="1" chance="35.82" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
<item id="17526" min="1" max="1" chance="35.82" /> <!-- Scroll: Enchant Weapon (R-grade) -->
|
||||||
</death>
|
</drop>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
</npc>
|
</npc>
|
||||||
<npc id="3482" level="93" type="L2Monster" name="Traitorous Mew the Cat" title="">
|
<npc id="3482" level="93" type="L2Monster" name="Traitorous Mew the Cat" title="">
|
||||||
|
@ -63,19 +63,17 @@
|
|||||||
</clan_list>
|
</clan_list>
|
||||||
</ai>
|
</ai>
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<group chance="8.082">
|
<item id="2397" min="1" max="1" chance="0.0300000000000003" /> <!-- Tunic of Zubei -->
|
||||||
<item id="2397" min="1" max="1" chance="0.37119524870082" /> <!-- Tunic of Zubei -->
|
<item id="2402" min="1" max="1" chance="0.0300000000000003" /> <!-- Stockings of Zubei -->
|
||||||
<item id="2402" min="1" max="1" chance="0.37119524870082" /> <!-- Stockings of Zubei -->
|
<item id="2406" min="1" max="1" chance="0.0300000000000003" /> <!-- Avadon Robe -->
|
||||||
<item id="2406" min="1" max="1" chance="0.37119524870082" /> <!-- Avadon Robe -->
|
<item id="4070" min="1" max="1" chance="3.70500000000001" /> <!-- Stockings of Zubei Fabric -->
|
||||||
<item id="4070" min="1" max="1" chance="45.842613214551" /> <!-- Stockings of Zubei Fabric -->
|
<item id="4069" min="1" max="1" chance="2.47499999999997" /> <!-- Tunic of Zubei Fabric -->
|
||||||
<item id="4069" min="1" max="1" chance="30.623608017817" /> <!-- Tunic of Zubei Fabric -->
|
<item id="4071" min="1" max="1" chance="1.81199999999997" /> <!-- Avadon Robe Fabric -->
|
||||||
<item id="4071" min="1" max="1" chance="22.420193021529" /> <!-- Avadon Robe Fabric -->
|
</drop>
|
||||||
</group>
|
<lucky_drop>
|
||||||
</death>
|
|
||||||
<lucky_corpse>
|
|
||||||
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
<item id="39629" min="1" max="1" chance="100" /> <!-- Fortune Pocket - Stage 1 -->
|
||||||
</lucky_corpse>
|
</lucky_drop>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
<collision>
|
<collision>
|
||||||
<radius normal="14" />
|
<radius normal="14" />
|
||||||
|
@ -2175,20 +2175,16 @@
|
|||||||
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
<s_npc_prop_hp_rate>0.25</s_npc_prop_hp_rate>
|
||||||
<ai type="BALANCED" aggroRange="300" clanHelpRange="300" isAggressive="true" />
|
<ai type="BALANCED" aggroRange="300" clanHelpRange="300" isAggressive="true" />
|
||||||
<drop_lists>
|
<drop_lists>
|
||||||
<death>
|
<drop>
|
||||||
<group chance="70">
|
<item id="57" min="711" max="1659" chance="70" /> <!-- Adena -->
|
||||||
<item id="57" min="711" max="1659" chance="100" /> <!-- Adena -->
|
<item id="8787" min="1" max="1" chance="17.71" /> <!-- Sprigant's Fruit -->
|
||||||
</group>
|
</drop>
|
||||||
<group chance="17.71">
|
<spoil>
|
||||||
<item id="8787" min="1" max="1" chance="100" /> <!-- Sprigant's Fruit -->
|
|
||||||
</group>
|
|
||||||
</death>
|
|
||||||
<corpse>
|
|
||||||
<item id="36532" min="1" max="1" chance="0.75" /> <!-- Thin Braid -->
|
<item id="36532" min="1" max="1" chance="0.75" /> <!-- Thin Braid -->
|
||||||
<item id="36533" min="1" max="1" chance="0.3" /> <!-- Synthetic Braid -->
|
<item id="36533" min="1" max="1" chance="0.3" /> <!-- Synthetic Braid -->
|
||||||
<item id="36882" min="1" max="1" chance="0.03" /> <!-- Recipe: Thin Braid - Upgrade -->
|
<item id="36882" min="1" max="1" chance="0.03" /> <!-- Recipe: Thin Braid - Upgrade -->
|
||||||
<item id="36881" min="1" max="1" chance="0.003" /> <!-- Recipe: Thin Braid - Downgrade -->
|
<item id="36881" min="1" max="1" chance="0.003" /> <!-- Recipe: Thin Braid - Downgrade -->
|
||||||
</corpse>
|
</spoil>
|
||||||
</drop_lists>
|
</drop_lists>
|
||||||
<collision>
|
<collision>
|
||||||
<radius normal="45" />
|
<radius normal="45" />
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user