Drops rework.

This commit is contained in:
MobiusDev
2017-10-06 00:53:49 +00:00
parent 2c61857b12
commit fc94704b2d
408 changed files with 741952 additions and 835872 deletions
-12
View File
@@ -509,18 +509,6 @@ DualboxCheckWhitelist = 127.0.0.1,0
AllowChangePassword = False
# ---------------------------------------------------------------------------
# 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
# ---------------------------------------------------------------------------
# Custom Starting Location
# ---------------------------------------------------------------------------
-30
View File
@@ -187,33 +187,3 @@ DisableRaidCurse = False
RaidChaosTime = 30
GrandChaosTime = 30
MinionChaosTime = 30
# ---------------------------------------------------------------------------
# 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=16
# Default: 15
DropAdenaMaxLevelDifference=30
# 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=20
# 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=10
# Default: 10
DropItemMaxLevelDifference=20
# 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=20
+62 -33
View File
@@ -5,39 +5,6 @@
# Warning:
# 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)
# ---------------------------------------------------------------------------
@@ -97,6 +64,68 @@ RateQuestRewardRecipe = 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
# ---------------------------------------------------------------------------
@@ -245,7 +245,7 @@ public class AdminAdmin implements IAdminCommandHandler
}
case "RateDropSpoil":
{
Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER = Float.valueOf(pValue);
Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER = Float.valueOf(pValue);
break;
}
case "EnchantChanceElementStone":
@@ -363,7 +363,7 @@ public class AdminAdmin implements IAdminCommandHandler
replyMSG.append("<tr><td><font color=\"00AA00\">Drop:</font></td><td></td><td></td></tr>");
replyMSG.append("<tr><td><font color=\"LEVEL\">Rate EXP</font> = " + Config.RATE_XP + "</td><td><edit var=\"param1\" width=40 height=15></td><td><button value=\"Set\" action=\"bypass -h admin_setconfig RateXp $param1\" width=40 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr>");
replyMSG.append("<tr><td><font color=\"LEVEL\">Rate SP</font> = " + Config.RATE_SP + "</td><td><edit var=\"param2\" width=40 height=15></td><td><button value=\"Set\" action=\"bypass -h admin_setconfig RateSp $param2\" width=40 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr>");
replyMSG.append("<tr><td><font color=\"LEVEL\">Rate Drop Spoil</font> = " + Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER + "</td><td><edit var=\"param4\" width=40 height=15></td><td><button value=\"Set\" action=\"bypass -h admin_setconfig RateDropSpoil $param4\" width=40 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr>");
replyMSG.append("<tr><td><font color=\"LEVEL\">Rate Drop Spoil</font> = " + Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER + "</td><td><edit var=\"param4\" width=40 height=15></td><td><button value=\"Set\" action=\"bypass -h admin_setconfig RateDropSpoil $param4\" width=40 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr>");
replyMSG.append("<tr><td width=140></td><td width=40></td><td width=40></td></tr>");
replyMSG.append("<tr><td><font color=\"00AA00\">Enchant:</font></td><td></td><td></td></tr>");
replyMSG.append("<tr><td><font color=\"LEVEL\">Enchant Element Stone</font> = " + Config.ENCHANT_CHANCE_ELEMENT_STONE + "</td><td><edit var=\"param8\" width=40 height=15></td><td><button value=\"Set\" action=\"bypass -h admin_setconfig EnchantChanceElementStone $param8\" width=40 height=25 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr>");
@@ -18,12 +18,13 @@ package handlers.bypasshandlers;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.TimeUnit;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.cache.HtmCache;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.DropType;
import com.l2jmobius.gameserver.handler.IBypassHandler;
import com.l2jmobius.gameserver.model.Elementals;
import com.l2jmobius.gameserver.model.L2Object;
@@ -32,10 +33,7 @@ import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.drops.DropListScope;
import com.l2jmobius.gameserver.model.drops.GeneralDropItem;
import com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem;
import com.l2jmobius.gameserver.model.drops.IDropItem;
import com.l2jmobius.gameserver.model.holders.DropHolder;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.util.HtmlUtil;
@@ -104,17 +102,18 @@ public class NpcViewMod implements IBypassHandler
return false;
}
final String dropListScopeString = st.nextToken();
final String dropListTypeString = st.nextToken();
try
{
final DropListScope dropListScope = Enum.valueOf(DropListScope.class, dropListScopeString);
final DropType dropListType = Enum.valueOf(DropType.class, dropListTypeString);
final L2Object target = L2World.getInstance().findObject(Integer.parseInt(st.nextToken()));
final L2Npc npc = target instanceof L2Npc ? (L2Npc) target : null;
if (npc == null)
{
return false;
}
sendNpcDropList(activeChar, npc, dropListScope, st.hasMoreElements() ? Integer.parseInt(st.nextToken()) : 0);
final int page = st.hasMoreElements() ? Integer.parseInt(st.nextToken()) : 0;
sendNpcDropList(activeChar, npc, dropListType, page);
}
catch (NumberFormatException e)
{
@@ -122,7 +121,7 @@ public class NpcViewMod implements IBypassHandler
}
catch (IllegalArgumentException e)
{
_log.warning("Bypass[NpcViewMod] unknown drop list scope: " + dropListScopeString);
_log.warning("Bypass[NpcViewMod] unknown drop list scope: " + dropListTypeString);
return false;
}
break;
@@ -216,28 +215,30 @@ public class NpcViewMod implements IBypassHandler
private static String getDropListButtons(L2Npc npc)
{
final StringBuilder sb = new StringBuilder();
final Map<DropListScope, List<IDropItem>> dropLists = npc.getTemplate().getDropLists();
if ((dropLists != null) && !dropLists.isEmpty() && (dropLists.containsKey(DropListScope.DEATH) || dropLists.containsKey(DropListScope.CORPSE)))
final List<DropHolder> dropListDeath = npc.getTemplate().getDropList(DropType.DROP);
final List<DropHolder> dropListSpoil = npc.getTemplate().getDropList(DropType.SPOIL);
if ((dropListDeath != null) || (dropListSpoil != null))
{
sb.append("<table width=275 cellpadding=0 cellspacing=0><tr>");
if (dropLists.containsKey(DropListScope.DEATH))
if (dropListDeath != null)
{
sb.append("<td align=center><button value=\"Show Drop\" width=100 height=25 action=\"bypass NpcViewMod dropList DEATH " + npc.getObjectId() + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
sb.append("<td align=center><button value=\"Show Drop\" width=100 height=25 action=\"bypass NpcViewMod dropList DROP " + npc.getObjectId() + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
}
if (dropLists.containsKey(DropListScope.CORPSE))
if (dropListSpoil != null)
{
sb.append("<td align=center><button value=\"Show Spoil\" width=100 height=25 action=\"bypass NpcViewMod dropList CORPSE " + npc.getObjectId() + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
sb.append("<td align=center><button value=\"Show Spoil\" width=100 height=25 action=\"bypass NpcViewMod dropList SPOIL " + npc.getObjectId() + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
}
sb.append("</tr></table>");
}
return sb.toString();
}
private static void sendNpcDropList(L2PcInstance activeChar, L2Npc npc, DropListScope dropListScope, int page)
private static void sendNpcDropList(L2PcInstance activeChar, L2Npc npc, DropType dropType, int page)
{
final List<IDropItem> dropList = npc.getTemplate().getDropList(dropListScope);
if ((dropList == null) || dropList.isEmpty())
final List<DropHolder> dropList = npc.getTemplate().getDropList(dropType);
if (dropList == null)
{
return;
}
@@ -254,7 +255,7 @@ public class NpcViewMod implements IBypassHandler
pagesSb.append("<table><tr>");
for (int i = 0; i < pages; i++)
{
pagesSb.append("<td align=center><button value=\"" + (i + 1) + "\" width=20 height=20 action=\"bypass NpcViewMod dropList " + dropListScope + " " + npc.getObjectId() + " " + i + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
pagesSb.append("<td align=center><button value=\"" + (i + 1) + "\" width=20 height=20 action=\"bypass NpcViewMod dropList " + dropType + " " + npc.getObjectId() + " " + i + "\" back=\"L2UI_CT1.Button_DF_Calculator_Down\" fore=\"L2UI_CT1.Button_DF_Calculator\"></td>");
}
pagesSb.append("</tr></table>");
}
@@ -279,134 +280,148 @@ public class NpcViewMod implements IBypassHandler
int rightHeight = 0;
final StringBuilder leftSb = new StringBuilder();
final StringBuilder rightSb = new StringBuilder();
String limitReachedMsg = "";
for (int i = start; i < end; i++)
{
final StringBuilder sb = new StringBuilder();
int height = 64;
final IDropItem dropItem = dropList.get(i);
if (dropItem instanceof GeneralDropItem)
{
final GeneralDropItem generalDropItem = (GeneralDropItem) dropItem;
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
sb.append("<table width=332 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
sb.append("<tr><td width=32 valign=top>");
sb.append("<img src=\"" + item.getIcon() + "\" width=32 height=32>");
sb.append("</td><td fixwidth=300 align=center><font name=\"hs9\" color=\"CD9000\">");
sb.append(item.getName());
sb.append("</font></td></tr><tr><td width=32></td><td width=300><table width=295 cellpadding=0 cellspacing=0>");
sb.append("<tr><td width=48 align=right valign=top><font color=\"LEVEL\">Amount:</font></td>");
sb.append("<td width=247 align=center>");
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=247 align=center>");
sb.append(chanceFormat.format(Math.min(generalDropItem.getChance(npc, activeChar), 100)));
sb.append("%</td></tr></table></td></tr><tr><td width=32></td><td width=300>&nbsp;</td></tr></table>");
}
else if (dropItem instanceof GroupedGeneralDropItem)
{
final GroupedGeneralDropItem generalGroupedDropItem = (GroupedGeneralDropItem) dropItem;
if (generalGroupedDropItem.getItems().size() == 1)
{
final GeneralDropItem generalDropItem = generalGroupedDropItem.getItems().get(0);
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
sb.append("<table width=332 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
sb.append("<tr><td width=32 valign=top>");
sb.append("<img src=\"" + item.getIcon() + "\" width=32 height=32>");
sb.append("</td><td fixwidth=300 align=center><font name=\"hs9\" color=\"CD9000\">");
sb.append(item.getName());
sb.append("</font></td></tr><tr><td width=32></td><td width=300><table width=295 cellpadding=0 cellspacing=0>");
sb.append("<tr><td width=48 align=right valign=top><font color=\"LEVEL\">Amount:</font></td>");
sb.append("<td width=247 align=center>");
final long min = generalDropItem.getMin(npc, activeChar);
final long max = generalDropItem.getMax(npc, activeChar);
if (min == max)
{
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(generalGroupedDropItem.getChance(npc, activeChar), 100)));
sb.append("%</td></tr></table></td></tr><tr><td width=32></td><td width=300>&nbsp;</td></tr></table>");
}
else
{
sb.append("<table width=332 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
sb.append("<tr><td width=32 valign=top><img src=\"L2UI_CT1.ICON_DF_premiumItem\" width=32 height=32></td>");
sb.append("<td fixwidth=300 align=center><font name=\"ScreenMessageSmall\" color=\"CD9000\">One from group</font>");
sb.append("</td></tr><tr><td width=32></td><td width=300><table width=295 cellpadding=0 cellspacing=0><tr>");
sb.append("<td width=48 align=right valign=top><font color=\"LEVEL\">Chance:</font></td>");
sb.append("<td width=247 align=center>");
sb.append(chanceFormat.format(Math.min(generalGroupedDropItem.getChance(npc, activeChar), 100)));
sb.append("%</td></tr></table><br>");
for (GeneralDropItem generalDropItem : generalGroupedDropItem.getItems())
{
final L2Item item = ItemTable.getInstance().getTemplate(generalDropItem.getItemId());
sb.append("<table width=291 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
sb.append("<tr><td width=32 valign=top>");
String icon = item.getIcon();
if (icon == null)
{
icon = "icon.etc_question_mark_i00";
}
sb.append("<img src=\"" + icon + "\" width=32 height=32>");
sb.append("</td><td fixwidth=259 align=center><font name=\"hs9\" color=\"CD9000\">");
sb.append(item.getName());
sb.append("</font></td></tr><tr><td width=32></td><td width=259><table width=253 cellpadding=0 cellspacing=0>");
sb.append("<tr><td width=48 align=right valign=top><font color=\"LEVEL\">Amount:</font></td><td width=205 align=center>");
final long min = generalDropItem.getMin(npc, activeChar);
final long max = generalDropItem.getMax(npc, activeChar);
sb.append(amountFormat.format(min));
if (min != max)
{
sb.append(" - ");
sb.append(amountFormat.format(max));
}
sb.append("</td></tr><tr><td width=48 align=right valign=top><font color=\"LEVEL\">Chance:</font></td>");
sb.append("<td width=205 align=center>");
sb.append(chanceFormat.format(Math.min(generalDropItem.getChance(npc, activeChar), 100)));
sb.append("%</td></tr></table></td></tr><tr><td width=32></td><td width=259>&nbsp;</td></tr></table>");
height += 64;
}
sb.append("</td></tr><tr><td width=32></td><td width=300>&nbsp;</td></tr></table>");
}
}
final DropHolder dropItem = dropList.get(i);
final L2Item item = ItemTable.getInstance().getTemplate(dropItem.getItemId());
if (leftHeight >= (rightHeight + height))
// real time server rate calculations
double rateChance = 1;
double rateAmount = 1;
if (dropType == DropType.SPOIL)
{
rightSb.append(sb);
rightHeight += height;
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 && activeChar.hasPremiumStatus())
{
rateChance *= Config.PREMIUM_RATE_SPOIL_CHANCE;
rateAmount *= Config.PREMIUM_RATE_SPOIL_AMOUNT;
}
}
else
{
leftSb.append(sb);
leftHeight += height;
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
{
rateChance *= Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
}
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 (npc.isRaid())
{
rateAmount *= Config.RATE_RAID_DROP_AMOUNT_MULTIPLIER;
}
else
{
rateAmount *= Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
}
// also check premium rates if available
if (Config.PREMIUM_SYSTEM_ENABLED && activeChar.hasPremiumStatus())
{
if (Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId()) != null)
{
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
{
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE;
}
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 (npc.isRaid())
{
// TODO: Premium raid amount? :)
}
else
{
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT;
}
}
}
sb.append("<table width=332 cellpadding=2 cellspacing=0 background=\"L2UI_CT1.Windows.Windows_DF_TooltipBG\">");
sb.append("<tr><td width=32 valign=top>");
sb.append("<img src=\"" + (item.getIcon() == null ? "icon.etc_question_mark_i00" : item.getIcon()) + "\" width=32 height=32>");
sb.append("</td><td fixwidth=300 align=center><font name=\"hs9\" color=\"CD9000\">");
sb.append(item.getName());
sb.append("</font></td></tr><tr><td width=32></td><td width=300><table width=295 cellpadding=0 cellspacing=0>");
sb.append("<tr><td width=48 align=right valign=top><font color=\"LEVEL\">Amount:</font></td>");
sb.append("<td width=247 align=center>");
final long min = (long) (dropItem.getMin() * rateAmount);
final long max = (long) (dropItem.getMax() * rateAmount);
if (min == max)
{
sb.append(amountFormat.format(min));
}
else
{
sb.append(amountFormat.format(min));
sb.append(" - ");
sb.append(amountFormat.format(max));
}
sb.append("</td></tr><tr><td width=48 align=right valign=top><font color=\"LEVEL\">Chance:</font></td>");
sb.append("<td width=247 align=center>");
sb.append(chanceFormat.format(Math.min((long) dropItem.getChance() * rateChance, 100)));
sb.append("%</td></tr></table></td></tr><tr><td width=32></td><td width=300>&nbsp;</td></tr></table>");
if ((sb.length() + rightSb.length() + leftSb.length()) < 16000) // limit of 32766?
{
if (leftHeight >= (rightHeight + height))
{
rightSb.append(sb);
rightHeight += height;
}
else
{
leftSb.append(sb);
leftHeight += height;
}
}
else
{
limitReachedMsg = "<br><center>Too many drops! Could not display them all!</center>";
}
}
@@ -428,7 +443,7 @@ public class NpcViewMod implements IBypassHandler
html = html.replaceAll("%name%", npc.getName());
html = html.replaceAll("%dropListButtons%", getDropListButtons(npc));
html = html.replaceAll("%pages%", pagesSb.toString());
html = html.replaceAll("%items%", bodySb.toString());
html = html.replaceAll("%items%", bodySb.toString() + limitReachedMsg);
Util.sendCBHtml(activeChar, html);
}
}
@@ -22,23 +22,21 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringJoiner;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.cache.HtmCache;
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.datatables.SpawnTable;
import com.l2jmobius.gameserver.enums.DropType;
import com.l2jmobius.gameserver.handler.CommunityBoardHandler;
import com.l2jmobius.gameserver.handler.IParseBoardHandler;
import com.l2jmobius.gameserver.model.L2Spawn;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.drops.DropListScope;
import com.l2jmobius.gameserver.model.drops.GeneralDropItem;
import com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem;
import com.l2jmobius.gameserver.model.drops.IDropItem;
import com.l2jmobius.gameserver.model.holders.DropHolder;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
@@ -55,40 +53,40 @@ public class DropSearchBoard implements IParseBoardHandler
"_bbs_npc_trace"
};
class DropHolder
class CBDropHolder
{
int itemId;
int npcId;
byte npcLevel;
long basemin;
long basemax;
double baseGroupChance;
double basechance;
boolean isSweep;
long min;
long max;
double chance;
boolean isSpoil;
boolean isRaid;
public DropHolder(L2NpcTemplate npc, GeneralDropItem item, double groupChance, boolean isSweep)
public CBDropHolder(L2NpcTemplate npcTemplate, DropHolder dropHolder)
{
itemId = item.getItemId();
npcId = npc.getId();
npcLevel = npc.getLevel();
basemin = item.getMin();
basemax = item.getMax();
baseGroupChance = groupChance;
basechance = item.getChance();
this.isSweep = isSweep;
isSpoil = dropHolder.getDropType() == DropType.SPOIL;
itemId = dropHolder.getItemId();
npcId = npcTemplate.getId();
npcLevel = npcTemplate.getLevel();
min = dropHolder.getMin();
max = dropHolder.getMax();
chance = dropHolder.getChance();
isRaid = npcTemplate.getType().equals("L2RaidBoss") || npcTemplate.getType().equals("L2GrandBoss");
}
/**
* only for debug'/;
* only for debug
*/
@Override
public String toString()
{
return "DropHolder [itemId=" + itemId + ", npcId=" + npcId + ", npcLevel=" + npcLevel + ", basemin=" + basemin + ", basemax=" + basemax + ", baseGroupChance=" + baseGroupChance + ", basechance=" + basechance + ", isSweep=" + isSweep + "]";
return "DropHolder [itemId=" + itemId + ", npcId=" + npcId + ", npcLevel=" + npcLevel + ", min=" + min + ", max=" + max + ", chance=" + chance + ", isSpoil=" + isSpoil + "]";
}
}
private final Map<Integer, List<DropHolder>> DROP_INDEX_CACHE = new HashMap<>();
private final Map<Integer, List<CBDropHolder>> DROP_INDEX_CACHE = new HashMap<>();
// nonsupport items
private final Set<Integer> BLOCK_ID = new HashSet<>();
@@ -103,44 +101,39 @@ public class DropSearchBoard implements IParseBoardHandler
private void buildDropIndex()
{
NpcData.getInstance().getTemplates(npc -> npc.getDropLists() != null).forEach(npcTemplate ->
NpcData.getInstance().getTemplates(npc -> npc.getDropList(DropType.DROP) != null).forEach(npcTemplate ->
{
for (Entry<DropListScope, List<IDropItem>> entry : npcTemplate.getDropLists().entrySet())
for (DropHolder dropHolder : npcTemplate.getDropList(DropType.DROP))
{
entry.getValue().forEach(idrop ->
{
if (idrop instanceof GroupedGeneralDropItem)
{
GroupedGeneralDropItem ggd = (GroupedGeneralDropItem) idrop;
ggd.getItems().stream().forEach(gd -> addToDropList(npcTemplate, gd, ggd.getChance(), entry.getKey() == DropListScope.CORPSE));
}
else
{
GeneralDropItem gd = (GeneralDropItem) idrop;
addToDropList(npcTemplate, gd, 100.0, entry.getKey() == DropListScope.CORPSE);
}
});
addToDropList(npcTemplate, dropHolder);
}
});
NpcData.getInstance().getTemplates(npc -> npc.getDropList(DropType.SPOIL) != null).forEach(npcTemplate ->
{
for (DropHolder dropHolder : npcTemplate.getDropList(DropType.SPOIL))
{
addToDropList(npcTemplate, dropHolder);
}
});
DROP_INDEX_CACHE.values().stream().forEach(l -> l.sort((d1, d2) -> Byte.valueOf(d1.npcLevel).compareTo(Byte.valueOf(d2.npcLevel))));
}
private void addToDropList(L2NpcTemplate npcTemplate, GeneralDropItem gd, double groupChance, boolean isSweep)
private void addToDropList(L2NpcTemplate npcTemplate, DropHolder dropHolder)
{
if (BLOCK_ID.contains(gd.getItemId()))
if (BLOCK_ID.contains(dropHolder.getItemId()))
{
return;
}
List<DropHolder> dropList = DROP_INDEX_CACHE.get(gd.getItemId());
List<CBDropHolder> dropList = DROP_INDEX_CACHE.get(dropHolder.getItemId());
if (dropList == null)
{
dropList = new ArrayList<>();
DROP_INDEX_CACHE.put(gd.getItemId(), dropList);
DROP_INDEX_CACHE.put(dropHolder.getItemId(), dropList);
}
dropList.add(new DropHolder(npcTemplate, gd, groupChance, isSweep));
dropList.add(new CBDropHolder(npcTemplate, dropHolder));
}
@Override
@@ -163,7 +156,7 @@ public class DropSearchBoard implements IParseBoardHandler
final DecimalFormat chanceFormat = new DecimalFormat("0.00##");
int itemId = Integer.parseInt(params[1]);
int page = Integer.parseInt(params[2]);
List<DropHolder> list = DROP_INDEX_CACHE.get(itemId);
List<CBDropHolder> list = DROP_INDEX_CACHE.get(itemId);
int pages = list.size() / 14;
if (pages == 0)
{
@@ -175,13 +168,106 @@ public class DropSearchBoard implements IParseBoardHandler
StringBuilder builder = new StringBuilder();
for (int index = start; index <= end; index++)
{
DropHolder dropHolder = list.get(index);
CBDropHolder cbDropHolder = list.get(index);
// real time server rate calculations
double rateChance = 1;
double rateAmount = 1;
if (cbDropHolder.isSpoil)
{
rateChance = Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER;
rateAmount = Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER;
// also check premium rates if available
if (Config.PREMIUM_SYSTEM_ENABLED && player.hasPremiumStatus())
{
rateChance *= Config.PREMIUM_RATE_SPOIL_CHANCE;
rateAmount *= Config.PREMIUM_RATE_SPOIL_AMOUNT;
}
}
else
{
final L2Item item = ItemTable.getInstance().getTemplate(cbDropHolder.itemId);
if (Config.RATE_DROP_CHANCE_BY_ID.get(cbDropHolder.itemId) != null)
{
rateChance *= Config.RATE_DROP_CHANCE_BY_ID.get(cbDropHolder.itemId);
}
else if (item.hasExImmediateEffect())
{
rateChance *= Config.RATE_HERB_DROP_CHANCE_MULTIPLIER;
}
else if (cbDropHolder.isRaid)
{
rateAmount *= Config.RATE_RAID_DROP_CHANCE_MULTIPLIER;
}
else
{
rateChance *= Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER;
}
if (Config.RATE_DROP_AMOUNT_BY_ID.get(cbDropHolder.itemId) != null)
{
rateAmount *= Config.RATE_DROP_AMOUNT_BY_ID.get(cbDropHolder.itemId);
}
else if (cbDropHolder.isRaid)
{
rateAmount *= Config.RATE_RAID_DROP_AMOUNT_MULTIPLIER;
}
else if (item.hasExImmediateEffect())
{
rateAmount *= Config.RATE_HERB_DROP_AMOUNT_MULTIPLIER;
}
else
{
rateAmount *= Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER;
}
// also check premium rates if available
if (Config.PREMIUM_SYSTEM_ENABLED && player.hasPremiumStatus())
{
if (Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(cbDropHolder.itemId) != null)
{
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(cbDropHolder.itemId);
}
else if (item.hasExImmediateEffect())
{
// TODO: Premium herb chance? :)
}
else if (cbDropHolder.isRaid)
{
// TODO: Premium raid chance? :)
}
else
{
rateChance *= Config.PREMIUM_RATE_DROP_CHANCE;
}
if (Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(cbDropHolder.itemId) != null)
{
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(cbDropHolder.itemId);
}
else if (item.hasExImmediateEffect())
{
// TODO: Premium herb amount? :)
}
else if (cbDropHolder.isRaid)
{
// TODO: Premium raid amount? :)
}
else
{
rateAmount *= Config.PREMIUM_RATE_DROP_AMOUNT;
}
}
}
builder.append("<tr>");
builder.append("<td width=30>").append(dropHolder.npcLevel).append("</td>");
builder.append("<td width=170>").append("<a action=\"bypass _bbs_npc_trace " + dropHolder.npcId + "\">").append("&@").append(dropHolder.npcId).append(";").append("</a>").append("</td>");
builder.append("<td width=80 align=CENTER>").append(dropHolder.basemin).append("-").append(dropHolder.basemax).append("</td>");
builder.append("<td width=50 align=CENTER>").append(chanceFormat.format((dropHolder.basechance * dropHolder.baseGroupChance) / 100)).append("%").append("</td>");
builder.append("<td width=50 align=CENTER>").append(dropHolder.isSweep ? "Sweep" : "Drop").append("</td>");
builder.append("<td width=30>").append(cbDropHolder.npcLevel).append("</td>");
builder.append("<td width=170>").append("<a action=\"bypass _bbs_npc_trace " + cbDropHolder.npcId + "\">").append("&@").append(cbDropHolder.npcId).append(";").append("</a>").append("</td>");
builder.append("<td width=80 align=CENTER>").append(cbDropHolder.min * rateAmount).append("-").append(cbDropHolder.max * rateAmount).append("</td>");
builder.append("<td width=50 align=CENTER>").append(chanceFormat.format(cbDropHolder.chance * rateChance)).append("%").append("</td>");
builder.append("<td width=50 align=CENTER>").append(cbDropHolder.isSpoil ? "Spoil" : "Drop").append("</td>");
builder.append("</tr>");
}
@@ -203,7 +289,7 @@ public class DropSearchBoard implements IParseBoardHandler
L2Spawn spawn = SpawnTable.getInstance().findAny(npcId);
if (spawn == null)
{
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
{
@@ -49,15 +49,15 @@ public class Premium implements IVoicedCommandHandler
html.append("<tr><td>Rate SP: <font color=\"LEVEL\"> x" + Config.RATE_SP + "<br1></font></td></tr>");
html.append("<tr><td>Drop Chance: <font color=\"LEVEL\"> x" + Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER + "<br1></font></td></tr><br>");
html.append("<tr><td>Drop Amount: <font color=\"LEVEL\"> x" + Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER + "<br1></font></td></tr><br>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\"> x" + Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER + "<br1></font></td></tr><br>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\"> x" + Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER + "<br><br></font></td></tr><br>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\"> x" + Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER + "<br1></font></td></tr><br>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\"> x" + Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER + "<br><br></font></td></tr><br>");
html.append("<tr><td><center>Premium Info & Rules<br></td></tr>");
html.append("<tr><td>Rate XP: <font color=\"LEVEL\"> x" + (Config.RATE_XP * Config.PREMIUM_RATE_XP) + "<br1></font></td></tr>");
html.append("<tr><td>Rate SP: <font color=\"LEVEL\"> x" + (Config.RATE_SP * Config.PREMIUM_RATE_SP) + "<br1></font></td></tr>");
html.append("<tr><td>Drop Chance: <font color=\"LEVEL\"> x" + (Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER * Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_DROP_CHANCE) + "<br1></font></td></tr>");
html.append("<tr><td>Drop Amount: <font color=\"LEVEL\"> x" + (Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_DROP_AMOUNT) + "<br1></font></td></tr>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\"> x" + (Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_CHANCE) + "<br1></font></td></tr>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\"> x" + (Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + "<br1></font></td></tr>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\"> x" + (Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_CHANCE) + "<br1></font></td></tr>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\"> x" + (Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + "<br1></font></td></tr>");
html.append("<tr><td> <font color=\"70FFCA\">1. Premium benefits CAN NOT BE TRANSFERED.<br1></font></td></tr>");
html.append("<tr><td> <font color=\"70FFCA\">2. Premium does not effect party members.<br1></font></td></tr>");
html.append("<tr><td> <font color=\"70FFCA\">3. Premium benefits effect ALL characters in same account.</font></td></tr>");
@@ -71,8 +71,8 @@ public class Premium implements IVoicedCommandHandler
html.append("<tr><td>Rate SP: <font color=\"LEVEL\">x" + (Config.RATE_SP * Config.PREMIUM_RATE_SP) + " <br1></font></td></tr>");
html.append("<tr><td>Drop Chance: <font color=\"LEVEL\">x" + (Config.RATE_DEATH_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_DROP_CHANCE) + " <br1></font></td></tr>");
html.append("<tr><td>Drop Amount: <font color=\"LEVEL\">x" + (Config.RATE_DEATH_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_DROP_AMOUNT) + " <br1></font></td></tr>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\">x" + (Config.RATE_CORPSE_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_CHANCE) + " <br1></font></td></tr>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\">x" + (Config.RATE_CORPSE_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + " <br1></font></td></tr>");
html.append("<tr><td>Spoil Chance: <font color=\"LEVEL\">x" + (Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_CHANCE) + " <br1></font></td></tr>");
html.append("<tr><td>Spoil Amount: <font color=\"LEVEL\">x" + (Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER * Config.PREMIUM_RATE_SPOIL_AMOUNT) + " <br1></font></td></tr>");
html.append("<tr><td>Expires: <font color=\"00A5FF\">" + format.format(endDate) + "</font></td></tr>");
html.append("<tr><td>Current Date: <font color=\"70FFCA\">" + format.format(System.currentTimeMillis()) + "<br><br></font></td></tr>");
html.append("<tr><td><center>Premium Info & Rules<br></center></td></tr>");
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,147 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="1600" level="80" type="L2Npc" name="Zinyanzi Agathion">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="1601" level="80" type="L2Npc" name="Super Feline Queen Z">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4416" level="7" /> <!--Spirits -->
<skill id="23318" level="1" /> <!--Cat the Ranger Boots -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="1602" level="80" type="L2Npc" name="Super Kat the Cat Z">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4416" level="2" /> <!--Magic Creatures -->
<skill id="5745" level="1" /> <!--Death Blow -->
<skill id="5746" level="1" /> <!--Double Attack -->
<skill id="5747" level="1" /> <!--Spin Attack -->
<skill id="6046" level="1" /> <!--Piercing Attack -->
<skill id="6047" level="1" /> <!--Whirlwind -->
<skill id="6048" level="1" /> <!--Lance Smash -->
<skill id="6049" level="1" /> <!--Battle Cry -->
<skill id="23318" level="1" /> <!--Cat the Ranger Boots -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="1603" level="80" type="L2Npc" name="Super Mew the Cat Z">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4416" level="4" /> <!--Animals -->
<skill id="5745" level="1" /> <!--Death Blow -->
<skill id="5746" level="1" /> <!--Double Attack -->
<skill id="5747" level="1" /> <!--Spin Attack -->
<skill id="6050" level="1" /> <!--Power Smash -->
<skill id="6053" level="1" /> <!--Ignite -->
<skill id="23318" level="1" /> <!--Cat the Ranger Boots -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="1604" level="80" type="L2Npc" name="Hanbok Agathion">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="1605" level="80" type="L2Npc" name="Juju Agathion">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="1600" level="80" type="L2Npc" name="Zinyanzi Agathion">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="1601" level="80" type="L2Npc" name="Super Feline Queen Z">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4416" level="7" /> <!--Spirits -->
<skill id="23318" level="1" /> <!--Cat the Ranger Boots -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="1602" level="80" type="L2Npc" name="Super Kat the Cat Z">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4416" level="2" /> <!--Magic Creatures -->
<skill id="5745" level="1" /> <!--Death Blow -->
<skill id="5746" level="1" /> <!--Double Attack -->
<skill id="5747" level="1" /> <!--Spin Attack -->
<skill id="6046" level="1" /> <!--Piercing Attack -->
<skill id="6047" level="1" /> <!--Whirlwind -->
<skill id="6048" level="1" /> <!--Lance Smash -->
<skill id="6049" level="1" /> <!--Battle Cry -->
<skill id="23318" level="1" /> <!--Cat the Ranger Boots -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="1603" level="80" type="L2Npc" name="Super Mew the Cat Z">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4416" level="4" /> <!--Animals -->
<skill id="5745" level="1" /> <!--Death Blow -->
<skill id="5746" level="1" /> <!--Double Attack -->
<skill id="5747" level="1" /> <!--Spin Attack -->
<skill id="6050" level="1" /> <!--Power Smash -->
<skill id="6053" level="1" /> <!--Ignite -->
<skill id="23318" level="1" /> <!--Cat the Ranger Boots -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="1604" level="80" type="L2Npc" name="Hanbok Agathion">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="1605" level="80" type="L2Npc" name="Juju Agathion">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
</list>
@@ -1,79 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="2081" level="80" type="L2Npc" name="Plague Kanabion">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4032" level="1" /> <!--NPC Strike -->
<skill id="4416" level="9" /> <!--Demons -->
<skill id="5565" level="1" /> <!--Expose Weak Point -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="2082" level="80" type="L2Npc" name="Plague Kanabion" title="Doppler">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4032" level="1" /> <!--NPC Strike -->
<skill id="4416" level="9" /> <!--Demons -->
<skill id="5565" level="1" /> <!--Expose Weak Point -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="2083" level="80" type="L2Npc" name="Plague Kanabion" title="Void">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4032" level="1" /> <!--NPC Strike -->
<skill id="4340" level="1" /> <!--Ultimate Buff, 2nd -->
<skill id="4416" level="9" /> <!--Demons -->
<skill id="5565" level="1" /> <!--Expose Weak Point -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="2081" level="80" type="L2Npc" name="Plague Kanabion">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4032" level="1" /> <!--NPC Strike -->
<skill id="4416" level="9" /> <!--Demons -->
<skill id="5565" level="1" /> <!--Expose Weak Point -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="2082" level="80" type="L2Npc" name="Plague Kanabion" title="Doppler">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4032" level="1" /> <!--NPC Strike -->
<skill id="4416" level="9" /> <!--Demons -->
<skill id="5565" level="1" /> <!--Expose Weak Point -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
<npc id="2083" level="80" type="L2Npc" name="Plague Kanabion" title="Void">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4032" level="1" /> <!--NPC Strike -->
<skill id="4340" level="1" /> <!--Ultimate Buff, 2nd -->
<skill id="4416" level="9" /> <!--Demons -->
<skill id="5565" level="1" /> <!--Expose Weak Point -->
</skillList>
<collision>
<radius normal="25" />
<height normal="35" />
</collision>
</npc>
</list>
@@ -1,68 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="2501" level="80" type="L2Monster" name="Lucky Pig" title="The Spirit of Fortune">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4416" level="3" /> <!--Beasts -->
<skill id="23325" level="1" /> <!--Enlarge - Luckpy -->
<skill id="23326" level="1" /> <!--Reduce - Luckpy -->
</skillList>
<collision>
<radius normal="25" />
<height normal="18" />
</collision>
</npc>
<npc id="2502" level="80" type="L2Monster" name="Wingless Lucky Pig">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<collision>
<radius normal="25" />
<height normal="18" />
</collision>
</npc>
<npc id="2503" level="80" type="L2Monster" name="Wingless Lucky Pig">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<collision>
<radius normal="25" />
<height normal="18" />
</collision>
</npc>
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="2501" level="80" type="L2Monster" name="Lucky Pig" title="The Spirit of Fortune">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<skillList>
<skill id="4416" level="3" /> <!--Beasts -->
<skill id="23325" level="1" /> <!--Enlarge - Luckpy -->
<skill id="23326" level="1" /> <!--Reduce - Luckpy -->
</skillList>
<collision>
<radius normal="25" />
<height normal="18" />
</collision>
</npc>
<npc id="2502" level="80" type="L2Monster" name="Wingless Lucky Pig">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<collision>
<radius normal="25" />
<height normal="18" />
</collision>
</npc>
<npc id="2503" level="80" type="L2Monster" name="Wingless Lucky Pig">
<!-- TODO: Must be confirmed -->
<sex>MALE</sex>
<stats str="10" int="10" dex="10" wit="10" con="10" men="10">
<vitals hp="2444" mp="2444.0" />
<attack physical="500" magical="500" attackSpeed="278" range="40" />
<defence physical="500" magical="500" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="160" />
</speed>
</stats>
<collision>
<radius normal="25" />
<height normal="18" />
</collision>
</npc>
</list>
File diff suppressed because it is too large Load Diff
@@ -1,41 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="12077" level="15" type="L2Pet" name="Wolf">
<!-- Confirmed CT2.5 -->
<race>ANIMAL</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="246.95422" hpRegen="2.5" mp="149.2" mpRegen="1.2" />
<attack physical="29.61691" magical="20.22451" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="73.55216" magical="53.82228" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="24" />
<run ground="125" />
</speed>
<hitTime>390</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="4" /> <!--Animals -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="13" />
<height normal="11.5" />
</collision>
</npc>
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="12077" level="15" type="L2Pet" name="Wolf">
<!-- Confirmed CT2.5 -->
<race>ANIMAL</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="246.95422" hpRegen="2.5" mp="149.2" mpRegen="1.2" />
<attack physical="29.61691" magical="20.22451" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="73.55216" magical="53.82228" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="24" />
<run ground="125" />
</speed>
<hitTime>390</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="4" /> <!--Animals -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="13" />
<height normal="11.5" />
</collision>
</npc>
</list>
@@ -1,128 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="12311" level="35" type="L2Pet" name="Hatchling of the Wind">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="PhysicalSpecial" id="4710" level="1" /> <!-- Wild Stun -->
<skill name="Buff" id="4711" level="1" /> <!-- Wild Defense -->
</parameters>
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="772.73802" hpRegen="4.5" mp="402.6" mpRegen="1.8" />
<attack physical="129.32896" magical="88.31491" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="136.72948" magical="100.0527" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="140" />
</speed>
<hitTime>270</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4715" level="1" /> <!--Wind Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="9" />
<height normal="10" />
</collision>
</npc>
<npc id="12312" level="35" type="L2Pet" name="Hatchling of the Stars">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="DDMagic" id="4712" level="1" /> <!-- Bright Burst -->
<skill name="Heal" id="4713" level="1" /> <!-- Bright Heal -->
</parameters>
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="772.73802" hpRegen="4.5" mp="402.6" mpRegen="1.8" />
<attack physical="129.32896" magical="88.31491" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="136.72948" magical="100.0527" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="140" />
</speed>
<hitTime>270</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4716" level="1" /> <!--Star Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="9" />
<height normal="10" />
</collision>
</npc>
<npc id="12313" level="35" type="L2Pet" name="Hatchling of Twilight">
<!-- Confirmed CT2.5 -->
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="772.73802" hpRegen="4.5" mp="402.6" mpRegen="1.8" />
<attack physical="129.32896" magical="88.31491" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="136.72948" magical="100.0527" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="140" />
</speed>
<hitTime>270</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4714" level="1" /> <!--Twilight Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="9" />
<height normal="10" />
</collision>
</npc>
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="12311" level="35" type="L2Pet" name="Hatchling of the Wind">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="PhysicalSpecial" id="4710" level="1" /> <!-- Wild Stun -->
<skill name="Buff" id="4711" level="1" /> <!-- Wild Defense -->
</parameters>
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="772.73802" hpRegen="4.5" mp="402.6" mpRegen="1.8" />
<attack physical="129.32896" magical="88.31491" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="136.72948" magical="100.0527" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="140" />
</speed>
<hitTime>270</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4715" level="1" /> <!--Wind Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="9" />
<height normal="10" />
</collision>
</npc>
<npc id="12312" level="35" type="L2Pet" name="Hatchling of the Stars">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="DDMagic" id="4712" level="1" /> <!-- Bright Burst -->
<skill name="Heal" id="4713" level="1" /> <!-- Bright Heal -->
</parameters>
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="772.73802" hpRegen="4.5" mp="402.6" mpRegen="1.8" />
<attack physical="129.32896" magical="88.31491" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="136.72948" magical="100.0527" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="140" />
</speed>
<hitTime>270</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4716" level="1" /> <!--Star Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="9" />
<height normal="10" />
</collision>
</npc>
<npc id="12313" level="35" type="L2Pet" name="Hatchling of Twilight">
<!-- Confirmed CT2.5 -->
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="772.73802" hpRegen="4.5" mp="402.6" mpRegen="1.8" />
<attack physical="129.32896" magical="88.31491" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="136.72948" magical="100.0527" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="140" />
</speed>
<hitTime>270</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4714" level="1" /> <!--Twilight Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="9" />
<height normal="10" />
</collision>
</npc>
</list>
@@ -1,166 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="12526" level="55" type="L2Pet" name="Wind Strider">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="PhysicalSpecial" id="4710" level="1" /> <!-- Wild Stun -->
<skill name="Buff" id="4711" level="1" /> <!-- Wild Defense -->
</parameters>
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="1673.05473" hpRegen="6.5" mp="889.8" mpRegen="2.4" />
<attack physical="388.11142" magical="265.02979" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="223.6362" magical="163.64727" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="170" />
</speed>
<hitTime>250</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4715" level="1" /> <!--Wind Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="23" />
<height normal="31" />
</collision>
</npc>
<npc id="12527" level="55" type="L2Pet" name="Star Strider">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="DDMagic" id="4712" level="1" /> <!-- Bright Burst -->
<skill name="Heal" id="4713" level="1" /> <!-- Bright Heal -->
</parameters>
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="1673.05473" hpRegen="6.5" mp="889.8" mpRegen="2.4" />
<attack physical="388.11142" magical="265.02979" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="223.6362" magical="163.64727" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="170" />
</speed>
<hitTime>250</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4716" level="1" /> <!--Star Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="23" />
<height normal="31" />
</collision>
</npc>
<npc id="12528" level="55" type="L2Pet" name="Twilight Strider">
<!-- Confirmed CT2.5 -->
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="1673.05473" hpRegen="6.5" mp="889.8" mpRegen="2.4" />
<attack physical="388.11142" magical="265.02979" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="223.6362" magical="163.64727" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="170" />
</speed>
<hitTime>250</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4714" level="1" /> <!--Twilight Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="23" />
<height normal="31" />
</collision>
</npc>
<npc id="12564" level="15" type="L2Pet" name="Sin Eater">
<!-- Confirmed CT2.5 -->
<race>FAIRY</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="1" men="25">
<vitals hp="424.2" hpRegen="7.2513" mp="149.2" mpRegen="1.2" />
<attack physical="29.61691" magical="20.22451" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="73.55216" magical="53.82228" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="125" />
</speed>
<hitTime>340</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="13" /> <!--Fairies -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="10" />
<height normal="24" />
</collision>
</npc>
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="12526" level="55" type="L2Pet" name="Wind Strider">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="PhysicalSpecial" id="4710" level="1" /> <!-- Wild Stun -->
<skill name="Buff" id="4711" level="1" /> <!-- Wild Defense -->
</parameters>
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="1673.05473" hpRegen="6.5" mp="889.8" mpRegen="2.4" />
<attack physical="388.11142" magical="265.02979" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="223.6362" magical="163.64727" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="170" />
</speed>
<hitTime>250</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4715" level="1" /> <!--Wind Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="23" />
<height normal="31" />
</collision>
</npc>
<npc id="12527" level="55" type="L2Pet" name="Star Strider">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="DDMagic" id="4712" level="1" /> <!-- Bright Burst -->
<skill name="Heal" id="4713" level="1" /> <!-- Bright Heal -->
</parameters>
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="1673.05473" hpRegen="6.5" mp="889.8" mpRegen="2.4" />
<attack physical="388.11142" magical="265.02979" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="223.6362" magical="163.64727" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="170" />
</speed>
<hitTime>250</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4716" level="1" /> <!--Star Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="23" />
<height normal="31" />
</collision>
</npc>
<npc id="12528" level="55" type="L2Pet" name="Twilight Strider">
<!-- Confirmed CT2.5 -->
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="1673.05473" hpRegen="6.5" mp="889.8" mpRegen="2.4" />
<attack physical="388.11142" magical="265.02979" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="223.6362" magical="163.64727" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="170" />
</speed>
<hitTime>250</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
<skill id="4714" level="1" /> <!--Twilight Dragon -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="23" />
<height normal="31" />
</collision>
</npc>
<npc id="12564" level="15" type="L2Pet" name="Sin Eater">
<!-- Confirmed CT2.5 -->
<race>FAIRY</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="1" men="25">
<vitals hp="424.2" hpRegen="7.2513" mp="149.2" mpRegen="1.2" />
<attack physical="29.61691" magical="20.22451" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="73.55216" magical="53.82228" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="60" />
<run ground="125" />
</speed>
<hitTime>340</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="13" /> <!--Fairies -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="10" />
<height normal="24" />
</collision>
</npc>
</list>
@@ -1,43 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="12621" level="70" type="L2Pet" name="Wyvern">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="DDMagic" id="4289" level="1" /> <!-- Wyvern Breath -->
</parameters>
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="2444.46819" hpRegen="7.5" mp="1345.8" mpRegen="2.7" />
<attack physical="688.86373" magical="470.40463" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="295.91597" magical="216.53847" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="170" />
</speed>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="60" />
<height normal="80" />
</collision>
</npc>
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="12621" level="70" type="L2Pet" name="Wyvern">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="DDMagic" id="4289" level="1" /> <!-- Wyvern Breath -->
</parameters>
<race>DRAGON</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="2444.46819" hpRegen="7.5" mp="1345.8" mpRegen="2.7" />
<attack physical="688.86373" magical="470.40463" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="295.91597" magical="216.53847" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="80" />
<run ground="170" />
</speed>
</stats>
<status undying="false" />
<skillList>
<skill id="4121" level="1" /> <!--Summoned Monster Magic Protection -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="10" /> <!--Dragons -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="60" />
<height normal="80" />
</collision>
</npc>
</list>
@@ -1,349 +1,349 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="12774" level="1" type="L2Npc" name="Young Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="10" />
<height normal="10.5" />
</collision>
</npc>
<npc id="12775" level="1" type="L2Npc" name="High Quality Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="23" />
<height normal="25" />
</collision>
</npc>
<npc id="12776" level="1" type="L2Npc" name="Low Quality Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="15" />
<height normal="16" />
</collision>
</npc>
<npc id="12777" level="1" type="L2Npc" name="Large Young Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="23" />
<height normal="25" />
</collision>
</npc>
<npc id="12778" level="1" type="L2Npc" name="High Quality Large Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="34" />
<height normal="40" />
</collision>
</npc>
<npc id="12779" level="1" type="L2Npc" name="Low Quality Large Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="28" />
<height normal="31" />
</collision>
</npc>
<npc id="12780" level="25" type="L2BabyPet" name="Baby Buffalo">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="Heal1" id="4717" level="1" /> <!-- Heal Trick -->
<skill name="Heal2" id="4718" level="1" /> <!-- Greater Heal Trick -->
</parameters>
<race>BEAST</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="460.96247" hpRegen="3.5" mp="259.2" mpRegen="1.5" />
<attack physical="64.83203" magical="44.27187" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="101.83533" magical="74.51868" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="30" />
<run ground="120" />
</speed>
<hitTime>480</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="3" /> <!--Beasts -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="12" />
<height normal="15" />
</collision>
</npc>
<npc id="12781" level="25" type="L2BabyPet" name="Baby Kookaburra">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="Heal1" id="4717" level="1" /> <!-- Heal Trick -->
<skill name="Heal2" id="4718" level="1" /> <!-- Greater Heal Trick -->
</parameters>
<race>BEAST</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="460.96247" hpRegen="3.5" mp="259.2" mpRegen="1.5" />
<attack physical="64.83203" magical="44.27187" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="101.83533" magical="74.51868" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="13" />
<run ground="120" />
</speed>
<hitTime>500</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="3" /> <!--Beasts -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="7" />
<height normal="15" />
</collision>
</npc>
<npc id="12782" level="25" type="L2BabyPet" name="Baby Cougar">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="Heal1" id="4717" level="1" /> <!-- Heal Trick -->
<skill name="Heal2" id="4718" level="1" /> <!-- Greater Heal Trick -->
</parameters>
<race>BEAST</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="460.96247" hpRegen="3.5" mp="259.2" mpRegen="1.5" />
<attack physical="64.83203" magical="44.27187" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="101.83533" magical="74.51868" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="28" />
<run ground="120" />
</speed>
<hitTime>480</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="3" /> <!--Beasts -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="11" />
<height normal="15.7" />
</collision>
</npc>
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/npcs.xsd">
<npc id="12774" level="1" type="L2Npc" name="Young Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="10" />
<height normal="10.5" />
</collision>
</npc>
<npc id="12775" level="1" type="L2Npc" name="High Quality Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="23" />
<height normal="25" />
</collision>
</npc>
<npc id="12776" level="1" type="L2Npc" name="Low Quality Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="15" />
<height normal="16" />
</collision>
</npc>
<npc id="12777" level="1" type="L2Npc" name="Large Young Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="23" />
<height normal="25" />
</collision>
</npc>
<npc id="12778" level="1" type="L2Npc" name="High Quality Large Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="34" />
<height normal="40" />
</collision>
</npc>
<npc id="12779" level="1" type="L2Npc" name="Low Quality Large Squash">
<!-- Confirmed CT2.5 -->
<race>ETC</race>
<sex>ETC</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="10">
<vitals hp="39.74519" hpRegen="2" mp="40.0" mpRegen="0.9" />
<attack physical="8.47458" magical="5.78704" random="50" critical="1" accuracy="9" attackSpeed="253" type="BLUNT" range="40" distance="80" width="120" />
<defence physical="44.44444" magical="32.52252" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="50" />
<run ground="100" />
</speed>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="3" /> <!--Light Armor Type -->
<skill id="4415" level="5" /> <!--Blunt Weapons -->
<skill id="4416" level="19" /> <!--Others -->
<skill id="4441" level="5" /> <!--Greater Resist Mental Derangement -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai type="BALANCED" aggroRange="1000" />
<collision>
<radius normal="28" />
<height normal="31" />
</collision>
</npc>
<npc id="12780" level="25" type="L2BabyPet" name="Baby Buffalo">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="Heal1" id="4717" level="1" /> <!-- Heal Trick -->
<skill name="Heal2" id="4718" level="1" /> <!-- Greater Heal Trick -->
</parameters>
<race>BEAST</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="460.96247" hpRegen="3.5" mp="259.2" mpRegen="1.5" />
<attack physical="64.83203" magical="44.27187" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="101.83533" magical="74.51868" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="30" />
<run ground="120" />
</speed>
<hitTime>480</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="3" /> <!--Beasts -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="12" />
<height normal="15" />
</collision>
</npc>
<npc id="12781" level="25" type="L2BabyPet" name="Baby Kookaburra">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="Heal1" id="4717" level="1" /> <!-- Heal Trick -->
<skill name="Heal2" id="4718" level="1" /> <!-- Greater Heal Trick -->
</parameters>
<race>BEAST</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="460.96247" hpRegen="3.5" mp="259.2" mpRegen="1.5" />
<attack physical="64.83203" magical="44.27187" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="101.83533" magical="74.51868" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="13" />
<run ground="120" />
</speed>
<hitTime>500</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="3" /> <!--Beasts -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="7" />
<height normal="15" />
</collision>
</npc>
<npc id="12782" level="25" type="L2BabyPet" name="Baby Cougar">
<!-- Confirmed CT2.5 -->
<parameters>
<skill name="Heal1" id="4717" level="1" /> <!-- Heal Trick -->
<skill name="Heal2" id="4718" level="1" /> <!-- Greater Heal Trick -->
</parameters>
<race>BEAST</race>
<sex>MALE</sex>
<stats str="40" int="21" dex="30" wit="20" con="43" men="25">
<vitals hp="460.96247" hpRegen="3.5" mp="259.2" mpRegen="1.5" />
<attack physical="64.83203" magical="44.27187" random="10" critical="4" accuracy="4.75" attackSpeed="253" type="FIST" range="40" distance="80" width="120" />
<defence physical="101.83533" magical="74.51868" />
<attribute>
<defence fire="20" water="20" wind="20" earth="20" holy="20" dark="20" />
</attribute>
<speed>
<walk ground="28" />
<run ground="120" />
</speed>
<hitTime>480</hitTime>
</stats>
<status undying="false" />
<skillList>
<skill id="4045" level="1" /> <!--Resist Full Magic Attack -->
<skill id="4408" level="1" /> <!--HP Increase (1x) -->
<skill id="4409" level="1" /> <!--MP Increase (1x) -->
<skill id="4410" level="11" /> <!--Average P. Atk. -->
<skill id="4411" level="11" /> <!--Average M. Atk. -->
<skill id="4412" level="11" /> <!--Average P. Def. -->
<skill id="4413" level="11" /> <!--Average M. Def. -->
<skill id="4414" level="2" /> <!--Standard Type -->
<skill id="4415" level="1" /> <!--Bare Hands -->
<skill id="4416" level="3" /> <!--Beasts -->
</skillList>
<shots soul="2" spirit="2" />
<corpseTime>86400</corpseTime>
<exCrtEffect>false</exCrtEffect>
<collision>
<radius normal="11" />
<height normal="15.7" />
</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
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
@@ -44,7 +44,7 @@
</skillList>
<ai type="BALANCED" clanHelpRange="300" />
<dropLists>
<death>
<drop>
<item id="223" min="1" max="1" chance="1.975622141" /> <!-- Kukuri -->
<item id="238" min="1" max="1" chance="1.975622141" /> <!-- Dagger of Mana -->
<item id="239" min="1" max="1" chance="1.975622141" /> <!-- Mystic Knife -->
@@ -57,7 +57,7 @@
<item id="1939" min="28" max="84" chance="46.0776635407" /> <!-- Mithril Banded Gaiters Material -->
<item id="2028" min="27" max="81" chance="6.4637854247" /> <!-- Shilen Knife Edge -->
<item id="22229" min="1" max="1" chance="12.6939" /> <!-- Scroll: Enchant Weapon of Destruction (D-Grade) - Event -->
</death>
</drop>
</dropLists>
<collision>
<radius normal="13" />
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
+2 -10
View File
@@ -85,22 +85,14 @@
<xs:complexType name="dropListsType">
<xs:all>
<xs:element name="death" type="dropList" minOccurs="0" maxOccurs="1" />
<xs:element name="corpse" type="dropList" minOccurs="0" maxOccurs="1" />
<xs:element name="drop" type="dropList" minOccurs="0" maxOccurs="1" />
<xs:element name="spoil" type="dropList" minOccurs="0" maxOccurs="1" />
</xs:all>
</xs:complexType>
<xs:complexType name="dropList">
<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:element name="item" type="dropListItem" />
<xs:element name="group">
<xs:complexType>
<xs:sequence>
<xs:element name="item" type="dropListItem" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="chance" type="xs:decimal" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
@@ -781,7 +781,6 @@ public final class Config
public static int L2JMOD_DUALBOX_CHECK_MAX_L2EVENT_PARTICIPANTS_PER_IP;
public static Map<Integer, Integer> L2JMOD_DUALBOX_CHECK_WHITELIST;
public static boolean L2JMOD_ALLOW_CHANGE_PASSWORD;
public static boolean L2JMOD_OLD_DROP_BEHAVIOR;
public static boolean CUSTOM_STARTING_LOC;
public static int CUSTOM_STARTING_LOC_X;
public static int CUSTOM_STARTING_LOC_Y;
@@ -905,11 +904,11 @@ public final class Config
public static float RATE_QUEST_REWARD_RECIPE;
public static float RATE_QUEST_REWARD_MATERIAL;
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_RAID_DROP_AMOUNT_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_RAID_DROP_CHANCE_MULTIPLIER;
public static Map<Integer, Float> RATE_DROP_AMOUNT_BY_ID;
@@ -2101,14 +2100,6 @@ public final class Config
PET_HP_REGEN_MULTIPLIER = NPC.getDouble("PetHpRegenMultiplier", 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);
// Load Rates L2Properties file (if exists)
final PropertiesParser RatesSettings = new PropertiesParser(RATES_CONFIG_FILE);
@@ -2161,11 +2152,11 @@ public final class Config
KARMA_RATE_DROP_EQUIP_WEAPON = RatesSettings.getInt("KarmaRateDropEquipWeapon", 10);
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_RAID_DROP_AMOUNT_MULTIPLIER = RatesSettings.getFloat("RaidDropAmountMultiplier", 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_RAID_DROP_CHANCE_MULTIPLIER = RatesSettings.getFloat("RaidDropChanceMultiplier", 1);
@@ -2225,6 +2216,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 Custom L2Properties file (if exists)
final PropertiesParser CustomSettings = new PropertiesParser(CUSTOM_CONFIG_FILE);
@@ -2272,8 +2270,6 @@ public final class Config
L2JMOD_ENABLE_WAREHOUSESORTING_CLAN = CustomSettings.getBoolean("EnableWarehouseSortingClan", false);
L2JMOD_ENABLE_WAREHOUSESORTING_PRIVATE = CustomSettings.getBoolean("EnableWarehouseSortingPrivate", false);
L2JMOD_OLD_DROP_BEHAVIOR = CustomSettings.getBoolean("OldDropBehavior", false);
if (TVT_EVENT_PARTICIPATION_NPC_ID == 0)
{
TVT_EVENT_ENABLED = false;
@@ -34,16 +34,15 @@ import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.datatables.SkillData;
import com.l2jmobius.gameserver.enums.AISkillScope;
import com.l2jmobius.gameserver.enums.DropType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
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.holders.DropHolder;
import com.l2jmobius.gameserver.model.holders.MinionHolder;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.model.skills.Skill;
@@ -102,7 +101,7 @@ public class NpcData implements IXmlReader
Map<Integer, Skill> skills = null;
Set<Integer> clans = null;
Set<Integer> ignoreClanNpcIds = null;
Map<DropListScope, List<IDropItem>> dropLists = null;
List<DropHolder> dropLists = null;
set.set("id", npcId);
set.set("displayId", parseInteger(attrs, "displayId"));
set.set("level", parseByte(attrs, "level"));
@@ -443,28 +442,41 @@ public class NpcData implements IXmlReader
}
case "droplists":
{
for (Node dropListsNode = npcNode.getFirstChild(); dropListsNode != null; dropListsNode = dropListsNode.getNextSibling())
for (Node drop_lists_node = npcNode.getFirstChild(); drop_lists_node != null; drop_lists_node = drop_lists_node.getNextSibling())
{
DropListScope dropListScope = null;
DropType dropType = null;
try
{
dropListScope = Enum.valueOf(DropListScope.class, dropListsNode.getNodeName().toUpperCase());
dropType = Enum.valueOf(DropType.class, drop_lists_node.getNodeName().toUpperCase());
}
catch (Exception e)
{
}
if (dropListScope != null)
if (dropType != null)
{
if (dropLists == null)
{
dropLists = new EnumMap<>(DropListScope.class);
dropLists = new ArrayList<>();
}
final List<IDropItem> dropList = new ArrayList<>();
parseDropList(f, dropListsNode, dropListScope, dropList);
dropLists.put(dropListScope, Collections.unmodifiableList(dropList));
for (Node drop_node = drop_lists_node.getFirstChild(); drop_node != null; drop_node = drop_node.getNextSibling())
{
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;
@@ -628,67 +640,27 @@ public class NpcData implements IXmlReader
template.setClans(clans);
template.setIgnoreClanNpcIds(ignoreClanNpcIds);
template.setDropLists(dropLists);
}
}
}
}
}
private void parseDropList(File f, Node dropListNode, DropListScope dropListScope, List<IDropItem> drops)
{
for (Node dropNode = dropListNode.getFirstChild(); dropNode != null; dropNode = dropNode.getNextSibling())
{
switch (dropNode.getNodeName().toLowerCase())
{
case "group":
{
final GroupedGeneralDropItem dropItem = dropListScope.newGroupedDropItem(parseDouble(dropNode.getAttributes(), "chance"));
final List<IDropItem> groupedDropList = new ArrayList<>(2);
for (Node groupNode = dropNode.getFirstChild(); groupNode != null; groupNode = groupNode.getNextSibling())
{
parseDropListItem(groupNode, dropListScope, groupedDropList);
}
final List<GeneralDropItem> items = new ArrayList<>(groupedDropList.size());
for (IDropItem item : groupedDropList)
{
if (item instanceof GeneralDropItem)
if (dropLists != null)
{
items.add((GeneralDropItem) item);
}
else
{
LOGGER.warning("[" + f + "] grouped general drop item supports only general drop item.");
for (DropHolder dropHolder : dropLists)
{
switch (dropHolder.getDropType())
{
case DROP:
{
template.addDrop(dropHolder);
break;
}
case SPOIL:
{
template.addSpoil(dropHolder);
break;
}
}
}
}
}
dropItem.setItems(items);
drops.add(dropItem);
break;
}
default:
{
parseDropListItem(dropNode, dropListScope, drops);
break;
}
}
}
}
private void parseDropListItem(Node dropListItem, DropListScope dropListScope, List<IDropItem> drops)
{
final NamedNodeMap attrs = dropListItem.getAttributes();
switch (dropListItem.getNodeName().toLowerCase())
{
case "item":
{
final IDropItem dropItem = dropListScope.newDropItem(parseInteger(attrs, "id"), parseLong(attrs, "min"), parseLong(attrs, "max"), parseDouble(attrs, "chance"));
if (dropItem != null)
{
drops.add(dropItem);
}
break;
}
}
}
@@ -14,30 +14,13 @@
* 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;
package com.l2jmobius.gameserver.enums;
/**
* @author NosBit
* @author Mobius
*/
public class GroupedDeathDropItem extends GroupedGeneralDropItem
public enum DropType
{
/**
* @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;
}
DROP,
SPOIL;
}
@@ -37,6 +37,7 @@ import com.l2jmobius.gameserver.datatables.EventDroplist;
import com.l2jmobius.gameserver.datatables.EventDroplist.DateDrop;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.enums.DropType;
import com.l2jmobius.gameserver.enums.InstanceType;
import com.l2jmobius.gameserver.enums.Team;
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
@@ -56,7 +57,6 @@ import com.l2jmobius.gameserver.model.actor.knownlist.AttackableKnownList;
import com.l2jmobius.gameserver.model.actor.status.AttackableStatus;
import com.l2jmobius.gameserver.model.actor.tasks.attackable.CommandChannelTimer;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.drops.DropListScope;
import com.l2jmobius.gameserver.model.events.EventDispatcher;
import com.l2jmobius.gameserver.model.events.impl.character.npc.attackable.OnAttackableAggroRangeEnter;
import com.l2jmobius.gameserver.model.events.impl.character.npc.attackable.OnAttackableAttack;
@@ -961,10 +961,10 @@ public class L2Attackable extends L2Npc
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)
{
for (ItemHolder drop : deathItems)
@@ -19,25 +19,29 @@ package com.l2jmobius.gameserver.model.actor.templates;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.l2jmobius.Config;
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.AIType;
import com.l2jmobius.gameserver.enums.DropType;
import com.l2jmobius.gameserver.enums.Race;
import com.l2jmobius.gameserver.enums.Sex;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.drops.DropListScope;
import com.l2jmobius.gameserver.model.drops.IDropItem;
import com.l2jmobius.gameserver.model.holders.DropHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
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.util.Util;
import com.l2jmobius.util.Rnd;
/**
* NPC template.
@@ -90,7 +94,8 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
private Map<AISkillScope, List<Skill>> _aiSkillLists;
private Set<Integer> _clans;
private Set<Integer> _ignoreClanNpcIds;
private Map<DropListScope, List<IDropItem>> _dropLists;
private List<DropHolder> _dropListDeath;
private List<DropHolder> _dropListSpoil;
private double _collisionRadiusGrown;
private double _collisionHeightGrown;
@@ -504,49 +509,220 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
_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:
{
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)
{
return null;
}
final int levelDifference = victim.getLevel() - killer.getLevel();
Collection<ItemHolder> calculatedDrops = null;
for (IDropItem dropItem : dropList)
for (DropHolder dropItem : dropList)
{
final Collection<ItemHolder> drops = dropItem.calculateDrops(victim, killer);
if ((drops == null) || drops.isEmpty())
// check level gap that may prevent drop this item
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;
}
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;
}
/**
* 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:
{
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()
{
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,300 +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.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2ChestInstance;
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;
import com.l2jmobius.util.Rnd;
/**
* @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)
{
// Treasure chests x1
if (victim instanceof L2ChestInstance)
{
return 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.L2JMOD_CHAMPION_REWARDS_AMOUNT : Config.L2JMOD_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)
{
// Treasure chests x1
if (victim instanceof L2ChestInstance)
{
return getChance();
}
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.L2JMOD_CHAMPION_REWARDS_CHANCE : Config.L2JMOD_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.L2JMOD_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,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.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;
import com.l2jmobius.util.Rnd;
/**
* @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.L2JMOD_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;
}
}
@@ -1,36 +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.Collection;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
/**
* @author NosBit
*/
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);
}
@@ -37,7 +37,7 @@ import com.l2jmobius.gameserver.datatables.EventDroplist;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.Location;
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.model.quest.Quest;
import com.l2jmobius.gameserver.script.DateRange;
import com.l2jmobius.gameserver.util.Broadcast;
@@ -62,7 +62,7 @@ public class LongTimeEvent extends Quest
private final List<NpcSpawn> _spawnList = new ArrayList<>();
// Drop data for event
private final List<GeneralDropItem> _dropList = new ArrayList<>();
private final List<DropHolder> _dropList = new ArrayList<>();
private class NpcSpawn
{
@@ -180,7 +180,7 @@ public class LongTimeEvent extends Quest
continue;
}
_dropList.add(new GeneralDropItem(itemId, minCount, maxCount, finalChance));
_dropList.add(new DropHolder(null, itemId, minCount, maxCount, finalChance));
}
catch (NumberFormatException nfe)
{
@@ -260,7 +260,7 @@ public class LongTimeEvent extends Quest
// Add drop
if ((_dropList != null) && (currentTime < _dropPeriod.getEndDate().getTime()))
{
for (GeneralDropItem drop : _dropList)
for (DropHolder drop : _dropList)
{
EventDroplist.getInstance().addGlobalDrop(drop.getItemId(), drop.getMin(), drop.getMax(), (int) drop.getChance(), _dropPeriod);
}
@@ -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;
}
}
+3
View File
@@ -21,3 +21,6 @@ What is done
-Custom community board
-Premium System
-User command expon/expoff
-Reworked drop system
-GeoEngine from aCis
-Threadpool manager from aCis