Multisell, augment and tax zone rework.
Adapted from: L2jUnity free files.
This commit is contained in:
@@ -508,10 +508,6 @@ AltGameCreationSpRate = 1
|
||||
# Default: 2
|
||||
AltGameCreationRareXpSpRate = 2
|
||||
|
||||
# If set to False, blacksmiths don't take recipes from players inventory when crafting.
|
||||
# Default: True
|
||||
AltBlacksmithUseRecipes = True
|
||||
|
||||
# Store/Restore Dwarven Manufacture list
|
||||
# Keep manufacture shoplist after relog
|
||||
# Default: False
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<tr><td><table width=270 border=0 bgcolor=131210><tr><td width=100><font color="LEVEL">Peace:</font></td><td align=right width=170>%PEACE%</td></tr></table></td></tr>
|
||||
<tr><td><table width=270 border=0><tr><td width=100><font color="LEVEL">Pvp:</font></td><td align=right width=170>%PVP%</td></tr></table></td></tr>
|
||||
<tr><td><table width=270 border=0 bgcolor=131210><tr><td width=100><font color="LEVEL">Siege:</font></td><td align=right width=170>%SIEGE%</td></tr></table></td></tr>
|
||||
<tr><td><table width=270 border=0><tr><td width=100><font color="LEVEL">Town:</font></td><td align=right width=170>%TOWN%</td></tr></table></td></tr>
|
||||
<tr><td><table width=270 border=0><tr><td width=100><font color="LEVEL">Tax:</font></td><td align=right width=170>%TAX%</td></tr></table></td></tr>
|
||||
<tr><td><table width=270 border=0 bgcolor=131210><tr><td width=100><font color="LEVEL">Castle:</font></td><td align=right width=170>%CASTLE%</td></tr></table></td></tr>
|
||||
<tr><td><table width=270 border=0><tr><td width=100><font color="LEVEL">Fort:</font></td><td align=right width=170>%FORT%</td></tr></table></td></tr>
|
||||
<tr><td><table width=270 border=0 bgcolor=131210><tr><td width=100><font color="LEVEL">HQ:</font></td><td align=right width=170>%HQ%</td></tr></table></td></tr>
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<list applyTaxes="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/multisell.xsd">
|
||||
<npcs>
|
||||
<npc>30283</npc> <!-- Altran -->
|
||||
<npc>30307</npc> <!-- Karrod -->
|
||||
<npc>30317</npc> <!-- Kluto -->
|
||||
<npc>30363</npc> <!-- Aios -->
|
||||
<npc>30471</npc> <!-- Rupio -->
|
||||
<npc>30526</npc> <!-- Brunon -->
|
||||
<npc>30527</npc> <!-- Silvera -->
|
||||
<npc>30564</npc> <!-- Sumari -->
|
||||
<npc>30846</npc> <!-- Wilbert -->
|
||||
<npc>30678</npc> <!-- Helton -->
|
||||
<npc>30688</npc> <!-- Duning -->
|
||||
</npcs>
|
||||
<item>
|
||||
<!-- Recipe: Durable Braid -->
|
||||
<ingredient count="1" id="2135" maintainIngredient="true" />
|
||||
<!-- Stem -->
|
||||
<ingredient count="5" id="1864" />
|
||||
<!-- Durable Braid -->
|
||||
<production count="1" id="1878" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Cokes -->
|
||||
<ingredient count="1" id="2136" maintainIngredient="true" />
|
||||
<!-- Coal -->
|
||||
<ingredient count="3" id="1870" />
|
||||
<!-- Charcoal -->
|
||||
<ingredient count="3" id="1871" />
|
||||
<!-- Cokes -->
|
||||
<production count="1" id="1879" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Steel -->
|
||||
<ingredient count="1" id="2137" maintainIngredient="true" />
|
||||
<!-- Varnish -->
|
||||
<ingredient count="5" id="1865" />
|
||||
<!-- Iron Ore -->
|
||||
<ingredient count="5" id="1869" />
|
||||
<!-- Steel -->
|
||||
<production count="1" id="1880" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Coarse Bone Powder (100%) -->
|
||||
<ingredient count="1" id="2138" maintainIngredient="true" />
|
||||
<!-- Animal Bone -->
|
||||
<ingredient count="10" id="1872" />
|
||||
<!-- Coarse Bone Powder -->
|
||||
<production count="1" id="1881" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Leather -->
|
||||
<ingredient count="1" id="1814" maintainIngredient="true" />
|
||||
<!-- Animal Skin -->
|
||||
<ingredient count="6" id="1867" />
|
||||
<!-- Leather -->
|
||||
<production count="1" id="1882" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Steel Mold -->
|
||||
<ingredient count="1" id="2139" maintainIngredient="true" />
|
||||
<!-- Durable Braid -->
|
||||
<ingredient count="5" id="1878" />
|
||||
<!-- Iron Ore -->
|
||||
<ingredient count="5" id="1869" />
|
||||
<!-- Coal -->
|
||||
<ingredient count="5" id="1870" />
|
||||
<!-- Steel Mold -->
|
||||
<production count="1" id="1883" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Cord -->
|
||||
<ingredient count="1" id="1817" maintainIngredient="true" />
|
||||
<!-- Steel -->
|
||||
<ingredient count="2" id="1880" />
|
||||
<!-- Thread -->
|
||||
<ingredient count="25" id="1868" />
|
||||
<!-- Cord -->
|
||||
<production count="20" id="1884" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: High-Grade Suede -->
|
||||
<ingredient count="1" id="2140" maintainIngredient="true" />
|
||||
<!-- Coarse Bone Powder -->
|
||||
<ingredient count="1" id="1881" />
|
||||
<!-- Suede -->
|
||||
<ingredient count="3" id="1866" />
|
||||
<!-- High-Grade Suede -->
|
||||
<production count="1" id="1885" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Silver Mold -->
|
||||
<ingredient count="1" id="2141" maintainIngredient="true" />
|
||||
<!-- Braided Hemp -->
|
||||
<ingredient count="5" id="1878" />
|
||||
<!-- Cokes -->
|
||||
<ingredient count="5" id="1879" />
|
||||
<!-- Silver Nugget -->
|
||||
<ingredient count="10" id="1873" />
|
||||
<!-- Silver Mold -->
|
||||
<production count="1" id="1886" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Varnish of Purity -->
|
||||
<ingredient count="1" id="2142" maintainIngredient="true" />
|
||||
<!-- Coarse Bone Powder -->
|
||||
<ingredient count="3" id="1881" />
|
||||
<!-- Varnish -->
|
||||
<ingredient count="3" id="1865" />
|
||||
<!-- Stone of Purity -->
|
||||
<ingredient count="1" id="1875" />
|
||||
<!-- Varnish of Purity -->
|
||||
<production count="1" id="1887" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Synthetic Cokes -->
|
||||
<ingredient count="1" id="2143" maintainIngredient="true" />
|
||||
<!-- Cokes -->
|
||||
<ingredient count="3" id="1879" />
|
||||
<!-- Oriharukon Ore -->
|
||||
<ingredient count="1" id="1874" />
|
||||
<!-- Synthetic Cokes -->
|
||||
<production count="1" id="1888" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Synthetic Braid -->
|
||||
<ingredient count="1" id="2144" maintainIngredient="true" />
|
||||
<!-- Durable Braid -->
|
||||
<ingredient count="5" id="1878" />
|
||||
<!-- Thread -->
|
||||
<ingredient count="5" id="1868" />
|
||||
<!-- Synthetic Braid -->
|
||||
<production count="1" id="1889" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Mithril Alloy -->
|
||||
<ingredient count="1" id="2145" maintainIngredient="true" />
|
||||
<!-- Varnish of Purity -->
|
||||
<ingredient count="1" id="1887" />
|
||||
<!-- Steel -->
|
||||
<ingredient count="2" id="1880" />
|
||||
<!-- Mithril Ore -->
|
||||
<ingredient count="1" id="1876" />
|
||||
<!-- Mithril Alloy -->
|
||||
<production count="1" id="1890" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Artisan's frame -->
|
||||
<ingredient count="1" id="2146" maintainIngredient="true" />
|
||||
<!-- Steel Mold -->
|
||||
<ingredient count="1" id="1883" />
|
||||
<!-- Varnish of Purity -->
|
||||
<ingredient count="5" id="1887" />
|
||||
<!-- Adamantite Nugget -->
|
||||
<ingredient count="10" id="1877" />
|
||||
<!-- Artisan's Frame -->
|
||||
<production count="1" id="1891" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Blacksmith's frame -->
|
||||
<ingredient count="1" id="2147" maintainIngredient="true" />
|
||||
<!-- Silver Mold -->
|
||||
<ingredient count="1" id="1886" />
|
||||
<!-- Varnish of Purity -->
|
||||
<ingredient count="5" id="1887" />
|
||||
<!-- Mithril Ore -->
|
||||
<ingredient count="10" id="1876" />
|
||||
<!-- Blacksmith's Frame -->
|
||||
<production count="1" id="1892" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Oriharukon -->
|
||||
<ingredient count="1" id="1825" maintainIngredient="true" />
|
||||
<!-- Synthetic Cokes -->
|
||||
<ingredient count="1" id="1888" />
|
||||
<!-- Silver Nugget -->
|
||||
<ingredient count="12" id="1873" />
|
||||
<!-- Oriharukon Ore -->
|
||||
<ingredient count="4" id="1874" />
|
||||
<!-- Oriharukon -->
|
||||
<production count="1" id="1893" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Crafted Leather -->
|
||||
<ingredient count="1" id="2148" maintainIngredient="true" />
|
||||
<!-- Cord -->
|
||||
<ingredient count="4" id="1884" />
|
||||
<!-- Leather -->
|
||||
<ingredient count="4" id="1882" />
|
||||
<!-- Coal -->
|
||||
<ingredient count="4" id="1870" />
|
||||
<!-- Crafted Leather -->
|
||||
<production count="1" id="1894" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Metallic Fiber -->
|
||||
<ingredient count="1" id="2149" maintainIngredient="true" />
|
||||
<!-- Cord -->
|
||||
<ingredient count="20" id="1884" />
|
||||
<!-- Silver Nugget -->
|
||||
<ingredient count="15" id="1873" />
|
||||
<!-- Metallic Fiber -->
|
||||
<production count="20" id="1895" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Recipe: Metal Hardener (100%) -->
|
||||
<ingredient count="1" id="5231" maintainIngredient="true" />
|
||||
<!-- Stem -->
|
||||
<ingredient count="10" id="1864" />
|
||||
<!-- Varnish -->
|
||||
<ingredient count="10" id="1865" />
|
||||
<!-- Iron Ore -->
|
||||
<ingredient count="10" id="1869" />
|
||||
<!-- Metal Hardener -->
|
||||
<production count="1" id="5220" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Cord -->
|
||||
<ingredient count="40" id="1884" />
|
||||
<!-- Reinforced Metal Plate -->
|
||||
<ingredient count="10" id="5550" />
|
||||
<!-- Adamantite Nugget -->
|
||||
<ingredient count="15" id="1877" />
|
||||
<!-- Reorin's Mold -->
|
||||
<production count="1" id="5551" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Artisan's Frame -->
|
||||
<ingredient count="1" id="1891" />
|
||||
<!-- Mold Hardener -->
|
||||
<ingredient count="10" id="4041" />
|
||||
<!-- Enria -->
|
||||
<ingredient count="5" id="4042" />
|
||||
<!-- Warsmith Mold -->
|
||||
<production count="1" id="5552" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Maestro Anvil Lock -->
|
||||
<ingredient count="3" id="4046" />
|
||||
<!-- Mold Lubricant -->
|
||||
<ingredient count="20" id="4040" />
|
||||
<!-- Thons -->
|
||||
<ingredient count="10" id="4044" />
|
||||
<!-- Arcsmith Anvil -->
|
||||
<production count="1" id="5553" />
|
||||
</item>
|
||||
<item>
|
||||
<!-- Maestro Holder -->
|
||||
<ingredient count="2" id="4045" />
|
||||
<!-- Mold Glue -->
|
||||
<ingredient count="10" id="4039" />
|
||||
<!-- Thread -->
|
||||
<ingredient count="10" id="1868" />
|
||||
<!-- Warsmith'Holder -->
|
||||
<production count="1" id="5554" />
|
||||
</item>
|
||||
</list>
|
||||
@@ -7,9 +7,11 @@
|
||||
<!-- Adena -->
|
||||
<ingredient count="250000" id="57" />
|
||||
<!-- Ring of Seal -->
|
||||
<production count="2" id="886" />
|
||||
<production count="1" id="886" />
|
||||
<production count="1" id="886" />
|
||||
<!-- Earring of Seal -->
|
||||
<production count="2" id="854" />
|
||||
<production count="1" id="854" />
|
||||
<production count="1" id="854" />
|
||||
<!-- Necklace of Seal -->
|
||||
<production count="1" id="119" />
|
||||
</item>
|
||||
|
||||
@@ -162,7 +162,7 @@ public class AdminElement implements IAdminCommandHandler
|
||||
}
|
||||
else
|
||||
{
|
||||
itemInstance.setAttribute(new AttributeHolder(type, value));
|
||||
itemInstance.setAttribute(new AttributeHolder(type, value), true);
|
||||
}
|
||||
player.getInventory().equipItem(itemInstance);
|
||||
|
||||
|
||||
@@ -19,9 +19,10 @@ package handlers.admincommandhandlers;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.MultisellData;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.buylist.ProductList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.BuyList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExBuySellList;
|
||||
@@ -40,7 +41,9 @@ public class AdminShop implements IAdminCommandHandler
|
||||
private static final String[] ADMIN_COMMANDS =
|
||||
{
|
||||
"admin_buy",
|
||||
"admin_gmshop"
|
||||
"admin_gmshop",
|
||||
"admin_multisell",
|
||||
"admin_exc_multisell"
|
||||
};
|
||||
|
||||
@Override
|
||||
@@ -61,6 +64,30 @@ public class AdminShop implements IAdminCommandHandler
|
||||
{
|
||||
AdminHtml.showAdminHtml(activeChar, "gmshops.htm");
|
||||
}
|
||||
else if (command.startsWith("admin_multisell"))
|
||||
{
|
||||
try
|
||||
{
|
||||
int listId = Integer.parseInt(command.substring(16).trim());
|
||||
MultisellData.getInstance().separateAndSend(listId, activeChar, null, false);
|
||||
}
|
||||
catch (NumberFormatException | IndexOutOfBoundsException e)
|
||||
{
|
||||
activeChar.sendMessage("Please specify multisell list ID.");
|
||||
}
|
||||
}
|
||||
else if (command.toLowerCase().startsWith("admin_exc_multisell"))
|
||||
{
|
||||
try
|
||||
{
|
||||
int listId = Integer.parseInt(command.substring(20).trim());
|
||||
MultisellData.getInstance().separateAndSend(listId, activeChar, null, true);
|
||||
}
|
||||
catch (NumberFormatException | IndexOutOfBoundsException e)
|
||||
{
|
||||
activeChar.sendMessage("Please specify multisell list ID.");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -82,17 +109,16 @@ public class AdminShop implements IAdminCommandHandler
|
||||
_log.warning("admin buylist failed:" + command);
|
||||
}
|
||||
|
||||
final L2BuyList buyList = BuyListData.getInstance().getBuyList(val);
|
||||
|
||||
final ProductList buyList = BuyListData.getInstance().getBuyList(val);
|
||||
if (buyList != null)
|
||||
{
|
||||
activeChar.sendPacket(new BuyList(buyList, activeChar.getAdena(), 0));
|
||||
activeChar.sendPacket(new BuyList(buyList, activeChar, 0));
|
||||
activeChar.sendPacket(new ExBuySellList(activeChar, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("no buylist with id:" + val);
|
||||
activeChar.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
activeChar.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,6 @@ public class AdminZone implements IAdminCommandHandler
|
||||
adminReply.replace("%PEACE%", activeChar.isInsideZone(ZoneId.PEACE) ? "<font color=\"LEVEL\">YES</font>" : "NO");
|
||||
adminReply.replace("%PVP%", activeChar.isInsideZone(ZoneId.PVP) ? "<font color=\"LEVEL\">YES</font>" : "NO");
|
||||
adminReply.replace("%SIEGE%", activeChar.isInsideZone(ZoneId.SIEGE) ? "<font color=\"LEVEL\">YES</font>" : "NO");
|
||||
adminReply.replace("%TOWN%", activeChar.isInsideZone(ZoneId.TOWN) ? "<font color=\"LEVEL\">YES</font>" : "NO");
|
||||
adminReply.replace("%CASTLE%", activeChar.isInsideZone(ZoneId.CASTLE) ? "<font color=\"LEVEL\">YES</font>" : "NO");
|
||||
adminReply.replace("%FORT%", activeChar.isInsideZone(ZoneId.FORT) ? "<font color=\"LEVEL\">YES</font>" : "NO");
|
||||
adminReply.replace("%HQ%", activeChar.isInsideZone(ZoneId.HQ) ? "<font color=\"LEVEL\">YES</font>" : "NO");
|
||||
@@ -128,6 +127,7 @@ public class AdminZone implements IAdminCommandHandler
|
||||
adminReply.replace("%DANGER%", activeChar.isInsideZone(ZoneId.DANGER_AREA) ? "<font color=\"LEVEL\">YES</font>" : "NO");
|
||||
adminReply.replace("%NOSTORE%", activeChar.isInsideZone(ZoneId.NO_STORE) ? "<font color=\"LEVEL\">YES</font>" : "NO");
|
||||
adminReply.replace("%SCRIPT%", activeChar.isInsideZone(ZoneId.SCRIPT) ? "<font color=\"LEVEL\">YES</font>" : "NO");
|
||||
adminReply.replace("%TAX%", (activeChar.isInsideZone(ZoneId.TAX) ? "<font color=\"LEVEL\">YES</font>" : "NO"));
|
||||
|
||||
final StringBuilder zones = new StringBuilder(100);
|
||||
for (L2ZoneType zone : ZoneManager.getInstance().getZones(activeChar))
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
|
||||
import com.l2jmobius.gameserver.handler.IBypassHandler;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.buylist.ProductList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ShopPreviewList;
|
||||
|
||||
@@ -70,7 +70,7 @@ public class Wear implements IBypassHandler
|
||||
|
||||
private static void showWearWindow(L2PcInstance player, int val)
|
||||
{
|
||||
final L2BuyList buyList = BuyListData.getInstance().getBuyList(val);
|
||||
final ProductList buyList = BuyListData.getInstance().getBuyList(val);
|
||||
if (buyList == null)
|
||||
{
|
||||
_log.warning("BuyList not found! BuyListId:" + val);
|
||||
|
||||
@@ -154,7 +154,7 @@ public final class HomeBoard implements IParseBoardHandler
|
||||
{
|
||||
final String page = command.replace("_bbssell;", "");
|
||||
returnHtml = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/CommunityBoard/Custom/" + page + ".html");
|
||||
activeChar.sendPacket(new BuyList(BuyListData.getInstance().getBuyList(423), activeChar.getAdena(), 0));
|
||||
activeChar.sendPacket(new BuyList(BuyListData.getInstance().getBuyList(423), activeChar, 0));
|
||||
activeChar.sendPacket(new ExBuySellList(activeChar, false));
|
||||
}
|
||||
else if (command.startsWith("_bbsteleport"))
|
||||
|
||||
@@ -18,6 +18,7 @@ package handlers.communityboard;
|
||||
|
||||
import com.l2jmobius.gameserver.cache.HtmCache;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
|
||||
import com.l2jmobius.gameserver.enums.TaxType;
|
||||
import com.l2jmobius.gameserver.handler.CommunityBoardHandler;
|
||||
import com.l2jmobius.gameserver.handler.IWriteBoardHandler;
|
||||
import com.l2jmobius.gameserver.instancemanager.CastleManager;
|
||||
@@ -64,7 +65,7 @@ public class RegionBoard implements IWriteBoardHandler
|
||||
link = link.replace("%region_name%", String.valueOf(REGIONS[i]));
|
||||
link = link.replace("%region_owning_clan%", (clan != null ? clan.getName() : "NPC"));
|
||||
link = link.replace("%region_owning_clan_alliance%", ((clan != null) && (clan.getAllyName() != null) ? clan.getAllyName() : ""));
|
||||
link = link.replace("%region_tax_rate%", (castle.getTaxRate() * 100) + "%");
|
||||
link = link.replace("%region_tax_rate%", castle.getTaxPercent(TaxType.BUY) + "%");
|
||||
sb.append(link);
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ public final class ConvertItem extends AbstractEffect
|
||||
|
||||
if (elementals != null)
|
||||
{
|
||||
newItem.setAttribute(elementals);
|
||||
newItem.setAttribute(elementals, true);
|
||||
}
|
||||
newItem.setEnchantLevel(enchantLevel);
|
||||
player.getInventory().equipItem(newItem);
|
||||
|
||||
@@ -22,13 +22,13 @@ import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.enums.ItemSkillType;
|
||||
import com.l2jmobius.gameserver.handler.IItemHandler;
|
||||
import com.l2jmobius.gameserver.instancemanager.CastleManorManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2Seed;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Playable;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2ChestInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemSkillHolder;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
@@ -81,7 +81,9 @@ public class Seed implements IItemHandler
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (seed.getCastleId() != MapRegionManager.getInstance().getAreaCastle(playable)) // TODO: replace me with tax zone
|
||||
|
||||
final Castle taxCastle = target.getTaxCastle();
|
||||
if ((taxCastle == null) || (seed.getCastleId() != taxCastle.getResidenceId()))
|
||||
{
|
||||
playable.sendPacket(SystemMessageId.THIS_SEED_MAY_NOT_BE_SOWN_HERE);
|
||||
return false;
|
||||
|
||||
@@ -29,9 +29,11 @@
|
||||
<xs:attribute name="price" type="xs:nonNegativeInteger" />
|
||||
<xs:attribute name="restock_delay" type="xs:positiveInteger" />
|
||||
<xs:attribute name="count" type="xs:positiveInteger" />
|
||||
<xs:attribute name="baseTax" type="xs:positiveInteger" use="optional" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="baseTax" type="xs:positiveInteger" use="optional" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -22,7 +22,6 @@
|
||||
<xs:attribute name="id" type="xs:integer" use="required" />
|
||||
<xs:attribute name="enchantmentLevel" type="xs:integer" />
|
||||
<xs:attribute name="count" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="maintainIngredient" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="production" minOccurs="1" maxOccurs="unbounded">
|
||||
@@ -40,7 +39,8 @@
|
||||
<xs:attribute name="isChanceMultisell" type="xs:boolean" use="optional" />
|
||||
<xs:attribute name="applyTaxes" type="xs:boolean" />
|
||||
<xs:attribute name="maintainEnchantment" type="xs:boolean" />
|
||||
<xs:attribute name="useRate" type="xs:token" />
|
||||
<xs:attribute name="ingredientMultiplier" type="xs:double" />
|
||||
<xs:attribute name="productMultiplier" type="xs:double" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -1,639 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<list enabled="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/zones.xsd">
|
||||
<!-- NOTE: Don't Remove IDs from Town zones due are used for "MerchantPriceConfig" to determine tax -->
|
||||
<!-- Town Zones -->
|
||||
<zone name="Giran Castle Town" id="11020" type="TownZone" shape="NPoly" minZ="-3800" maxZ="-3300">
|
||||
<stat name="townId" val="9" />
|
||||
<stat name="taxById" val="3" />
|
||||
<node X="77170" Y="147420" />
|
||||
<node X="79200" Y="147420" />
|
||||
<node X="79200" Y="144780" />
|
||||
<node X="80310" Y="144780" />
|
||||
<node X="80310" Y="143630" />
|
||||
<node X="83120" Y="143630" />
|
||||
<node X="83120" Y="143505" />
|
||||
<node X="83700" Y="143505" />
|
||||
<node X="83700" Y="141500" />
|
||||
<node X="84070" Y="141500" />
|
||||
<node X="84070" Y="143505" />
|
||||
<node X="85040" Y="143505" />
|
||||
<node X="85040" Y="145760" />
|
||||
<node X="86115" Y="145760" />
|
||||
<node X="86115" Y="146910" />
|
||||
<node X="88425" Y="146910" />
|
||||
<node X="88425" Y="147175" />
|
||||
<node X="90430" Y="147175" />
|
||||
<node X="90430" Y="147540" />
|
||||
<node X="88425" Y="147540" />
|
||||
<node X="88425" Y="150050" />
|
||||
<node X="86495" Y="150050" />
|
||||
<node X="86495" Y="150250" />
|
||||
<node X="85995" Y="150250" />
|
||||
<node X="85995" Y="152250" />
|
||||
<node X="86780" Y="152250" />
|
||||
<node X="86780" Y="153600" />
|
||||
<node X="84850" Y="153600" />
|
||||
<node X="84850" Y="152250" />
|
||||
<node X="85625" Y="152250" />
|
||||
<node X="85265" Y="150250" />
|
||||
<node X="85085" Y="150250" />
|
||||
<node X="85085" Y="149875" />
|
||||
<node X="83680" Y="149875" />
|
||||
<node X="83680" Y="149920" />
|
||||
<node X="83500" Y="149920" />
|
||||
<node X="83500" Y="151270" />
|
||||
<node X="82705" Y="151270" />
|
||||
<node X="82705" Y="152820" />
|
||||
<node X="79195" Y="152820" />
|
||||
<node X="79195" Y="149805" />
|
||||
<node X="77170" Y="149805" />
|
||||
</zone>
|
||||
<zone name="Dark Elven Village" id="11021" type="TownZone" shape="NPoly" minZ="-4700" maxZ="-3600">
|
||||
<stat name="townId" val="1" />
|
||||
<stat name="taxById" val="4" />
|
||||
<node X="15704" Y="15397" />
|
||||
<node X="15765" Y="15878" />
|
||||
<node X="15801" Y="16332" />
|
||||
<node X="14098" Y="19672" />
|
||||
<node X="10278" Y="20689" />
|
||||
<node X="8852" Y="20421" />
|
||||
<node X="7484" Y="18628" />
|
||||
<node X="7236" Y="18042" />
|
||||
<node X="7141" Y="17507" />
|
||||
<node X="7045" Y="16819" />
|
||||
<node X="7382" Y="14486" />
|
||||
<node X="13891" Y="13025" />
|
||||
<node X="15542" Y="15230" />
|
||||
</zone>
|
||||
<zone name="Talking Island" id="11022" type="TownZone" shape="NPoly" minZ="-3800" maxZ="-3700">
|
||||
<stat name="townId" val="2" />
|
||||
<stat name="taxById" val="1" />
|
||||
<node X="-83739" Y="245733" />
|
||||
<node X="-84049" Y="246087" />
|
||||
<node X="-84289" Y="246258" />
|
||||
<node X="-84556" Y="246243" />
|
||||
<node X="-84984" Y="245820" />
|
||||
<node X="-85336" Y="245426" />
|
||||
<node X="-85684" Y="245099" />
|
||||
<node X="-85969" Y="244770" />
|
||||
<node X="-86400" Y="244292" />
|
||||
<node X="-86664" Y="243997" />
|
||||
<node X="-86940" Y="243631" />
|
||||
<node X="-87517" Y="243034" />
|
||||
<node X="-87650" Y="242799" />
|
||||
<node X="-87613" Y="242572" />
|
||||
<node X="-87348" Y="242246" />
|
||||
<node X="-86956" Y="241942" />
|
||||
<node X="-86656" Y="241684" />
|
||||
<node X="-86343" Y="241365" />
|
||||
<node X="-85829" Y="240966" />
|
||||
<node X="-85544" Y="240765" />
|
||||
<node X="-85193" Y="240440" />
|
||||
<node X="-84865" Y="240185" />
|
||||
<node X="-84594" Y="239866" />
|
||||
<node X="-84284" Y="239666" />
|
||||
<node X="-84002" Y="239734" />
|
||||
<node X="-83822" Y="239922" />
|
||||
<node X="-83640" Y="240190" />
|
||||
<node X="-83295" Y="240492" />
|
||||
<node X="-82990" Y="240878" />
|
||||
<node X="-82635" Y="241208" />
|
||||
<node X="-82234" Y="241698" />
|
||||
<node X="-82027" Y="241985" />
|
||||
<node X="-81684" Y="242328" />
|
||||
<node X="-81421" Y="242741" />
|
||||
<node X="-81113" Y="243073" />
|
||||
<node X="-81011" Y="243228" />
|
||||
<node X="-81029" Y="243496" />
|
||||
<node X="-81340" Y="243797" />
|
||||
<node X="-81691" Y="244028" />
|
||||
<node X="-82292" Y="244585" />
|
||||
<node X="-82787" Y="244999" />
|
||||
<node X="-83726" Y="245721" />
|
||||
</zone>
|
||||
<zone name="Elven Village" id="11023" type="TownZone" shape="NPoly" minZ="-3600" maxZ="-2750">
|
||||
<stat name="townId" val="3" />
|
||||
<stat name="taxById" val="4" />
|
||||
<node X="45364" Y="46535" />
|
||||
<node X="45895" Y="46578" />
|
||||
<node X="46388" Y="46713" />
|
||||
<node X="46861" Y="46934" />
|
||||
<node X="47290" Y="47232" />
|
||||
<node X="47659" Y="47598" />
|
||||
<node X="47959" Y="48024" />
|
||||
<node X="48182" Y="48499" />
|
||||
<node X="48318" Y="49006" />
|
||||
<node X="48364" Y="49523" />
|
||||
<node X="48319" Y="50048" />
|
||||
<node X="48186" Y="50548" />
|
||||
<node X="47963" Y="51022" />
|
||||
<node X="47661" Y="51450" />
|
||||
<node X="47286" Y="51836" />
|
||||
<node X="46864" Y="52126" />
|
||||
<node X="46398" Y="52345" />
|
||||
<node X="46313" Y="52598" />
|
||||
<node X="45768" Y="52597" />
|
||||
<node X="45735" Y="52665" />
|
||||
<node X="45651" Y="52791" />
|
||||
<node X="45520" Y="52878" />
|
||||
<node X="45363" Y="52912" />
|
||||
<node X="45210" Y="52882" />
|
||||
<node X="45077" Y="52794" />
|
||||
<node X="44993" Y="52667" />
|
||||
<node X="44961" Y="52600" />
|
||||
<node X="44422" Y="52600" />
|
||||
<node X="44342" Y="52347" />
|
||||
<node X="43867" Y="52131" />
|
||||
<node X="43438" Y="51827" />
|
||||
<node X="43075" Y="51458" />
|
||||
<node X="42766" Y="51019" />
|
||||
<node X="42546" Y="50557" />
|
||||
<node X="42412" Y="50051" />
|
||||
<node X="42367" Y="49530" />
|
||||
<node X="42410" Y="49012" />
|
||||
<node X="42547" Y="48509" />
|
||||
<node X="42769" Y="48034" />
|
||||
<node X="43065" Y="47602" />
|
||||
<node X="43437" Y="47232" />
|
||||
<node X="43859" Y="46937" />
|
||||
<node X="44336" Y="46713" />
|
||||
<node X="44843" Y="46575" />
|
||||
<node X="45395" Y="46530" />
|
||||
</zone>
|
||||
<zone name="Orc Village" id="11024" type="TownZone" shape="NPoly" minZ="-400" maxZ="-200">
|
||||
<stat name="townId" val="4" />
|
||||
<stat name="taxById" val="9" />
|
||||
<node X="-45528" Y="-110079" />
|
||||
<node X="-45711" Y="-110075" />
|
||||
<node X="-45704" Y="-110164" />
|
||||
<node X="-46633" Y="-110080" />
|
||||
<node X="-46625" Y="-109992" />
|
||||
<node X="-46803" Y="-109993" />
|
||||
<node X="-47345" Y="-109973" />
|
||||
<node X="-47388" Y="-110012" />
|
||||
<node X="-47388" Y="-113001" />
|
||||
<node X="-47351" Y="-113039" />
|
||||
<node X="-47102" Y="-113038" />
|
||||
<node X="-47107" Y="-113382" />
|
||||
<node X="-47326" Y="-113379" />
|
||||
<node X="-47326" Y="-113829" />
|
||||
<node X="-47114" Y="-113826" />
|
||||
<node X="-47102" Y="-114171" />
|
||||
<node X="-47350" Y="-114170" />
|
||||
<node X="-47388" Y="-114199" />
|
||||
<node X="-47391" Y="-117182" />
|
||||
<node X="-47339" Y="-117239" />
|
||||
<node X="-46791" Y="-117240" />
|
||||
<node X="-46607" Y="-117240" />
|
||||
<node X="-46619" Y="-117151" />
|
||||
<node X="-45701" Y="-117000" />
|
||||
<node X="-45705" Y="-117085" />
|
||||
<node X="-45523" Y="-117088" />
|
||||
<node X="-44169" Y="-116722" />
|
||||
<node X="-44147" Y="-116804" />
|
||||
<node X="-43838" Y="-116717" />
|
||||
<node X="-43855" Y="-116638" />
|
||||
<node X="-43779" Y="-116620" />
|
||||
<node X="-42581" Y="-115424" />
|
||||
<node X="-42472" Y="-115258" />
|
||||
<node X="-42051" Y="-113671" />
|
||||
<node X="-42050" Y="-113502" />
|
||||
<node X="-42474" Y="-111925" />
|
||||
<node X="-42554" Y="-111775" />
|
||||
<node X="-43843" Y="-110456" />
|
||||
<node X="-44147" Y="-110375" />
|
||||
<node X="-45529" Y="-110078" />
|
||||
</zone>
|
||||
<zone name="Gludin Village" id="11025" type="TownZone" shape="NPoly" minZ="-3300" maxZ="-3000">
|
||||
<stat name="townId" val="5" />
|
||||
<stat name="taxById" val="1" />
|
||||
<node X="-84867" Y="149371" />
|
||||
<node X="-82581" Y="149364" />
|
||||
<node X="-82499" Y="149139" />
|
||||
<node X="-81593" Y="149177" />
|
||||
<node X="-81551" Y="149410" />
|
||||
<node X="-79270" Y="149392" />
|
||||
<node X="-79275" Y="150365" />
|
||||
<node X="-79055" Y="150368" />
|
||||
<node X="-78820" Y="150429" />
|
||||
<node X="-78644" Y="150595" />
|
||||
<node X="-78558" Y="150837" />
|
||||
<node X="-78567" Y="152410" />
|
||||
<node X="-78796" Y="152420" />
|
||||
<node X="-78803" Y="154319" />
|
||||
<node X="-77131" Y="155437" />
|
||||
<node X="-78190" Y="156459" />
|
||||
<node X="-79978" Y="156104" />
|
||||
<node X="-84876" Y="156106" />
|
||||
<node X="-84875" Y="149371" />
|
||||
</zone>
|
||||
<zone name="Dwarven Village" id="11026" type="TownZone" shape="NPoly" minZ="-1600" maxZ="-800">
|
||||
<stat name="townId" val="6" />
|
||||
<stat name="taxById" val="9" />
|
||||
<node X="115499" Y="-176771" />
|
||||
<node X="115301" Y="-176769" />
|
||||
<node X="114877" Y="-176811" />
|
||||
<node X="113385" Y="-177602" />
|
||||
<node X="112934" Y="-178507" />
|
||||
<node X="113954" Y="-183578" />
|
||||
<node X="115493" Y="-183698" />
|
||||
<node X="115748" Y="-184078" />
|
||||
<node X="115936" Y="-184197" />
|
||||
<node X="116268" Y="-184243" />
|
||||
<node X="116716" Y="-184246" />
|
||||
<node X="117023" Y="-184162" />
|
||||
<node X="117211" Y="-184022" />
|
||||
<node X="117325" Y="-183825" />
|
||||
<node X="117490" Y="-183411" />
|
||||
<node X="117629" Y="-182930" />
|
||||
<node X="117762" Y="-182686" />
|
||||
<node X="117762" Y="-182260" />
|
||||
<node X="117734" Y="-182090" />
|
||||
<node X="117531" Y="-181747" />
|
||||
<node X="117452" Y="-180534" />
|
||||
<node X="117492" Y="-180010" />
|
||||
<node X="117466" Y="-179559" />
|
||||
<node X="117327" Y="-179170" />
|
||||
<node X="117328" Y="-178966" />
|
||||
<node X="117303" Y="-178695" />
|
||||
<node X="116860" Y="-177230" />
|
||||
<node X="116806" Y="-177131" />
|
||||
<node X="116650" Y="-176975" />
|
||||
<node X="116418" Y="-176887" />
|
||||
<node X="115929" Y="-176804" />
|
||||
<node X="115490" Y="-176767" />
|
||||
</zone>
|
||||
<zone name="Gludio Castle Town" id="11027" type="TownZone" shape="NPoly" minZ="-3200" maxZ="-2900">
|
||||
<stat name="townId" val="7" />
|
||||
<stat name="taxById" val="1" />
|
||||
<node X="-14960" Y="121148" />
|
||||
<node X="-14875" Y="121120" />
|
||||
<node X="-14717" Y="121106" />
|
||||
<node X="-14394" Y="121109" />
|
||||
<node X="-14242" Y="121104" />
|
||||
<node X="-12659" Y="121098" />
|
||||
<node X="-12025" Y="121767" />
|
||||
<node X="-12024" Y="123944" />
|
||||
<node X="-12277" Y="124668" />
|
||||
<node X="-12648" Y="125573" />
|
||||
<node X="-12879" Y="126199" />
|
||||
<node X="-13855" Y="126470" />
|
||||
<node X="-14484" Y="126463" />
|
||||
<node X="-15236" Y="126178" />
|
||||
<node X="-16126" Y="125356" />
|
||||
<node X="-16531" Y="124493" />
|
||||
<node X="-16537" Y="123850" />
|
||||
<node X="-16492" Y="123330" />
|
||||
<node X="-16194" Y="123160" />
|
||||
<node X="-16057" Y="123101" />
|
||||
<node X="-15327" Y="122741" />
|
||||
<node X="-14958" Y="121150" />
|
||||
</zone>
|
||||
<zone name="Dion Castle Town" id="11028" type="TownZone" shape="NPoly" minZ="-3250" maxZ="-2600">
|
||||
<stat name="townId" val="8" />
|
||||
<stat name="taxById" val="2" />
|
||||
<node X="15264" Y="141764" />
|
||||
<node X="15434" Y="143574" />
|
||||
<node X="15760" Y="144707" />
|
||||
<node X="15846" Y="145302" />
|
||||
<node X="16134" Y="146850" />
|
||||
<node X="16715" Y="147153" />
|
||||
<node X="17844" Y="147640" />
|
||||
<node X="18139" Y="147138" />
|
||||
<node X="18541" Y="146758" />
|
||||
<node X="18782" Y="146598" />
|
||||
<node X="19069" Y="146521" />
|
||||
<node X="19430" Y="146485" />
|
||||
<node X="20363" Y="146421" />
|
||||
<node X="20722" Y="146319" />
|
||||
<node X="21415" Y="146319" />
|
||||
<node X="21402" Y="145011" />
|
||||
<node X="21381" Y="143675" />
|
||||
<node X="20696" Y="142841" />
|
||||
<node X="20380" Y="142492" />
|
||||
<node X="19060" Y="142463" />
|
||||
<node X="18821" Y="142512" />
|
||||
<node X="17885" Y="143046" />
|
||||
<node X="17447" Y="143348" />
|
||||
<node X="17019" Y="144028" />
|
||||
<node X="16780" Y="142908" />
|
||||
<node X="17344" Y="142847" />
|
||||
<node X="17327" Y="142650" />
|
||||
<node X="17483" Y="142634" />
|
||||
<node X="17396" Y="141776" />
|
||||
<node X="17238" Y="141792" />
|
||||
<node X="17218" Y="141574" />
|
||||
<node X="15265" Y="141765" />
|
||||
</zone>
|
||||
<zone name="Town of Oren" id="11029" type="TownZone" shape="NPoly" minZ="-2250" maxZ="-1400">
|
||||
<stat name="townId" val="10" />
|
||||
<stat name="taxById" val="4" />
|
||||
<node X="84014" Y="52245" />
|
||||
<node X="84138" Y="54683" />
|
||||
<node X="84143" Y="55029" />
|
||||
<node X="84001" Y="57029" />
|
||||
<node X="81773" Y="57023" />
|
||||
<node X="81795" Y="56237" />
|
||||
<node X="81239" Y="56236" />
|
||||
<node X="81282" Y="56892" />
|
||||
<node X="81187" Y="56904" />
|
||||
<node X="81105" Y="57179" />
|
||||
<node X="79195" Y="57167" />
|
||||
<node X="78986" Y="57076" />
|
||||
<node X="78844" Y="55218" />
|
||||
<node X="78843" Y="54882" />
|
||||
<node X="79148" Y="54560" />
|
||||
<node X="79660" Y="54556" />
|
||||
<node X="79662" Y="53994" />
|
||||
<node X="79002" Y="53990" />
|
||||
<node X="78963" Y="53359" />
|
||||
<node X="78959" Y="53070" />
|
||||
<node X="79027" Y="52125" />
|
||||
<node X="79628" Y="52070" />
|
||||
<node X="80547" Y="52068" />
|
||||
<node X="80835" Y="52116" />
|
||||
<node X="80733" Y="53068" />
|
||||
<node X="81306" Y="53070" />
|
||||
<node X="81369" Y="52310" />
|
||||
<node X="82605" Y="52244" />
|
||||
<node X="84010" Y="52250" />
|
||||
</zone>
|
||||
<zone name="Hunter Village" id="11030" type="TownZone" shape="NPoly" minZ="-2800" maxZ="-1500">
|
||||
<stat name="townId" val="11" />
|
||||
<stat name="taxById" val="5" />
|
||||
<node X="115318" Y="74260" />
|
||||
<node X="115019" Y="74495" />
|
||||
<node X="113919" Y="75365" />
|
||||
<node X="114386" Y="77505" />
|
||||
<node X="114653" Y="78197" />
|
||||
<node X="115063" Y="80068" />
|
||||
<node X="117015" Y="81804" />
|
||||
<node X="120527" Y="81006" />
|
||||
<node X="121485" Y="79049" />
|
||||
<node X="121631" Y="74718" />
|
||||
<node X="119999" Y="74209" />
|
||||
<node X="118499" Y="74097" />
|
||||
<node X="117946" Y="74068" />
|
||||
<node X="117404" Y="73671" />
|
||||
<node X="115622" Y="74026" />
|
||||
<node X="115328" Y="74252" />
|
||||
</zone>
|
||||
<zone name="Town of Aden" id="11031" type="TownZone" shape="NPoly" minZ="-2700" maxZ="-1900">
|
||||
<stat name="townId" val="12" />
|
||||
<stat name="taxById" val="5" />
|
||||
<node X="143209" Y="25727" />
|
||||
<node X="143209" Y="26975" />
|
||||
<node X="143463" Y="27286" />
|
||||
<node X="143473" Y="30074" />
|
||||
<node X="144386" Y="30947" />
|
||||
<node X="146209" Y="30946" />
|
||||
<node X="146649" Y="31179" />
|
||||
<node X="146830" Y="31508" />
|
||||
<node X="148081" Y="31511" />
|
||||
<node X="148275" Y="31176" />
|
||||
<node X="148696" Y="30937" />
|
||||
<node X="150367" Y="30942" />
|
||||
<node X="151289" Y="30008" />
|
||||
<node X="151233" Y="25914" />
|
||||
<node X="151399" Y="25719" />
|
||||
<node X="151403" Y="24470" />
|
||||
<node X="151205" Y="24271" />
|
||||
<node X="151198" Y="21168" />
|
||||
<node X="150233" Y="20225" />
|
||||
<node X="148287" Y="20227" />
|
||||
<node X="148086" Y="19992" />
|
||||
<node X="146836" Y="19992" />
|
||||
<node X="146642" Y="20199" />
|
||||
<node X="144429" Y="20204" />
|
||||
<node X="143459" Y="21124" />
|
||||
<node X="143446" Y="25542" />
|
||||
<node X="143198" Y="25731" />
|
||||
</zone>
|
||||
<zone name="Town of Goddard" id="11032" type="TownZone" shape="NPoly" minZ="-3550" maxZ="-2600">
|
||||
<stat name="townId" val="13" />
|
||||
<stat name="taxById" val="7" />
|
||||
<node X="144345" Y="-53353" />
|
||||
<node X="145283" Y="-52411" />
|
||||
<node X="146840" Y="-51665" />
|
||||
<node X="148575" Y="-51659" />
|
||||
<node X="150128" Y="-52405" />
|
||||
<node X="151075" Y="-53362" />
|
||||
<node X="152091" Y="-54735" />
|
||||
<node X="151974" Y="-55898" />
|
||||
<node X="151852" Y="-56567" />
|
||||
<node X="151737" Y="-57217" />
|
||||
<node X="151608" Y="-57387" />
|
||||
<node X="151239" Y="-57131" />
|
||||
<node X="150447" Y="-58201" />
|
||||
<node X="150832" Y="-58488" />
|
||||
<node X="150551" Y="-58851" />
|
||||
<node X="148717" Y="-59764" />
|
||||
<node X="148590" Y="-59759" />
|
||||
<node X="148590" Y="-59291" />
|
||||
<node X="146839" Y="-59291" />
|
||||
<node X="146842" Y="-59768" />
|
||||
<node X="146700" Y="-59766" />
|
||||
<node X="144860" Y="-58848" />
|
||||
<node X="144589" Y="-58489" />
|
||||
<node X="144967" Y="-58193" />
|
||||
<node X="144179" Y="-57141" />
|
||||
<node X="143807" Y="-57392" />
|
||||
<node X="143685" Y="-57210" />
|
||||
<node X="143335" Y="-55225" />
|
||||
<node X="143679" Y="-53917" />
|
||||
<node X="143887" Y="-53081" />
|
||||
</zone>
|
||||
<zone name="Rune Castle Town" id="11033" type="TownZone" shape="Cuboid" minZ="-1200" maxZ="3000">
|
||||
<stat name="townId" val="14" />
|
||||
<stat name="taxById" val="8" />
|
||||
<node X="47150" Y="-44815" />
|
||||
<node X="32531" Y="-52045" />
|
||||
</zone>
|
||||
<zone name="Heine" id="11034" type="TownZone" shape="NPoly" minZ="-3800" maxZ="-3400">
|
||||
<stat name="townId" val="15" />
|
||||
<stat name="taxById" val="6" />
|
||||
<node X="111391" Y="216329" />
|
||||
<node X="106872" Y="216579" />
|
||||
<node X="106693" Y="217371" />
|
||||
<node X="106612" Y="217923" />
|
||||
<node X="106612" Y="218409" />
|
||||
<node X="106435" Y="221617" />
|
||||
<node X="106435" Y="222250" />
|
||||
<node X="106563" Y="222851" />
|
||||
<node X="108183" Y="223150" />
|
||||
<node X="108916" Y="223150" />
|
||||
<node X="110264" Y="222975" />
|
||||
<node X="110253" Y="223651" />
|
||||
<node X="110185" Y="223669" />
|
||||
<node X="110095" Y="223756" />
|
||||
<node X="110056" Y="223864" />
|
||||
<node X="109790" Y="223883" />
|
||||
<node X="109703" Y="223966" />
|
||||
<node X="109705" Y="224197" />
|
||||
<node X="109882" Y="224363" />
|
||||
<node X="109884" Y="225522" />
|
||||
<node X="110764" Y="225507" />
|
||||
<node X="110767" Y="225985" />
|
||||
<node X="112002" Y="225992" />
|
||||
<node X="112005" Y="225510" />
|
||||
<node X="112891" Y="225520" />
|
||||
<node X="112886" Y="224389" />
|
||||
<node X="113068" Y="224198" />
|
||||
<node X="113072" Y="223967" />
|
||||
<node X="112983" Y="223887" />
|
||||
<node X="112704" Y="223864" />
|
||||
<node X="112676" Y="223758" />
|
||||
<node X="112592" Y="223669" />
|
||||
<node X="112520" Y="223654" />
|
||||
<node X="112506" Y="222975" />
|
||||
<node X="113745" Y="223440" />
|
||||
<node X="115249" Y="223440" />
|
||||
<node X="115249" Y="223653" />
|
||||
<node X="115356" Y="223653" />
|
||||
<node X="115356" Y="223322" />
|
||||
<node X="115392" Y="222838" />
|
||||
<node X="115393" Y="221433" />
|
||||
<node X="115980" Y="220372" />
|
||||
<node X="116055" Y="219529" />
|
||||
<node X="116055" Y="219029" />
|
||||
<node X="116220" Y="218649" />
|
||||
<node X="116219" Y="218388" />
|
||||
<node X="116041" Y="218380" />
|
||||
<node X="116043" Y="217586" />
|
||||
<node X="115310" Y="217610" />
|
||||
<node X="114755" Y="217086" />
|
||||
<node X="114434" Y="217051" />
|
||||
<node X="114417" Y="216838" />
|
||||
<node X="114182" Y="216838" />
|
||||
<node X="114161" Y="216957" />
|
||||
<node X="113280" Y="216962" />
|
||||
<node X="111885" Y="216801" />
|
||||
<node X="111808" Y="216566" />
|
||||
<node X="111631" Y="216386" />
|
||||
<node X="111393" Y="216322" />
|
||||
</zone>
|
||||
<zone name="Town of Schuttgart" id="11035" type="TownZone" shape="NPoly" minZ="-2350" maxZ="-1200">
|
||||
<stat name="townId" val="17" />
|
||||
<stat name="taxById" val="9" />
|
||||
<node X="91098" Y="-144458" />
|
||||
<node X="91477" Y="-143218" />
|
||||
<node X="91170" Y="-141327" />
|
||||
<node X="90797" Y="-140803" />
|
||||
<node X="90404" Y="-141058" />
|
||||
<node X="90077" Y="-140615" />
|
||||
<node X="90424" Y="-140324" />
|
||||
<node X="89997" Y="-139845" />
|
||||
<node X="88300" Y="-138977" />
|
||||
<node X="87659" Y="-138913" />
|
||||
<node X="87656" Y="-139375" />
|
||||
<node X="87044" Y="-139383" />
|
||||
<node X="87039" Y="-138938" />
|
||||
<node X="86427" Y="-138981" />
|
||||
<node X="84717" Y="-139826" />
|
||||
<node X="84295" Y="-140324" />
|
||||
<node X="84648" Y="-140602" />
|
||||
<node X="84286" Y="-141095" />
|
||||
<node X="83959" Y="-140825" />
|
||||
<node X="83562" Y="-141356" />
|
||||
<node X="83229" Y="-143217" />
|
||||
<node X="83821" Y="-145580" />
|
||||
<node X="84373" Y="-148184" />
|
||||
<node X="89454" Y="-148688" />
|
||||
<node X="91280" Y="-145403" />
|
||||
<node X="91084" Y="-144472" />
|
||||
</zone>
|
||||
<zone name="Floran Village" id="11036" type="TownZone" shape="NPoly" minZ="-3600" maxZ="-3400">
|
||||
<stat name="townId" val="16" />
|
||||
<stat name="taxById" val="2" />
|
||||
<node X="16529" Y="170516" />
|
||||
<node X="16645" Y="170141" />
|
||||
<node X="16747" Y="169833" />
|
||||
<node X="16770" Y="169677" />
|
||||
<node X="16822" Y="169464" />
|
||||
<node X="16858" Y="169431" />
|
||||
<node X="17457" Y="169398" />
|
||||
<node X="17939" Y="169475" />
|
||||
<node X="18109" Y="169528" />
|
||||
<node X="18435" Y="169666" />
|
||||
<node X="18628" Y="169781" />
|
||||
<node X="18641" Y="169828" />
|
||||
<node X="18531" Y="170204" />
|
||||
<node X="18473" Y="170530" />
|
||||
<node X="18452" Y="170686" />
|
||||
<node X="18394" Y="170900" />
|
||||
<node X="18361" Y="170937" />
|
||||
<node X="17771" Y="170962" />
|
||||
<node X="17220" Y="170888" />
|
||||
<node X="16897" Y="170757" />
|
||||
<node X="16543" Y="170561" />
|
||||
</zone>
|
||||
<zone name="Kamael Village" id="11038" type="TownZone" shape="NPoly" minZ="250" maxZ="2250">
|
||||
<stat name="townId" val="20" />
|
||||
<stat name="taxById" val="5" />
|
||||
<node X="-121743" Y="44424" />
|
||||
<node X="-121032" Y="43295" />
|
||||
<node X="-120886" Y="42480" />
|
||||
<node X="-120203" Y="41012" />
|
||||
<node X="-118418" Y="40332" />
|
||||
<node X="-112554" Y="40643" />
|
||||
<node X="-111161" Y="40894" />
|
||||
<node X="-110912" Y="41569" />
|
||||
<node X="-110910" Y="41908" />
|
||||
<node X="-111011" Y="42108" />
|
||||
<node X="-111186" Y="42197" />
|
||||
<node X="-111601" Y="42194" />
|
||||
<node X="-111736" Y="42102" />
|
||||
<node X="-111827" Y="41951" />
|
||||
<node X="-113240" Y="41951" />
|
||||
<node X="-113330" Y="42107" />
|
||||
<node X="-113477" Y="42193" />
|
||||
<node X="-113905" Y="42190" />
|
||||
<node X="-114072" Y="42096" />
|
||||
<node X="-114146" Y="41940" />
|
||||
<node X="-114602" Y="41944" />
|
||||
<node X="-114536" Y="43719" />
|
||||
<node X="-114513" Y="46154" />
|
||||
<node X="-114275" Y="46912" />
|
||||
<node X="-114275" Y="47297" />
|
||||
<node X="-114665" Y="48163" />
|
||||
<node X="-115473" Y="48310" />
|
||||
<node X="-118971" Y="48310" />
|
||||
<node X="-119259" Y="47970" />
|
||||
<node X="-120430" Y="47970" />
|
||||
<node X="-120654" Y="47199" />
|
||||
<node X="-120917" Y="46429" />
|
||||
</zone>
|
||||
<zone name="Fantasy Isle" id="11039" type="TownZone" shape="Cuboid" minZ="-4324" maxZ="3097">
|
||||
<stat name="townId" val="22" />
|
||||
<node X="-88871" Y="-77664" />
|
||||
<node X="-43060" Y="-43491" />
|
||||
</zone>
|
||||
<!-- Does not exist on Underground.
|
||||
<zone name="Fantasy Isle Magic Zone" type="EffectZone" shape="Cuboid" minZ="-4324" maxZ="3097">
|
||||
<stat name="chance" val="100" />
|
||||
<stat name="default_enabled" val="true" />
|
||||
<stat name="initialDelay" val="1000" />
|
||||
<stat name="reuse" val="3000" />
|
||||
<stat name="showDangerIcon" val="false" />
|
||||
<stat name="skillIdLvl" val="22300-1;" />
|
||||
<node X="-88871" Y="-77664" />
|
||||
<node X="-43060" Y="-43491" />
|
||||
</zone> -->
|
||||
<zone name="Keucereus" id="11040" type="TownZone" shape="Cuboid" minZ="1080" maxZ="3210">
|
||||
<stat name="townId" val="33" />
|
||||
<node X="-187342" Y="238059" />
|
||||
<node X="-181849" Y="247548" />
|
||||
</zone>
|
||||
<zone name="Primeval Isle (Town Zone)" id="40001" type="TownZone" shape="Cuboid" minZ="-4300" maxZ="2700">
|
||||
<stat name="townId" val="19" />
|
||||
<node X="0" Y="-32768" />
|
||||
<node X="32678" Y="0" />
|
||||
</zone>
|
||||
<zone name="Hellbound (Town Zone)" type="TownZone" shape="NPoly" minZ="-30000" maxZ="30000">
|
||||
<stat name="townId" val="21" />
|
||||
<node X="-32768" Y="229376" />
|
||||
<node X="32768" Y="229376" />
|
||||
<node X="32768" Y="262143" />
|
||||
<node X="-32768" Y="262143" />
|
||||
</zone>
|
||||
</list>
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- TODO: Require Support -->
|
||||
<list enabled="false" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/zones.xsd">
|
||||
<list enabled="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/zones.xsd">
|
||||
<!-- Tax Zones -->
|
||||
<zone name="gludio_1621_001" type="TaxZone" shape="NPoly" minZ="-5036" maxZ="964">
|
||||
<stat name="domainId" val="1" />
|
||||
@@ -313,7 +312,7 @@
|
||||
<node X="-32918" Y="86639" />
|
||||
<node X="-65420" Y="93116" />
|
||||
</zone>
|
||||
<zone name="oren_1820_002" type="TaxZone" shape="NPoly" minZ="3612" maxZ="1388">
|
||||
<zone name="oren_1820_002" type="TaxZone" shape="NPoly" minZ="1388" maxZ="3612">
|
||||
<stat name="domainId" val="4" />
|
||||
<node X="-50272" Y="84060" />
|
||||
<node X="-39573" Y="83914" />
|
||||
|
||||
@@ -236,7 +236,6 @@ public final class Config
|
||||
public static double ALT_GAME_CREATION_XP_RATE;
|
||||
public static double ALT_GAME_CREATION_RARE_XPSP_RATE;
|
||||
public static double ALT_GAME_CREATION_SP_RATE;
|
||||
public static boolean ALT_BLACKSMITH_USE_RECIPES;
|
||||
public static boolean ALT_CLAN_LEADER_INSTANT_ACTIVATION;
|
||||
public static int ALT_CLAN_JOIN_DAYS;
|
||||
public static int ALT_CLAN_CREATE_DAYS;
|
||||
@@ -1582,7 +1581,6 @@ public final class Config
|
||||
ALT_GAME_CREATION_XP_RATE = Character.getDouble("AltGameCreationXpRate", 1);
|
||||
ALT_GAME_CREATION_SP_RATE = Character.getDouble("AltGameCreationSpRate", 1);
|
||||
ALT_GAME_CREATION_RARE_XPSP_RATE = Character.getDouble("AltGameCreationRareXpSpRate", 2);
|
||||
ALT_BLACKSMITH_USE_RECIPES = Character.getBoolean("AltBlacksmithUseRecipes", true);
|
||||
ALT_CLAN_LEADER_INSTANT_ACTIVATION = Character.getBoolean("AltClanLeaderInstantActivation", false);
|
||||
ALT_CLAN_JOIN_DAYS = Character.getInt("DaysBeforeJoinAClan", 1);
|
||||
ALT_CLAN_CREATE_DAYS = Character.getInt("DaysBeforeCreateAClan", 10);
|
||||
|
||||
@@ -28,15 +28,14 @@ import java.util.logging.Logger;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.commons.util.IGameXmlReader;
|
||||
import com.l2jmobius.commons.util.file.filter.NumericNameFilter;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.buylist.Product;
|
||||
import com.l2jmobius.gameserver.model.buylist.ProductList;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
|
||||
/**
|
||||
@@ -47,7 +46,7 @@ public final class BuyListData implements IGameXmlReader
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(BuyListData.class.getName());
|
||||
|
||||
private final Map<Integer, L2BuyList> _buyLists = new HashMap<>();
|
||||
private final Map<Integer, ProductList> _buyLists = new HashMap<>();
|
||||
private static final FileFilter NUMERIC_FILTER = new NumericNameFilter();
|
||||
|
||||
protected BuyListData()
|
||||
@@ -77,7 +76,7 @@ public final class BuyListData implements IGameXmlReader
|
||||
final int itemId = rs.getInt("item_id");
|
||||
final long count = rs.getLong("count");
|
||||
final long nextRestockTime = rs.getLong("next_restock_time");
|
||||
final L2BuyList buyList = getBuyList(buyListId);
|
||||
final ProductList buyList = getBuyList(buyListId);
|
||||
if (buyList == null)
|
||||
{
|
||||
LOGGER.warning("BuyList found in database but not loaded from xml! BuyListId: " + buyListId);
|
||||
@@ -108,71 +107,44 @@ public final class BuyListData implements IGameXmlReader
|
||||
try
|
||||
{
|
||||
final int buyListId = Integer.parseInt(f.getName().replaceAll(".xml", ""));
|
||||
|
||||
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
|
||||
forEach(doc, "list", (list) ->
|
||||
{
|
||||
if ("list".equalsIgnoreCase(node.getNodeName()))
|
||||
final int defaultBaseTax = parseInteger(list.getAttributes(), "baseTax", 0);
|
||||
final ProductList buyList = new ProductList(buyListId);
|
||||
forEach(list, (node) ->
|
||||
{
|
||||
final L2BuyList buyList = new L2BuyList(buyListId);
|
||||
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
|
||||
switch (node.getNodeName())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(list_node.getNodeName()))
|
||||
case "item":
|
||||
{
|
||||
int itemId = -1;
|
||||
long price = -1;
|
||||
long restockDelay = -1;
|
||||
long count = -1;
|
||||
final NamedNodeMap attrs = list_node.getAttributes();
|
||||
Node attr = attrs.getNamedItem("id");
|
||||
itemId = Integer.parseInt(attr.getNodeValue());
|
||||
attr = attrs.getNamedItem("price");
|
||||
if (attr != null)
|
||||
{
|
||||
price = Long.parseLong(attr.getNodeValue());
|
||||
}
|
||||
attr = attrs.getNamedItem("restock_delay");
|
||||
if (attr != null)
|
||||
{
|
||||
restockDelay = Long.parseLong(attr.getNodeValue());
|
||||
}
|
||||
attr = attrs.getNamedItem("count");
|
||||
if (attr != null)
|
||||
{
|
||||
count = Long.parseLong(attr.getNodeValue());
|
||||
}
|
||||
final NamedNodeMap attrs = node.getAttributes();
|
||||
|
||||
final int itemId = parseInteger(attrs, "id");
|
||||
final L2Item item = ItemTable.getInstance().getTemplate(itemId);
|
||||
if (item != null)
|
||||
{
|
||||
if ((price > -1) && (item.getReferencePrice() > price) && (buyList.getNpcsAllowed() != null))
|
||||
{
|
||||
LOGGER.warning("Item price is too low. BuyList:" + buyList.getListId() + " ItemID:" + itemId + " File:" + f.getName());
|
||||
LOGGER.warning("Setting price to reference price " + item.getReferencePrice() + " instead of " + price + ".");
|
||||
buyList.addProduct(new Product(buyList.getListId(), item, item.getReferencePrice(), restockDelay, count));
|
||||
}
|
||||
else
|
||||
{
|
||||
buyList.addProduct(new Product(buyList.getListId(), item, price, restockDelay, count));
|
||||
}
|
||||
final long price = parseLong(attrs, "price", -1L);
|
||||
final long restockDelay = parseLong(attrs, "restock_delay", -1L);
|
||||
final long count = parseLong(attrs, "count", -1L);
|
||||
final int baseTax = parseInteger(attrs, "baseTax", defaultBaseTax);
|
||||
|
||||
buyList.addProduct(new Product(buyListId, item, price, restockDelay, count, baseTax));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning("Item not found. BuyList:" + buyList.getListId() + " ItemID:" + itemId + " File:" + f.getName());
|
||||
LOGGER.warning("Item not found. BuyList:" + buyListId + " ItemID:" + itemId + " File:" + f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if ("npcs".equalsIgnoreCase(list_node.getNodeName()))
|
||||
case "npcs":
|
||||
{
|
||||
for (Node npcs_node = list_node.getFirstChild(); npcs_node != null; npcs_node = npcs_node.getNextSibling())
|
||||
{
|
||||
if ("npc".equalsIgnoreCase(npcs_node.getNodeName()))
|
||||
{
|
||||
buyList.addAllowedNpc(Integer.parseInt(npcs_node.getTextContent()));
|
||||
}
|
||||
}
|
||||
forEach(node, "npc", (npcNode) -> buyList.addAllowedNpc(Integer.parseInt(npcNode.getTextContent())));
|
||||
break;
|
||||
}
|
||||
}
|
||||
_buyLists.put(buyList.getListId(), buyList);
|
||||
}
|
||||
}
|
||||
});
|
||||
_buyLists.put(buyListId, buyList);
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -186,7 +158,7 @@ public final class BuyListData implements IGameXmlReader
|
||||
return NUMERIC_FILTER;
|
||||
}
|
||||
|
||||
public L2BuyList getBuyList(int listId)
|
||||
public ProductList getBuyList(int listId)
|
||||
{
|
||||
return _buyLists.get(listId);
|
||||
}
|
||||
|
||||
@@ -18,50 +18,44 @@ package com.l2jmobius.gameserver.data.xml.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.util.IGameXmlReader;
|
||||
import com.l2jmobius.commons.util.file.filter.NumericNameFilter;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.enums.SpecialItemType;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.multisell.Entry;
|
||||
import com.l2jmobius.gameserver.model.multisell.Ingredient;
|
||||
import com.l2jmobius.gameserver.model.multisell.ListContainer;
|
||||
import com.l2jmobius.gameserver.model.multisell.PreparedListContainer;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExPCCafePointInfo;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MultiSellList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(MultisellData.class.getName());
|
||||
|
||||
private final Map<Integer, ListContainer> _entries = new HashMap<>();
|
||||
|
||||
public static final int PAGE_SIZE = 40;
|
||||
// Special IDs.
|
||||
public static final int PC_CAFE_POINTS = -100;
|
||||
public static final int CLAN_REPUTATION = -200;
|
||||
public static final int FAME = -300;
|
||||
public static final int FIELD_CYCLE_POINTS = -400;
|
||||
public static final int RAIDBOSS_POINTS = -500;
|
||||
// Misc
|
||||
private static final FileFilter NUMERIC_FILTER = new NumericNameFilter();
|
||||
|
||||
private final Map<Integer, MultisellListHolder> _multisells = new HashMap<>();
|
||||
|
||||
protected MultisellData()
|
||||
{
|
||||
load();
|
||||
@@ -70,15 +64,14 @@ public final class MultisellData implements IGameXmlReader
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_entries.clear();
|
||||
_multisells.clear();
|
||||
parseDatapackDirectory("data/multisell", false);
|
||||
if (Config.CUSTOM_MULTISELL_LOAD)
|
||||
{
|
||||
parseDatapackDirectory("data/multisell/custom", false);
|
||||
}
|
||||
|
||||
verify();
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _entries.size() + " multisell lists.");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _multisells.size() + " multisell lists.");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,73 +79,88 @@ public final class MultisellData implements IGameXmlReader
|
||||
{
|
||||
try
|
||||
{
|
||||
final int id = Integer.parseInt(f.getName().replaceAll(".xml", ""));
|
||||
int entryId = 1;
|
||||
Node att;
|
||||
final ListContainer list = new ListContainer(id);
|
||||
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
forEach(doc, "list", listNode ->
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
final StatsSet set = new StatsSet(parseAttributes(listNode));
|
||||
final int listId = Integer.parseInt(f.getName().substring(0, f.getName().length() - 4));
|
||||
final List<MultisellEntryHolder> entries = new ArrayList<>(listNode.getChildNodes().getLength());
|
||||
|
||||
forEach(listNode, itemNode ->
|
||||
{
|
||||
list.setApplyTaxes(parseBoolean(n.getAttributes(), "applyTaxes", false));
|
||||
list.setIsChanceMultisell(parseBoolean(n.getAttributes(), "isChanceMultisell", false));
|
||||
list.setMaintainEnchantment(parseBoolean(n.getAttributes(), "maintainEnchantment", false));
|
||||
|
||||
att = n.getAttributes().getNamedItem("useRate");
|
||||
if (att != null)
|
||||
if ("item".equalsIgnoreCase(itemNode.getNodeName()))
|
||||
{
|
||||
try
|
||||
final List<ItemHolder> ingredients = new ArrayList<>(1);
|
||||
final List<ItemChanceHolder> products = new ArrayList<>(1);
|
||||
final MultisellEntryHolder entry = new MultisellEntryHolder(ingredients, products);
|
||||
|
||||
for (Node d = itemNode.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
|
||||
list.setUseRate(Double.valueOf(att.getNodeValue()));
|
||||
if (list.getUseRate() <= 1e-6)
|
||||
if ("ingredient".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
throw new NumberFormatException("The value cannot be 0"); // threat 0 as invalid value
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
try
|
||||
{
|
||||
list.setUseRate(Config.class.getField(att.getNodeValue()).getDouble(Config.class));
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.warning(e1.getMessage() + doc.getLocalName());
|
||||
list.setUseRate(1.0);
|
||||
}
|
||||
}
|
||||
catch (DOMException e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage() + doc.getLocalName());
|
||||
}
|
||||
}
|
||||
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
final Entry e = parseEntry(d, entryId++, list);
|
||||
list.getEntries().add(e);
|
||||
}
|
||||
else if ("npcs".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
if ("npc".equalsIgnoreCase(b.getNodeName()))
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final ItemHolder ingredient = new ItemHolder(id, count);
|
||||
|
||||
if (itemExists(ingredient))
|
||||
{
|
||||
if (Util.isDigit(b.getTextContent()))
|
||||
ingredients.add(ingredient);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning("Invalid ingredient id or count for itemId: " + ingredient.getId() + ", count: " + ingredient.getCount() + " in list: " + listId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ("production".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final long count = parseLong(d.getAttributes(), "count");
|
||||
final double chance = parseDouble(d.getAttributes(), "chance", Double.NaN);
|
||||
final ItemChanceHolder product = new ItemChanceHolder(id, chance, count);
|
||||
|
||||
if (itemExists(product))
|
||||
{
|
||||
// Check chance only of items that have set chance. Items without chance (NaN) are used for displaying purposes.
|
||||
if ((!Double.isNaN(chance) && (chance < 0)) || (chance > 100))
|
||||
{
|
||||
list.allowNpc(Integer.parseInt(b.getTextContent()));
|
||||
LOGGER.warning("Invalid chance for itemId: " + product.getId() + ", count: " + product.getCount() + ", chance: " + chance + " in list: " + listId);
|
||||
continue;
|
||||
}
|
||||
|
||||
products.add(product);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning("Invalid product id or count for itemId: " + product.getId() + ", count: " + product.getCount() + " in list: " + listId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final double totalChance = products.stream().filter(i -> !Double.isNaN(i.getChance())).mapToDouble(ItemChanceHolder::getChance).sum();
|
||||
if (totalChance > 100)
|
||||
{
|
||||
LOGGER.warning("Products' total chance of " + totalChance + "% exceeds 100% for list: " + listId + " at entry " + entries.size() + 1 + ".");
|
||||
}
|
||||
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
_entries.put(id, list);
|
||||
else if ("npcs".equalsIgnoreCase(itemNode.getNodeName()))
|
||||
{
|
||||
// Initialize NPCs with the size of child nodes.
|
||||
final Set<Integer> allowNpc = new HashSet<>(itemNode.getChildNodes().getLength());
|
||||
forEach(itemNode, n -> "npc".equalsIgnoreCase(n.getNodeName()) && Util.isDigit(n.getTextContent()), n -> allowNpc.add(Integer.parseInt(n.getTextContent())));
|
||||
|
||||
// Add npcs to stats set.
|
||||
set.set("allowNpc", allowNpc);
|
||||
}
|
||||
});
|
||||
|
||||
set.set("listId", listId);
|
||||
set.set("entries", entries);
|
||||
|
||||
_multisells.put(listId, new MultisellListHolder(set));
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -166,44 +174,6 @@ public final class MultisellData implements IGameXmlReader
|
||||
return NUMERIC_FILTER;
|
||||
}
|
||||
|
||||
private final Entry parseEntry(Node n, int entryId, ListContainer list)
|
||||
{
|
||||
final Node first = n.getFirstChild();
|
||||
final Entry entry = new Entry(entryId);
|
||||
|
||||
NamedNodeMap attrs;
|
||||
Node att;
|
||||
StatsSet set;
|
||||
|
||||
for (n = first; n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("ingredient".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
attrs = n.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
entry.addIngredient(new Ingredient(set));
|
||||
}
|
||||
else if ("production".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
attrs = n.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
entry.addProduct(new Ingredient(set));
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will generate the multisell list for the items.<br>
|
||||
* There exist various parameters in multisells that affect the way they will appear:
|
||||
@@ -230,38 +200,36 @@ public final class MultisellData implements IGameXmlReader
|
||||
* @param player
|
||||
* @param npc
|
||||
* @param inventoryOnly
|
||||
* @param productMultiplier
|
||||
* @param ingredientMultiplier
|
||||
* @param productMultiplier
|
||||
*/
|
||||
public final void separateAndSend(int listId, L2PcInstance player, L2Npc npc, boolean inventoryOnly, double productMultiplier, double ingredientMultiplier)
|
||||
public final void separateAndSend(int listId, L2PcInstance player, L2Npc npc, boolean inventoryOnly, double ingredientMultiplier, double productMultiplier)
|
||||
{
|
||||
final ListContainer template = _entries.get(listId);
|
||||
final MultisellListHolder template = _multisells.get(listId);
|
||||
if (template == null)
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Cannot find list ID: " + listId + " requested by player: " + player.getName() + ", NPC ID:" + (npc != null ? npc.getId() : 0));
|
||||
LOGGER.warning("Can't find list id: " + listId + " requested by player: " + player.getName() + ", npcId: " + (npc != null ? npc.getId() : 0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!template.isNpcAllowed(-1) && (((npc != null) && !template.isNpcAllowed(npc.getId())) || ((npc == null) && template.isNpcOnly())))
|
||||
if (((npc != null) && !template.isNpcAllowed(npc.getId())) || ((npc == null) && template.isNpcOnly()))
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Player " + player + " attempted to open multisell " + listId + " from npc " + npc + " which is not allowed!");
|
||||
return;
|
||||
}
|
||||
|
||||
final PreparedListContainer list = new PreparedListContainer(template, inventoryOnly, player, npc);
|
||||
|
||||
// Pass through this only when multipliers are different from 1
|
||||
if ((productMultiplier != 1) || (ingredientMultiplier != 1))
|
||||
{
|
||||
list.getEntries().forEach(entry ->
|
||||
if (player.isGM())
|
||||
{
|
||||
// Math.max used here to avoid dropping count to 0
|
||||
entry.getProducts().forEach(product -> product.setItemCount((long) Math.max(product.getItemCount() * productMultiplier, 1)));
|
||||
|
||||
// Math.max used here to avoid dropping count to 0
|
||||
entry.getIngredients().forEach(ingredient -> ingredient.setItemCount((long) Math.max(ingredient.getItemCount() * ingredientMultiplier, 1)));
|
||||
});
|
||||
player.sendMessage("Multisell " + listId + " is restricted. Under current conditions cannot be used. Only GMs are allowed to use it.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Player " + player + " attempted to open multisell " + listId + " from npc " + npc + " which is not allowed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if ingredient/product multipliers are set, if not, set them to the template value.
|
||||
ingredientMultiplier = (Double.isNaN(ingredientMultiplier) ? template.getIngredientMultiplier() : ingredientMultiplier);
|
||||
productMultiplier = (Double.isNaN(productMultiplier) ? template.getProductMultiplier() : productMultiplier);
|
||||
|
||||
final PreparedMultisellListHolder list = new PreparedMultisellListHolder(template, inventoryOnly, player.getInventory(), npc, ingredientMultiplier, productMultiplier);
|
||||
int index = 0;
|
||||
do
|
||||
{
|
||||
@@ -276,172 +244,19 @@ public final class MultisellData implements IGameXmlReader
|
||||
|
||||
public final void separateAndSend(int listId, L2PcInstance player, L2Npc npc, boolean inventoryOnly)
|
||||
{
|
||||
separateAndSend(listId, player, npc, inventoryOnly, 1, 1);
|
||||
separateAndSend(listId, player, npc, inventoryOnly, Double.NaN, Double.NaN);
|
||||
}
|
||||
|
||||
public static boolean hasSpecialIngredient(int id, long amount, L2PcInstance player)
|
||||
private final boolean itemExists(ItemHolder holder)
|
||||
{
|
||||
switch (id)
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(holder.getId());
|
||||
if (specialItem != null)
|
||||
{
|
||||
case PC_CAFE_POINTS:
|
||||
{
|
||||
if (player.getPcCafePoints() >= amount)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_SHORT_OF_PC_POINTS));
|
||||
break;
|
||||
}
|
||||
case CLAN_REPUTATION:
|
||||
{
|
||||
if (player.getClan() == null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_A_CLAN_MEMBER_AND_CANNOT_PERFORM_THIS_ACTION);
|
||||
return false;
|
||||
}
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.ONLY_THE_CLAN_LEADER_IS_ENABLED);
|
||||
return false;
|
||||
}
|
||||
if (player.getClan().getReputationScore() < amount)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_CLAN_REPUTATION_IS_TOO_LOW);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case FAME:
|
||||
{
|
||||
if (player.getFame() < amount)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_DON_T_HAVE_ENOUGH_FAME_TO_DO_THAT);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case RAIDBOSS_POINTS:
|
||||
{
|
||||
if (player.getRaidbossPoints() < amount)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.NOT_ENOUGH_RAID_POINTS);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean takeSpecialIngredient(int id, long amount, L2PcInstance player)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case PC_CAFE_POINTS:
|
||||
{
|
||||
final int cost = player.getPcCafePoints() - (int) amount;
|
||||
player.setPcCafePoints(cost);
|
||||
final SystemMessage smsgpc = SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_USING_S1_POINT);
|
||||
smsgpc.addLong((int) amount);
|
||||
player.sendPacket(smsgpc);
|
||||
player.sendPacket(new ExPCCafePointInfo(player.getPcCafePoints(), (int) amount, 1));
|
||||
return true;
|
||||
}
|
||||
case CLAN_REPUTATION:
|
||||
{
|
||||
player.getClan().takeReputationScore((int) amount, true);
|
||||
final SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.S1_POINT_S_HAVE_BEEN_DEDUCTED_FROM_THE_CLAN_S_REPUTATION);
|
||||
smsg.addLong(amount);
|
||||
player.sendPacket(smsg);
|
||||
return true;
|
||||
}
|
||||
case FAME:
|
||||
{
|
||||
player.setFame(player.getFame() - (int) amount);
|
||||
player.sendPacket(new UserInfo(player));
|
||||
// player.sendPacket(new ExBrExtraUserInfo(player));
|
||||
return true;
|
||||
}
|
||||
case RAIDBOSS_POINTS:
|
||||
{
|
||||
player.setRaidbossPoints(player.getRaidbossPoints() - (int) amount);
|
||||
player.sendPacket(new UserInfo(player));
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CONSUMED_S1_RAID_POINTS).addLong(amount));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void giveSpecialProduct(int id, long amount, L2PcInstance player)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case CLAN_REPUTATION:
|
||||
{
|
||||
player.getClan().addReputationScore((int) amount, true);
|
||||
break;
|
||||
}
|
||||
case FAME:
|
||||
{
|
||||
player.setFame((int) (player.getFame() + amount));
|
||||
player.sendPacket(new UserInfo(player));
|
||||
// player.sendPacket(new ExBrExtraUserInfo(player));
|
||||
break;
|
||||
}
|
||||
case RAIDBOSS_POINTS:
|
||||
{
|
||||
player.increaseRaidbossPoints((int) amount);
|
||||
player.sendPacket(new UserInfo(player));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void verify()
|
||||
{
|
||||
ListContainer list;
|
||||
final Iterator<ListContainer> iter = _entries.values().iterator();
|
||||
while (iter.hasNext())
|
||||
{
|
||||
list = iter.next();
|
||||
|
||||
for (Entry ent : list.getEntries())
|
||||
{
|
||||
for (Ingredient ing : ent.getIngredients())
|
||||
{
|
||||
if (!verifyIngredient(ing))
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Cannot find ingredient with item ID: " + ing.getItemId() + " in list: " + list.getListId());
|
||||
}
|
||||
}
|
||||
for (Ingredient ing : ent.getProducts())
|
||||
{
|
||||
if (!verifyIngredient(ing))
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Cannot find product with item ID: " + ing.getItemId() + " in list: " + list.getListId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final boolean verifyIngredient(Ingredient ing)
|
||||
{
|
||||
switch (ing.getItemId())
|
||||
{
|
||||
case PC_CAFE_POINTS:
|
||||
case CLAN_REPUTATION:
|
||||
case FAME:
|
||||
case RAIDBOSS_POINTS:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return ing.getTemplate() != null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(holder.getId());
|
||||
return (template != null) && (template.isStackable() ? (holder.getCount() >= 1) : (holder.getCount() == 1));
|
||||
}
|
||||
|
||||
public static MultisellData getInstance()
|
||||
|
||||
@@ -83,12 +83,12 @@ public class OptionData implements IGameXmlReader
|
||||
}
|
||||
case "active_skill":
|
||||
{
|
||||
option.setActiveSkill(new SkillHolder(parseInteger(innerNode.getAttributes(), "id"), parseInteger(innerNode.getAttributes(), "level")));
|
||||
option.addActiveSkill(new SkillHolder(parseInteger(innerNode.getAttributes(), "id"), parseInteger(innerNode.getAttributes(), "level")));
|
||||
break;
|
||||
}
|
||||
case "passive_skill":
|
||||
{
|
||||
option.setPassiveSkill(new SkillHolder(parseInteger(innerNode.getAttributes(), "id"), parseInteger(innerNode.getAttributes(), "level")));
|
||||
option.addPassiveSkill(new SkillHolder(parseInteger(innerNode.getAttributes(), "id"), parseInteger(innerNode.getAttributes(), "level")));
|
||||
break;
|
||||
}
|
||||
case "attack_skill":
|
||||
|
||||
@@ -33,8 +33,7 @@ import org.w3c.dom.Node;
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.OptionData;
|
||||
import com.l2jmobius.gameserver.model.L2Augmentation;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.Augmentation;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.options.Options;
|
||||
@@ -86,12 +85,11 @@ public class AugmentationData
|
||||
private final List<List<Integer>> _redSkills = new ArrayList<>();
|
||||
private final List<List<Integer>> _yellowSkills = new ArrayList<>();
|
||||
|
||||
private final Map<Integer, Augmentation> _augmentations = new HashMap<>();
|
||||
private final List<AugmentationChance> _augmentationChances = new ArrayList<>();
|
||||
private final List<augmentationChanceAcc> _augmentationChancesAcc = new ArrayList<>();
|
||||
private final List<Integer> _augmentationStones = new ArrayList<>();
|
||||
|
||||
private final Map<Integer, SkillHolder> _allSkills = new HashMap<>();
|
||||
|
||||
protected AugmentationData()
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
@@ -298,8 +296,6 @@ public class AugmentationData
|
||||
{
|
||||
_redSkills.get(k).add(augmentationId);
|
||||
}
|
||||
|
||||
_allSkills.put(augmentationId, new SkillHolder(skillId, skillLvL));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -424,7 +420,7 @@ public class AugmentationData
|
||||
}
|
||||
}
|
||||
// Accessories disabled for Classic.
|
||||
/*
|
||||
/**
|
||||
* if (Config.RETAIL_LIKE_AUGMENTATION_ACCESSORY) { final DocumentBuilderFactory factory3 = DocumentBuilderFactory.newInstance(); factory3.setValidating(false); factory3.setIgnoringComments(true); final File aFile3 = new File(Config.DATAPACK_ROOT +
|
||||
* "/data/stats/augmentation/retailchances_accessory.xml"); if (aFile3.exists()) { Document aDoc = null; try { aDoc = factory3.newDocumentBuilder().parse(aFile3); } catch (Exception e) { e.printStackTrace(); return; } String aWeaponType = null; int aStoneId = 0; int aVariationId = 0; int
|
||||
* aCategoryChance = 0; int aAugmentId = 0; float aAugmentChance = 0; for (Node l = aDoc.getFirstChild(); l != null; l = l.getNextSibling()) { if (l.getNodeName().equals("list")) { NamedNodeMap aNodeAttributes = null; for (Node n = l.getFirstChild(); n != null; n = n.getNextSibling()) { if
|
||||
@@ -437,6 +433,11 @@ public class AugmentationData
|
||||
*/
|
||||
}
|
||||
|
||||
public Augmentation getAugmentation(int id)
|
||||
{
|
||||
return _augmentations.computeIfAbsent(id, k -> new Augmentation(k));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new random augmentation
|
||||
* @param lifeStoneLevel
|
||||
@@ -446,7 +447,7 @@ public class AugmentationData
|
||||
* @param targetItem
|
||||
* @return
|
||||
*/
|
||||
public L2Augmentation generateRandomAugmentation(int lifeStoneLevel, int lifeStoneGrade, int bodyPart, int lifeStoneId, L2ItemInstance targetItem)
|
||||
public Augmentation generateRandomAugmentation(int lifeStoneLevel, int lifeStoneGrade, int bodyPart, int lifeStoneId, L2ItemInstance targetItem)
|
||||
{
|
||||
switch (bodyPart)
|
||||
{
|
||||
@@ -463,7 +464,7 @@ public class AugmentationData
|
||||
}
|
||||
}
|
||||
|
||||
private L2Augmentation generateRandomWeaponAugmentation(int lifeStoneLevel, int lifeStoneGrade, int lifeStoneId, L2ItemInstance item)
|
||||
private Augmentation generateRandomWeaponAugmentation(int lifeStoneLevel, int lifeStoneGrade, int lifeStoneId, L2ItemInstance item)
|
||||
{
|
||||
int stat12 = 0;
|
||||
int stat34 = 0;
|
||||
@@ -656,7 +657,8 @@ public class AugmentationData
|
||||
}
|
||||
}
|
||||
}
|
||||
return new L2Augmentation(((stat34 << 16) + stat12));
|
||||
final int augmentationId = ((stat34 << 16) + stat12);
|
||||
return getAugmentation(augmentationId);
|
||||
}
|
||||
boolean generateSkill = false;
|
||||
boolean generateGlow = false;
|
||||
@@ -833,10 +835,10 @@ public class AugmentationData
|
||||
{
|
||||
LOGGER.info(getClass().getSimpleName() + ": Augmentation success: stat12=" + stat12 + "; stat34=" + stat34 + "; resultColor=" + resultColor + "; level=" + lifeStoneLevel + "; grade=" + lifeStoneGrade);
|
||||
}
|
||||
return new L2Augmentation(((stat34 << 16) + stat12));
|
||||
return new Augmentation(((stat34 << 16) + stat12));
|
||||
}
|
||||
|
||||
private L2Augmentation generateRandomAccessoryAugmentation(int lifeStoneLevel, int bodyPart, int lifeStoneId)
|
||||
private Augmentation generateRandomAccessoryAugmentation(int lifeStoneLevel, int bodyPart, int lifeStoneId)
|
||||
{
|
||||
int stat12 = 0;
|
||||
int stat34 = 0;
|
||||
@@ -904,7 +906,8 @@ public class AugmentationData
|
||||
}
|
||||
}
|
||||
|
||||
return new L2Augmentation(((stat34 << 16) + stat12));
|
||||
final int augmentationId = ((stat34 << 16) + stat12);
|
||||
return getAugmentation(augmentationId);
|
||||
}
|
||||
lifeStoneLevel = Math.min(lifeStoneLevel, 9);
|
||||
int base = 0;
|
||||
@@ -948,7 +951,7 @@ public class AugmentationData
|
||||
op = OptionData.getInstance().getOptions(stat34);
|
||||
}
|
||||
|
||||
if ((op == null) || (!op.hasActiveSkill() && !op.hasPassiveSkill() && !op.hasActivationSkills()))
|
||||
if ((op == null) || (!op.hasActiveSkills() && !op.hasPassiveSkills() && !op.hasActivationSkills()))
|
||||
{
|
||||
// second augmentation (stats)
|
||||
// calculating any different from stat12 value inside sub-block
|
||||
@@ -965,7 +968,8 @@ public class AugmentationData
|
||||
{
|
||||
LOGGER.info(getClass().getSimpleName() + ": Accessory augmentation success: stat12=" + stat12 + "; stat34=" + stat34 + "; level=" + lifeStoneLevel);
|
||||
}
|
||||
return new L2Augmentation(((stat34 << 16) + stat12));
|
||||
final int augmentationId = ((stat34 << 16) + stat12);
|
||||
return getAugmentation(augmentationId);
|
||||
}
|
||||
|
||||
public boolean isAugmentaionStoneValid(int stoneId)
|
||||
|
||||
@@ -74,7 +74,6 @@ public final class MapRegionManager implements IGameXmlReader
|
||||
String name;
|
||||
String town;
|
||||
int locId;
|
||||
int castle;
|
||||
int bbs;
|
||||
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
@@ -89,10 +88,9 @@ public final class MapRegionManager implements IGameXmlReader
|
||||
name = attrs.getNamedItem("name").getNodeValue();
|
||||
town = attrs.getNamedItem("town").getNodeValue();
|
||||
locId = parseInteger(attrs, "locId");
|
||||
castle = parseInteger(attrs, "castle");
|
||||
bbs = parseInteger(attrs, "bbs");
|
||||
|
||||
final L2MapRegion region = new L2MapRegion(name, town, locId, castle, bbs);
|
||||
final L2MapRegion region = new L2MapRegion(name, town, locId, bbs);
|
||||
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
attrs = c.getAttributes();
|
||||
@@ -224,22 +222,6 @@ public final class MapRegionManager implements IGameXmlReader
|
||||
return region.getTown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param activeChar
|
||||
* @return
|
||||
*/
|
||||
public int getAreaCastle(L2Character activeChar)
|
||||
{
|
||||
final L2MapRegion region = getMapRegion(activeChar);
|
||||
|
||||
if (region == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return region.getCastle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param activeChar
|
||||
* @param teleportWhere
|
||||
|
||||
@@ -1,121 +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.instancemanager;
|
||||
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2TownZone;
|
||||
|
||||
public final class TownManager
|
||||
{
|
||||
public static int getTownCastle(int townId)
|
||||
{
|
||||
switch (townId)
|
||||
{
|
||||
case 912:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case 916:
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
case 918:
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
case 922:
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
case 924:
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
case 926:
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
case 1538:
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
case 1537:
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
case 1714:
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean townHasCastleInSiege(int townId)
|
||||
{
|
||||
final int castleId = getTownCastle(townId);
|
||||
if (castleId > 0)
|
||||
{
|
||||
final Castle castle = CastleManager.getInstance().getCastleById(castleId);
|
||||
if (castle != null)
|
||||
{
|
||||
return castle.getSiege().isInProgress();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean townHasCastleInSiege(int x, int y)
|
||||
{
|
||||
return townHasCastleInSiege(MapRegionManager.getInstance().getMapRegionLocId(x, y));
|
||||
}
|
||||
|
||||
public static L2TownZone getTown(int townId)
|
||||
{
|
||||
for (L2TownZone temp : ZoneManager.getInstance().getAllZones(L2TownZone.class))
|
||||
{
|
||||
if (temp.getTownId() == townId)
|
||||
{
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the town at that position (if any)
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @return
|
||||
*/
|
||||
public static L2TownZone getTown(int x, int y, int z)
|
||||
{
|
||||
for (L2ZoneType temp : ZoneManager.getInstance().getZones(x, y, z))
|
||||
{
|
||||
if (temp instanceof L2TownZone)
|
||||
{
|
||||
return (L2TownZone) temp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,107 +1,95 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.OptionData;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.options.Options;
|
||||
|
||||
/**
|
||||
* Used to store an augmentation and its bonuses.
|
||||
* @author durgus, UnAfraid
|
||||
*/
|
||||
public final class L2Augmentation
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(L2Augmentation.class.getName());
|
||||
private final List<Options> _options = new ArrayList<>();
|
||||
private boolean _active;
|
||||
private final int _id;
|
||||
|
||||
public L2Augmentation(int id)
|
||||
{
|
||||
_id = id;
|
||||
_active = false;
|
||||
final int[] stats = new int[2];
|
||||
stats[0] = 0x0000FFFF & id;
|
||||
stats[1] = (id >> 16);
|
||||
|
||||
for (int stat : stats)
|
||||
{
|
||||
final Options op = OptionData.getInstance().getOptions(stat);
|
||||
if (op != null)
|
||||
{
|
||||
_options.add(op);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Couldn't find option: " + stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the augmentation "id" used in serverpackets.
|
||||
* @return augmentationId
|
||||
*/
|
||||
public int getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
public List<Options> getOptions()
|
||||
{
|
||||
return _options;
|
||||
}
|
||||
|
||||
public void applyBonus(L2PcInstance player)
|
||||
{
|
||||
// make sure the bonuses are not applied twice..
|
||||
if (_active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Options op : _options)
|
||||
{
|
||||
op.apply(player);
|
||||
}
|
||||
|
||||
player.getStat().recalculateStats(true);
|
||||
_active = true;
|
||||
}
|
||||
|
||||
public void removeBonus(L2PcInstance player)
|
||||
{
|
||||
// make sure the bonuses are not removed twice
|
||||
if (!_active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Options op : _options)
|
||||
{
|
||||
op.remove(player);
|
||||
}
|
||||
|
||||
player.getStat().recalculateStats(true);
|
||||
_active = false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.OptionData;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.options.Options;
|
||||
|
||||
/**
|
||||
* Used to store an augmentation and its bonuses.
|
||||
* @author durgus, UnAfraid
|
||||
*/
|
||||
public final class Augmentation
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(Augmentation.class.getName());
|
||||
private final Options[] _options;
|
||||
private final int _id;
|
||||
|
||||
public Augmentation(int id)
|
||||
{
|
||||
_id = id;
|
||||
final int[] stats = new int[2];
|
||||
stats[0] = 0x0000FFFF & id;
|
||||
stats[1] = (id >> 16);
|
||||
_options = new Options[stats.length];
|
||||
|
||||
for (int i = 0; i < stats.length; i++)
|
||||
{
|
||||
final Options op = OptionData.getInstance().getOptions(stats[i]);
|
||||
if (op != null)
|
||||
{
|
||||
_options[i] = op;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Couldn't find option: " + stats[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the augmentation "id" used in serverpackets.
|
||||
* @return augmentationId
|
||||
*/
|
||||
public int getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
public Options[] getOptions()
|
||||
{
|
||||
return _options;
|
||||
}
|
||||
|
||||
public int getOptionId(int index)
|
||||
{
|
||||
if ((index >= 0) && (index < _options.length) && (_options[index] != null))
|
||||
{
|
||||
return _options[index].getId();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void applyBonus(L2PcInstance player)
|
||||
{
|
||||
for (Options op : _options)
|
||||
{
|
||||
op.apply(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeBonus(L2PcInstance player)
|
||||
{
|
||||
for (Options op : _options)
|
||||
{
|
||||
op.remove(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public class CharSelectInfoPackage
|
||||
private int _reputation = 0;
|
||||
private int _pkKills = 0;
|
||||
private int _pvpKills = 0;
|
||||
private int _augmentationId = 0;
|
||||
private Augmentation _augmentation;
|
||||
private int _x = 0;
|
||||
private int _y = 0;
|
||||
private int _z = 0;
|
||||
@@ -336,14 +336,14 @@ public class CharSelectInfoPackage
|
||||
return _reputation;
|
||||
}
|
||||
|
||||
public void setAugmentationId(int augmentationId)
|
||||
public void setAugmentation(Augmentation augmentation)
|
||||
{
|
||||
_augmentationId = augmentationId;
|
||||
_augmentation = augmentation;
|
||||
}
|
||||
|
||||
public int getAugmentationId()
|
||||
public Augmentation getAugmentation()
|
||||
{
|
||||
return _augmentationId;
|
||||
return _augmentation;
|
||||
}
|
||||
|
||||
public void setPkKills(int PkKills)
|
||||
|
||||
@@ -39,10 +39,10 @@ public class ItemInfo
|
||||
private L2Item _item;
|
||||
|
||||
/** The level of enchant on the L2ItemInstance */
|
||||
private int _enchant;
|
||||
private int _enchantLevel;
|
||||
|
||||
/** The augmentation of the item */
|
||||
private int _augmentation;
|
||||
private Augmentation _augmentation;
|
||||
|
||||
/** The quantity of L2ItemInstance */
|
||||
private long _count;
|
||||
@@ -68,7 +68,7 @@ public class ItemInfo
|
||||
|
||||
private byte _elemAtkType = -2;
|
||||
private int _elemAtkPower = 0;
|
||||
private final int[] _elemDefAttr =
|
||||
private final int[] _attributeDefence =
|
||||
{
|
||||
0,
|
||||
0,
|
||||
@@ -99,17 +99,10 @@ public class ItemInfo
|
||||
_item = item.getItem();
|
||||
|
||||
// Get the enchant level of the L2ItemInstance
|
||||
_enchant = item.getEnchantLevel();
|
||||
_enchantLevel = item.getEnchantLevel();
|
||||
|
||||
// Get the augmentation boni
|
||||
if (item.isAugmented())
|
||||
{
|
||||
_augmentation = item.getAugmentation().getId();
|
||||
}
|
||||
else
|
||||
{
|
||||
_augmentation = 0;
|
||||
}
|
||||
// Get the augmentation bonus
|
||||
_augmentation = item.getAugmentation();
|
||||
|
||||
// Get the quantity of the L2ItemInstance
|
||||
_count = item.getCount();
|
||||
@@ -150,7 +143,7 @@ public class ItemInfo
|
||||
_elemAtkPower = item.getAttackAttributePower();
|
||||
for (AttributeType type : AttributeType.ATTRIBUTE_TYPES)
|
||||
{
|
||||
_elemDefAttr[type.getClientId()] = item.getDefenceAttribute(type);
|
||||
_attributeDefence[type.getClientId()] = item.getDefenceAttribute(type);
|
||||
}
|
||||
_option = item.getEnchantOptions();
|
||||
_soulCrystalOptions = item.getSpecialAbilities();
|
||||
@@ -179,10 +172,10 @@ public class ItemInfo
|
||||
_item = item.getItem();
|
||||
|
||||
// Get the enchant level of the L2ItemInstance
|
||||
_enchant = item.getEnchant();
|
||||
_enchantLevel = item.getEnchant();
|
||||
|
||||
// Get the augmentation bonus
|
||||
_augmentation = item.getAugmentId();
|
||||
_augmentation = item.getAugmentation();
|
||||
|
||||
// Get the quantity of the L2ItemInstance
|
||||
_count = item.getCount();
|
||||
@@ -207,7 +200,7 @@ public class ItemInfo
|
||||
_elemAtkPower = item.getAttackElementPower();
|
||||
for (byte i = 0; i < 6; i++)
|
||||
{
|
||||
_elemDefAttr[i] = item.getElementDefAttr(i);
|
||||
_attributeDefence[i] = item.getElementDefAttr(i);
|
||||
}
|
||||
|
||||
_option = item.getEnchantOptions();
|
||||
@@ -230,10 +223,10 @@ public class ItemInfo
|
||||
_item = item.getItem();
|
||||
|
||||
// Get the enchant level of the L2ItemInstance
|
||||
_enchant = 0;
|
||||
_enchantLevel = 0;
|
||||
|
||||
// Get the augmentation boni
|
||||
_augmentation = 0;
|
||||
// Get the augmentation bonus
|
||||
_augmentation = null;
|
||||
|
||||
// Get the quantity of the L2ItemInstance
|
||||
_count = item.getCount();
|
||||
@@ -272,17 +265,10 @@ public class ItemInfo
|
||||
_item = item.getItem();
|
||||
|
||||
// Get the enchant level of the L2ItemInstance
|
||||
_enchant = item.getEnchantLevel();
|
||||
_enchantLevel = item.getEnchantLevel();
|
||||
|
||||
// Get the augmentation boni
|
||||
if (item.isAugmented())
|
||||
{
|
||||
_augmentation = item.getAugmentationId();
|
||||
}
|
||||
else
|
||||
{
|
||||
_augmentation = 0;
|
||||
}
|
||||
// Get the augmentation bonus
|
||||
_augmentation = item.getAugmentation();
|
||||
|
||||
// Get the quantity of the L2ItemInstance
|
||||
_count = item.getCount();
|
||||
@@ -303,7 +289,7 @@ public class ItemInfo
|
||||
_elemAtkPower = item.getAttackElementPower();
|
||||
for (byte i = 0; i < 6; i++)
|
||||
{
|
||||
_elemDefAttr[i] = item.getElementDefAttr(i);
|
||||
_attributeDefence[i] = item.getElementDefAttr(i);
|
||||
}
|
||||
_option = item.getEnchantOptions();
|
||||
_soulCrystalOptions = item.getSoulCrystalOptions();
|
||||
@@ -320,26 +306,16 @@ public class ItemInfo
|
||||
return _item;
|
||||
}
|
||||
|
||||
public int getEnchant()
|
||||
public int getEnchantLevel()
|
||||
{
|
||||
return _enchant;
|
||||
return _enchantLevel;
|
||||
}
|
||||
|
||||
public int getAugmentationBonus()
|
||||
public Augmentation getAugmentation()
|
||||
{
|
||||
return _augmentation;
|
||||
}
|
||||
|
||||
public int get1stAugmentationId()
|
||||
{
|
||||
return 0x0000FFFF & getAugmentationBonus();
|
||||
}
|
||||
|
||||
public int get2ndAugmentationId()
|
||||
{
|
||||
return getAugmentationBonus() >> 16;
|
||||
}
|
||||
|
||||
public long getCount()
|
||||
{
|
||||
return _count;
|
||||
@@ -395,9 +371,9 @@ public class ItemInfo
|
||||
return _elemAtkPower;
|
||||
}
|
||||
|
||||
public int getElementDefAttr(byte i)
|
||||
public int getAttributeDefence(AttributeType attribute)
|
||||
{
|
||||
return _elemDefAttr[i];
|
||||
return _attributeDefence[attribute.getClientId()];
|
||||
}
|
||||
|
||||
public int[] getEnchantOptions()
|
||||
@@ -412,12 +388,12 @@ public class ItemInfo
|
||||
|
||||
public Collection<EnsoulOption> getSoulCrystalOptions()
|
||||
{
|
||||
return _soulCrystalOptions;
|
||||
return _soulCrystalOptions != null ? _soulCrystalOptions : Collections.emptyList();
|
||||
}
|
||||
|
||||
public Collection<EnsoulOption> getSoulCrystalSpecialOptions()
|
||||
{
|
||||
return _soulCrystalSpecialOptions;
|
||||
return _soulCrystalSpecialOptions != null ? _soulCrystalSpecialOptions : Collections.emptyList();
|
||||
}
|
||||
|
||||
public long getVisualExpiration()
|
||||
|
||||
@@ -33,7 +33,6 @@ public class L2MapRegion
|
||||
private final String _name;
|
||||
private final String _town;
|
||||
private final int _locId;
|
||||
private final int _castle;
|
||||
private final int _bbs;
|
||||
private List<int[]> _maps = null;
|
||||
|
||||
@@ -44,12 +43,11 @@ public class L2MapRegion
|
||||
|
||||
private final Map<Race, String> _bannedRace = new HashMap<>();
|
||||
|
||||
public L2MapRegion(String name, String town, int locId, int castle, int bbs)
|
||||
public L2MapRegion(String name, String town, int locId, int bbs)
|
||||
{
|
||||
_name = name;
|
||||
_town = town;
|
||||
_locId = locId;
|
||||
_castle = castle;
|
||||
_bbs = bbs;
|
||||
}
|
||||
|
||||
@@ -68,11 +66,6 @@ public class L2MapRegion
|
||||
return _locId;
|
||||
}
|
||||
|
||||
public final int getCastle()
|
||||
{
|
||||
return _castle;
|
||||
}
|
||||
|
||||
public final int getBbs()
|
||||
{
|
||||
return _bbs;
|
||||
|
||||
@@ -711,6 +711,20 @@ public class StatsSet implements IParserAdvUtils
|
||||
return (A) obj;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <A> A getObject(String name, Class<A> type, A defaultValue)
|
||||
{
|
||||
Objects.requireNonNull(name);
|
||||
Objects.requireNonNull(type);
|
||||
final Object obj = _set.get(name);
|
||||
if ((obj == null) || !type.isAssignableFrom(obj.getClass()))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return (A) obj;
|
||||
}
|
||||
|
||||
public SkillHolder getSkillHolder(String key)
|
||||
{
|
||||
Objects.requireNonNull(key);
|
||||
|
||||
@@ -51,7 +51,7 @@ public class TradeItem
|
||||
private final Collection<EnsoulOption> _soulCrystalOptions;
|
||||
private final Collection<EnsoulOption> _soulCrystalSpecialOptions;
|
||||
private int _visualId;
|
||||
private int _augmentId;
|
||||
private Augmentation _augmentation;
|
||||
|
||||
public TradeItem(L2ItemInstance item, long count, long price)
|
||||
{
|
||||
@@ -74,7 +74,7 @@ public class TradeItem
|
||||
_soulCrystalOptions = item.getSpecialAbilities();
|
||||
_soulCrystalSpecialOptions = item.getAdditionalSpecialAbilities();
|
||||
_visualId = item.getVisualId();
|
||||
_augmentId = item.isAugmented() ? item.getAugmentation().getId() : 0;
|
||||
_augmentation = item.getAugmentation();
|
||||
}
|
||||
|
||||
public TradeItem(L2Item item, long count, long price)
|
||||
@@ -215,9 +215,9 @@ public class TradeItem
|
||||
return _soulCrystalSpecialOptions;
|
||||
}
|
||||
|
||||
public int getAugmentId()
|
||||
public Augmentation getAugmentation()
|
||||
{
|
||||
return _augmentId;
|
||||
return _augmentation;
|
||||
}
|
||||
|
||||
public int getVisualId()
|
||||
|
||||
@@ -323,6 +323,12 @@ public class TradeList
|
||||
return null;
|
||||
}
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
_log.warning(_owner.getName() + ": Attempt to remove " + count + " items from TradeList!");
|
||||
return null;
|
||||
}
|
||||
|
||||
for (TradeItem titem : _items)
|
||||
{
|
||||
if ((titem.getObjectId() == objectId) || (titem.getItem().getId() == itemId))
|
||||
@@ -881,10 +887,10 @@ public class TradeList
|
||||
/**
|
||||
* Sell items to this PrivateStore list
|
||||
* @param player
|
||||
* @param items
|
||||
* @param requestedItems
|
||||
* @return : boolean true if success
|
||||
*/
|
||||
public synchronized boolean privateStoreSell(L2PcInstance player, ItemRequest[] items)
|
||||
public synchronized boolean privateStoreSell(L2PcInstance player, ItemRequest[] requestedItems)
|
||||
{
|
||||
if (_locked)
|
||||
{
|
||||
@@ -907,12 +913,14 @@ public class TradeList
|
||||
|
||||
long totalPrice = 0;
|
||||
|
||||
for (ItemRequest item : items)
|
||||
final TradeItem[] sellerItems = _items.toArray(new TradeItem[0]);
|
||||
|
||||
for (ItemRequest item : requestedItems)
|
||||
{
|
||||
// searching item in tradelist using itemId
|
||||
boolean found = false;
|
||||
|
||||
for (TradeItem ti : _items)
|
||||
for (TradeItem ti : sellerItems)
|
||||
{
|
||||
if (ti.getItem().getId() == item.getItemId())
|
||||
{
|
||||
@@ -956,8 +964,19 @@ public class TradeList
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((item.getObjectId() < 1) || (item.getObjectId() > sellerItems.length))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final TradeItem tradeItem = sellerItems[item.getObjectId() - 1];
|
||||
if ((tradeItem == null) || (tradeItem.getItem().getId() != item.getItemId()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if requested item is available for manipulation
|
||||
int objectId = item.getObjectId();
|
||||
int objectId = tradeItem.getObjectId();
|
||||
L2ItemInstance oldItem = player.checkItemManipulation(objectId, item.getCount(), "sell");
|
||||
// private store - buy use same objectId for buying several non-stackable items
|
||||
if (oldItem == null)
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.l2jmobius.gameserver.enums.MpRewardAffectType;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.enums.ShotType;
|
||||
import com.l2jmobius.gameserver.enums.TaxType;
|
||||
import com.l2jmobius.gameserver.enums.Team;
|
||||
import com.l2jmobius.gameserver.enums.UserInfoType;
|
||||
import com.l2jmobius.gameserver.handler.BypassHandler;
|
||||
@@ -42,7 +43,6 @@ import com.l2jmobius.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.DBSpawnManager.DBStatusType;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.TownManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
@@ -83,6 +83,7 @@ import com.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
|
||||
import com.l2jmobius.gameserver.model.stats.Formulas;
|
||||
import com.l2jmobius.gameserver.model.variables.NpcVariables;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2TaxZone;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
@@ -154,6 +155,9 @@ public class L2Npc extends L2Character
|
||||
private StatsSet _params;
|
||||
private DBSpawnManager.DBStatusType _raidStatus;
|
||||
|
||||
/** Contains information about local tax payments. */
|
||||
private L2TaxZone _taxZone = null;
|
||||
|
||||
/**
|
||||
* Constructor of L2NpcInstance (use L2Character constructor).<br>
|
||||
* <B><U>Actions</U>:</B>
|
||||
@@ -519,6 +523,48 @@ public class L2Npc extends L2Character
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set another tax zone which will be used for tax payments.
|
||||
* @param zone newly entered tax zone
|
||||
*/
|
||||
public final void setTaxZone(L2TaxZone zone)
|
||||
{
|
||||
_taxZone = ((zone != null) && !isInInstance()) ? zone : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets castle for tax payments.
|
||||
* @return instance of {@link Castle} when NPC is inside {@link L2TaxZone} otherwise {@code null}
|
||||
*/
|
||||
public final Castle getTaxCastle()
|
||||
{
|
||||
return (_taxZone != null) ? _taxZone.getCastle() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets castle tax rate
|
||||
* @param type type of tax
|
||||
* @return tax rate when NPC is inside tax zone otherwise {@code 0}
|
||||
*/
|
||||
public final double getCastleTaxRate(TaxType type)
|
||||
{
|
||||
final Castle castle = getTaxCastle();
|
||||
return (castle != null) ? (castle.getTaxPercent(type) / 100.0) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase castle vault by specified tax amount.
|
||||
* @param amount tax amount
|
||||
*/
|
||||
public final void handleTaxPayment(long amount)
|
||||
{
|
||||
final Castle taxCastle = getTaxCastle();
|
||||
if (taxCastle != null)
|
||||
{
|
||||
taxCastle.addToTreasury(amount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nearest L2Castle this L2NpcInstance belongs to. Otherwise null.
|
||||
*/
|
||||
@@ -560,11 +606,6 @@ public class L2Npc extends L2Character
|
||||
return FortManager.getInstance().findNearestFort(this, maxDistance);
|
||||
}
|
||||
|
||||
public final boolean isInTown()
|
||||
{
|
||||
return TownManager.getTown(getX(), getY(), getZ()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a quest or chat window on client with the text of the L2NpcInstance in function of the command.<br>
|
||||
* <B><U> Example of use </U> :</B>
|
||||
@@ -1063,14 +1104,9 @@ public class L2Npc extends L2Character
|
||||
WalkingManager.getInstance().onSpawn(this);
|
||||
}
|
||||
|
||||
// Display clan flag
|
||||
if (isInsideZone(ZoneId.TOWN) && (getCastle() != null) && (Config.SHOW_CREST_WITHOUT_QUEST || getCastle().getShowNpcCrest()) && (getCastle().getOwnerId() != 0))
|
||||
if (isInsideZone(ZoneId.TAX) && (getCastle() != null) && (Config.SHOW_CREST_WITHOUT_QUEST || getCastle().getShowNpcCrest()) && (getCastle().getOwnerId() != 0))
|
||||
{
|
||||
final int townId = TownManager.getTown(getX(), getY(), getZ()).getTownId();
|
||||
if ((townId != 33) && (townId != 22))
|
||||
{
|
||||
setClanId(getCastle().getOwnerId());
|
||||
}
|
||||
setClanId(getCastle().getOwnerId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1079,12 +1115,12 @@ public class L2Npc extends L2Character
|
||||
*/
|
||||
public void onRespawn()
|
||||
{
|
||||
// Stop all effects and recalculate stats without broadcasting.
|
||||
getEffectList().stopAllEffects(false);
|
||||
|
||||
// Make it alive
|
||||
setIsDead(false);
|
||||
|
||||
// Stop all effects and recalculate stats without broadcasting.
|
||||
getEffectList().stopAllEffects(false);
|
||||
|
||||
// Reset decay info
|
||||
setDecayed(false);
|
||||
|
||||
@@ -1827,11 +1863,17 @@ public class L2Npc extends L2Character
|
||||
initSeenCreatures(getTemplate().getAggroRange());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the NpcStringId for name
|
||||
*/
|
||||
public NpcStringId getNameString()
|
||||
{
|
||||
return _nameString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the NpcStringId for title
|
||||
*/
|
||||
public NpcStringId getTitleString()
|
||||
{
|
||||
return _titleString;
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.enums.TaxType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.buylist.ProductList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.BuyList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExBuySellList;
|
||||
@@ -52,8 +52,7 @@ public class L2MerchantInstance extends L2NpcInstance
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
String pom;
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
@@ -62,7 +61,6 @@ public class L2MerchantInstance extends L2NpcInstance
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "data/html/merchant/" + pom + ".htm";
|
||||
}
|
||||
|
||||
@@ -71,9 +69,9 @@ public class L2MerchantInstance extends L2NpcInstance
|
||||
showBuyWindow(player, val, true);
|
||||
}
|
||||
|
||||
public final void showBuyWindow(L2PcInstance player, int val, boolean applyTax)
|
||||
public final void showBuyWindow(L2PcInstance player, int val, boolean applyCastleTax)
|
||||
{
|
||||
final L2BuyList buyList = BuyListData.getInstance().getBuyList(val);
|
||||
final ProductList buyList = BuyListData.getInstance().getBuyList(val);
|
||||
if (buyList == null)
|
||||
{
|
||||
_log.warning("BuyList not found! BuyListId:" + val);
|
||||
@@ -90,23 +88,7 @@ public class L2MerchantInstance extends L2NpcInstance
|
||||
|
||||
player.setInventoryBlockingStatus(true);
|
||||
|
||||
player.sendPacket(new BuyList(buyList, player.getAdena(), (applyTax) ? getTotalTaxRate(TaxType.BUY) : 0));
|
||||
player.sendPacket(new ExBuySellList(player, false, (applyTax) ? getTotalTaxRate(TaxType.SELL) : 0));
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
public boolean hasCastle()
|
||||
{
|
||||
return getCastle() != null;
|
||||
}
|
||||
|
||||
public int getTotalTax(TaxType taxType)
|
||||
{
|
||||
return hasCastle() ? getCastle().getTaxPercent(taxType) : 0;
|
||||
}
|
||||
|
||||
public double getTotalTaxRate(TaxType taxType)
|
||||
{
|
||||
return getTotalTax(taxType) / 100.0;
|
||||
player.sendPacket(new BuyList(buyList, player, (applyCastleTax) ? getCastleTaxRate(TaxType.BUY) : 0));
|
||||
player.sendPacket(new ExBuySellList(player, false, (applyCastleTax) ? getCastleTaxRate(TaxType.SELL) : 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,6 @@ import com.l2jmobius.gameserver.model.actor.stat.PcStat;
|
||||
import com.l2jmobius.gameserver.model.actor.status.PcStatus;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.DismountTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.FameTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.GameGuardCheckTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.HennaDurationTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.InventoryEnableTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.player.PetFeedTask;
|
||||
@@ -211,6 +210,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerSubCh
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MovieHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PlayerEventHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.SellBuffHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillUseHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.TrainingHolder;
|
||||
@@ -234,7 +234,6 @@ import com.l2jmobius.gameserver.model.items.type.ArmorType;
|
||||
import com.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||
import com.l2jmobius.gameserver.model.items.type.WeaponType;
|
||||
import com.l2jmobius.gameserver.model.matching.MatchingRoom;
|
||||
import com.l2jmobius.gameserver.model.multisell.PreparedListContainer;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadGameManager;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadGameTask;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
|
||||
@@ -288,7 +287,6 @@ import com.l2jmobius.gameserver.network.serverpackets.ExUseSharedGroupItem;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoAbnormalVisualEffect;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoCubic;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.GameGuardQuery;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.GetOnVehicle;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.HennaInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
@@ -557,7 +555,7 @@ public final class L2PcInstance extends L2Playable
|
||||
private TradeList _buyList;
|
||||
|
||||
// Multisell
|
||||
private PreparedListContainer _currentMultiSell = null;
|
||||
private PreparedMultisellListHolder _currentMultiSell = null;
|
||||
|
||||
private boolean _noble = false;
|
||||
private boolean _hero = false;
|
||||
@@ -4305,6 +4303,8 @@ public final class L2PcInstance extends L2Playable
|
||||
return getClan().getAllyCrestId();
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
/*
|
||||
public void queryGameGuard()
|
||||
{
|
||||
if (getClient() != null)
|
||||
@@ -4314,9 +4314,10 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
if (Config.GAMEGUARD_ENFORCE)
|
||||
{
|
||||
ThreadPoolManager.schedule(new GameGuardCheckTask(this), 30 * 1000);
|
||||
ThreadPoolManager.scheduleGeneral(new GameGuardCheckTask(this), 30 * 1000);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
//@formatter:on
|
||||
|
||||
/**
|
||||
* Send a Server->Client packet StatusUpdate to the L2PcInstance.
|
||||
@@ -4681,12 +4682,12 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
}
|
||||
|
||||
public final PreparedListContainer getMultiSell()
|
||||
public final PreparedMultisellListHolder getMultiSell()
|
||||
{
|
||||
return _currentMultiSell;
|
||||
}
|
||||
|
||||
public final void setMultiSell(PreparedListContainer list)
|
||||
public final void setMultiSell(PreparedMultisellListHolder list)
|
||||
{
|
||||
_currentMultiSell = list;
|
||||
}
|
||||
|
||||
@@ -25,9 +25,11 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.model.items.type.EtcItemType;
|
||||
|
||||
/**
|
||||
* @author NosBit
|
||||
@@ -41,28 +43,25 @@ public final class Product
|
||||
private final long _price;
|
||||
private final long _restockDelay;
|
||||
private final long _maxCount;
|
||||
private final double _baseTax;
|
||||
private AtomicLong _count = null;
|
||||
private ScheduledFuture<?> _restockTask = null;
|
||||
|
||||
public Product(int buyListId, L2Item item, long price, long restockDelay, long maxCount)
|
||||
public Product(int buyListId, L2Item item, long price, long restockDelay, long maxCount, int baseTax)
|
||||
{
|
||||
Objects.requireNonNull(item);
|
||||
_buyListId = buyListId;
|
||||
_item = item;
|
||||
_price = price;
|
||||
_price = (price < 0) ? item.getReferencePrice() : price;
|
||||
_restockDelay = restockDelay * 60000;
|
||||
_maxCount = maxCount;
|
||||
_baseTax = baseTax / 100.0;
|
||||
if (hasLimitedStock())
|
||||
{
|
||||
_count = new AtomicLong(maxCount);
|
||||
}
|
||||
}
|
||||
|
||||
public int getBuyListId()
|
||||
{
|
||||
return _buyListId;
|
||||
}
|
||||
|
||||
public L2Item getItem()
|
||||
{
|
||||
return _item;
|
||||
@@ -75,11 +74,17 @@ public final class Product
|
||||
|
||||
public long getPrice()
|
||||
{
|
||||
if (_price < 0)
|
||||
long price = _price;
|
||||
if (_item.getItemType().equals(EtcItemType.CASTLE_GUARD))
|
||||
{
|
||||
return getItem().getReferencePrice();
|
||||
price *= Config.RATE_SIEGE_GUARDS_PRICE;
|
||||
}
|
||||
return _price;
|
||||
return price;
|
||||
}
|
||||
|
||||
public double getBaseTaxRate()
|
||||
{
|
||||
return _baseTax;
|
||||
}
|
||||
|
||||
public long getRestockDelay()
|
||||
@@ -155,7 +160,7 @@ public final class Product
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("INSERT INTO `buylists`(`buylist_id`, `item_id`, `count`, `next_restock_time`) VALUES(?, ?, ?, ?) ON DUPLICATE KEY UPDATE `count` = ?, `next_restock_time` = ?"))
|
||||
{
|
||||
statement.setInt(1, getBuyListId());
|
||||
statement.setInt(1, _buyListId);
|
||||
statement.setInt(2, getItemId());
|
||||
statement.setLong(3, getCount());
|
||||
statement.setLong(5, getCount());
|
||||
@@ -174,7 +179,7 @@ public final class Product
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Failed to save Product buylist_id:" + getBuyListId() + " item_id:" + getItemId(), e);
|
||||
_log.log(Level.WARNING, "Failed to save Product buylist_id:" + _buyListId + " item_id:" + getItemId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,13 +25,13 @@ import java.util.Set;
|
||||
/**
|
||||
* @author NosBit
|
||||
*/
|
||||
public final class L2BuyList
|
||||
public final class ProductList
|
||||
{
|
||||
private final int _listId;
|
||||
private final Map<Integer, Product> _products = new LinkedHashMap<>();
|
||||
private Set<Integer> _allowedNpcs = null;
|
||||
|
||||
public L2BuyList(int listId)
|
||||
public ProductList(int listId)
|
||||
{
|
||||
_listId = listId;
|
||||
}
|
||||
@@ -70,8 +70,8 @@ public final class L2BuyList
|
||||
return (_allowedNpcs != null) && _allowedNpcs.contains(npcId);
|
||||
}
|
||||
|
||||
public Set<Integer> getNpcsAllowed()
|
||||
{
|
||||
return _allowedNpcs;
|
||||
}
|
||||
//public Set<Integer> getNpcsAllowed()
|
||||
//{
|
||||
// return _allowedNpcs;
|
||||
//}
|
||||
}
|
||||
@@ -49,4 +49,10 @@ public class EnsoulOption extends SkillHolder
|
||||
{
|
||||
return _desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Ensoul Id: " + _id + " Name: " + _name + " Desc: " + _desc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,6 @@ public final class Castle extends AbstractResidence
|
||||
private boolean _isTimeRegistrationOver = true; // true if Castle Lords set the time, or 24h is elapsed after the siege
|
||||
private Calendar _siegeTimeRegistrationEndDate; // last siege end date + 1 day
|
||||
private CastleSide _castleSide = null;
|
||||
private double _taxRate;
|
||||
private long _treasury = 0;
|
||||
private boolean _showNpcCrest = false;
|
||||
private L2SiegeZone _zone = null;
|
||||
@@ -301,7 +300,7 @@ public final class Castle extends AbstractResidence
|
||||
final Castle rune = CastleManager.getInstance().getCastle("rune");
|
||||
if (rune != null)
|
||||
{
|
||||
final long runeTax = (long) (amount * rune.getTaxRate());
|
||||
final long runeTax = (long) (amount * rune.getTaxRate(TaxType.BUY));
|
||||
if (rune.getOwnerId() > 0)
|
||||
{
|
||||
rune.addToTreasury(runeTax);
|
||||
@@ -319,7 +318,7 @@ public final class Castle extends AbstractResidence
|
||||
final Castle aden = CastleManager.getInstance().getCastle("aden");
|
||||
if (aden != null)
|
||||
{
|
||||
final long adenTax = (long) (amount * aden.getTaxRate()); // Find out what Aden gets from the current castle instance's income
|
||||
final long adenTax = (long) (amount * aden.getTaxRate(TaxType.BUY)); // Find out what Aden gets from the current castle instance's income
|
||||
if (aden.getOwnerId() > 0)
|
||||
{
|
||||
aden.addToTreasury(adenTax); // Only bother to really add the tax to the treasury if not npc owned
|
||||
@@ -673,7 +672,6 @@ public final class Castle extends AbstractResidence
|
||||
}
|
||||
}
|
||||
|
||||
setTaxRate(getTaxPercent(TaxType.BUY) / 100);
|
||||
ps2.setInt(1, getResidenceId());
|
||||
try (ResultSet rs = ps2.executeQuery())
|
||||
{
|
||||
@@ -980,14 +978,9 @@ public final class Castle extends AbstractResidence
|
||||
return taxPercent;
|
||||
}
|
||||
|
||||
public void setTaxRate(double taxRate)
|
||||
public final double getTaxRate(TaxType taxType)
|
||||
{
|
||||
_taxRate = taxRate;
|
||||
}
|
||||
|
||||
public final double getTaxRate()
|
||||
{
|
||||
return _taxRate;
|
||||
return getTaxPercent(taxType) / 100.0;
|
||||
}
|
||||
|
||||
public final long getTreasury()
|
||||
@@ -1229,7 +1222,6 @@ public final class Castle extends AbstractResidence
|
||||
_log.log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
_castleSide = side;
|
||||
setTaxRate(getTaxPercent(TaxType.BUY) / 100);
|
||||
Broadcast.toAllOnlinePlayers(new ExCastleState(this));
|
||||
spawnSideNpcs();
|
||||
}
|
||||
|
||||
@@ -2700,7 +2700,7 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
||||
// set enchant level for item if that item is not adena
|
||||
if ((attributeType != null) && (attributeValue > 0))
|
||||
{
|
||||
item.setAttribute(new AttributeHolder(attributeType, attributeValue));
|
||||
item.setAttribute(new AttributeHolder(attributeType, attributeValue), true);
|
||||
if (item.isEquipped())
|
||||
{
|
||||
// Recalculate all stats
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.events.impl.character.player;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Augmentation;
|
||||
import com.l2jmobius.gameserver.model.Augmentation;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventType;
|
||||
import com.l2jmobius.gameserver.model.events.impl.IBaseEvent;
|
||||
@@ -29,10 +29,10 @@ public class OnPlayerAugment implements IBaseEvent
|
||||
{
|
||||
private final L2PcInstance _activeChar;
|
||||
private final L2ItemInstance _item;
|
||||
private final L2Augmentation _augmentation;
|
||||
private final Augmentation _augmentation;
|
||||
private final boolean _isAugment; // true = is being augmented // false = augment is being removed
|
||||
|
||||
public OnPlayerAugment(L2PcInstance activeChar, L2ItemInstance item, L2Augmentation augment, boolean isAugment)
|
||||
public OnPlayerAugment(L2PcInstance activeChar, L2ItemInstance item, Augmentation augment, boolean isAugment)
|
||||
{
|
||||
_activeChar = activeChar;
|
||||
_item = item;
|
||||
@@ -50,7 +50,7 @@ public class OnPlayerAugment implements IBaseEvent
|
||||
return _item;
|
||||
}
|
||||
|
||||
public L2Augmentation getAugmentation()
|
||||
public Augmentation getAugmentation()
|
||||
{
|
||||
return _augmentation;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.holders;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
|
||||
/**
|
||||
* A DTO for items; contains item ID, count and chance.<br>
|
||||
* Complemented by {@link QuestItemHolder}.
|
||||
@@ -45,6 +49,34 @@ public class ItemChanceHolder extends ItemHolder
|
||||
return _chance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a cumulative chance of all given holders. If all holders' chance sum up to 100% or above, there is 100% guarantee a holder will be selected.
|
||||
* @param holders list of holders to calculate chance from.
|
||||
* @return {@code ItemChanceHolder} of the successful random roll or {@code null} if there was no lucky holder selected.
|
||||
*/
|
||||
public static ItemChanceHolder getRandomHolder(List<ItemChanceHolder> holders)
|
||||
{
|
||||
double itemRandom = 100 * Rnd.nextDouble();
|
||||
|
||||
for (ItemChanceHolder holder : holders)
|
||||
{
|
||||
// Any mathmatical expression including NaN will result in either NaN or 0 of converted to something other than double.
|
||||
// We would usually want to skip calculating any holders that include NaN as a chance, because that ruins the overall process.
|
||||
if (!Double.isNaN(holder.getChance()))
|
||||
{
|
||||
// Calculate chance
|
||||
if (holder.getChance() > itemRandom)
|
||||
{
|
||||
return holder;
|
||||
}
|
||||
|
||||
itemRandom -= holder.getChance();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
|
||||
/**
|
||||
* @author Nik
|
||||
*/
|
||||
public class MultisellEntryHolder
|
||||
{
|
||||
private final boolean _stackable;
|
||||
private final List<ItemHolder> _ingredients;
|
||||
private final List<ItemChanceHolder> _products;
|
||||
|
||||
public MultisellEntryHolder(List<ItemHolder> ingredients, List<ItemChanceHolder> products)
|
||||
{
|
||||
_ingredients = Collections.unmodifiableList(ingredients);
|
||||
_products = Collections.unmodifiableList(products);
|
||||
_stackable = products.stream().map(i -> ItemTable.getInstance().getTemplate(i.getId())).filter(Objects::nonNull).allMatch(L2Item::isStackable);
|
||||
}
|
||||
|
||||
public final List<ItemHolder> getIngredients()
|
||||
{
|
||||
return _ingredients;
|
||||
}
|
||||
|
||||
public final List<ItemChanceHolder> getProducts()
|
||||
{
|
||||
return _products;
|
||||
}
|
||||
|
||||
public final boolean isStackable()
|
||||
{
|
||||
return _stackable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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 java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.interfaces.IIdentifiable;
|
||||
|
||||
/**
|
||||
* A static list container of all multisell entries of a given list.
|
||||
* @author Nik
|
||||
*/
|
||||
public class MultisellListHolder implements IIdentifiable
|
||||
{
|
||||
private final int _listId;
|
||||
private final boolean _isChanceMultisell;
|
||||
private final boolean _applyTaxes;
|
||||
private final boolean _maintainEnchantment;
|
||||
private final double _ingredientMultiplier;
|
||||
private final double _productMultiplier;
|
||||
|
||||
protected List<MultisellEntryHolder> _entries;
|
||||
protected final Set<Integer> _npcsAllowed;
|
||||
|
||||
public MultisellListHolder(int listId, boolean isChanceMultisell, boolean applyTaxes, boolean maintainEnchantment, double ingredientMultiplier, double productMultiplier, List<MultisellEntryHolder> entries, Set<Integer> npcsAllowed)
|
||||
{
|
||||
_listId = listId;
|
||||
_isChanceMultisell = isChanceMultisell;
|
||||
_applyTaxes = applyTaxes;
|
||||
_maintainEnchantment = maintainEnchantment;
|
||||
_ingredientMultiplier = ingredientMultiplier;
|
||||
_productMultiplier = productMultiplier;
|
||||
_entries = entries;
|
||||
_npcsAllowed = npcsAllowed;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public MultisellListHolder(StatsSet set)
|
||||
{
|
||||
_listId = set.getInt("listId");
|
||||
_isChanceMultisell = set.getBoolean("isChanceMultisell", false);
|
||||
_applyTaxes = set.getBoolean("applyTaxes", false);
|
||||
_maintainEnchantment = set.getBoolean("maintainEnchantment", false);
|
||||
_ingredientMultiplier = set.getDouble("ingredientMultiplier", 1.0);
|
||||
_productMultiplier = set.getDouble("productMultiplier", 1.0);
|
||||
_entries = Collections.unmodifiableList(set.getList("entries", MultisellEntryHolder.class, Collections.emptyList()));
|
||||
_npcsAllowed = set.getObject("allowNpc", Set.class);
|
||||
}
|
||||
|
||||
public List<MultisellEntryHolder> getEntries()
|
||||
{
|
||||
return _entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getId()
|
||||
{
|
||||
return _listId;
|
||||
}
|
||||
|
||||
public final boolean isChanceMultisell()
|
||||
{
|
||||
return _isChanceMultisell;
|
||||
}
|
||||
|
||||
public final boolean isApplyTaxes()
|
||||
{
|
||||
return _applyTaxes;
|
||||
}
|
||||
|
||||
public final boolean isMaintainEnchantment()
|
||||
{
|
||||
return _maintainEnchantment;
|
||||
}
|
||||
|
||||
public final double getIngredientMultiplier()
|
||||
{
|
||||
return _ingredientMultiplier;
|
||||
}
|
||||
|
||||
public final double getProductMultiplier()
|
||||
{
|
||||
return _productMultiplier;
|
||||
}
|
||||
|
||||
public final boolean isNpcAllowed(int npcId)
|
||||
{
|
||||
return (_npcsAllowed == null) || _npcsAllowed.contains(npcId);
|
||||
}
|
||||
|
||||
public final boolean isNpcOnly()
|
||||
{
|
||||
return _npcsAllowed != null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.TaxType;
|
||||
import com.l2jmobius.gameserver.model.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.ItemContainer;
|
||||
|
||||
/**
|
||||
* A modified version of {@link MultisellListHolder} that may include altered data of the original and other dynamic data resulted from players' interraction.
|
||||
* @author Nik
|
||||
*/
|
||||
public class PreparedMultisellListHolder extends MultisellListHolder
|
||||
{
|
||||
private int _npcObjectId;
|
||||
private final boolean _inventoryOnly;
|
||||
private double _taxRate;
|
||||
private List<ItemInfo> _itemInfos;
|
||||
|
||||
public PreparedMultisellListHolder(MultisellListHolder list, boolean inventoryOnly, ItemContainer inventory, L2Npc npc, double ingredientMultiplier, double productMultiplier)
|
||||
{
|
||||
super(list.getId(), list.isChanceMultisell(), list.isApplyTaxes(), list.isMaintainEnchantment(), list.getIngredientMultiplier(), list.getProductMultiplier(), list._entries, list._npcsAllowed);
|
||||
|
||||
_inventoryOnly = inventoryOnly;
|
||||
|
||||
if (npc != null)
|
||||
{
|
||||
_npcObjectId = npc.getObjectId();
|
||||
_taxRate = npc.getCastleTaxRate(TaxType.BUY);
|
||||
}
|
||||
|
||||
// Display items from inventory that are available for exchange.
|
||||
if (inventoryOnly)
|
||||
{
|
||||
_entries = new ArrayList<>();
|
||||
_itemInfos = new ArrayList<>();
|
||||
|
||||
// Only do the match up on equippable items that are not currently equipped. For each appropriate item, produce a set of entries for the multisell list.
|
||||
inventory.getItems(item -> !item.isEquipped() && (item.isArmor() || item.isWeapon())).forEach(item ->
|
||||
{
|
||||
// Check ingredients of each entry to see if it's an entry we'd like to include.
|
||||
list.getEntries().stream().filter(e -> e.getIngredients().stream().anyMatch(i -> i.getId() == item.getId())).forEach(e ->
|
||||
{
|
||||
_entries.add(e);
|
||||
_itemInfos.add(new ItemInfo(item));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ItemInfo getItemEnchantment(int index)
|
||||
{
|
||||
return _itemInfos != null ? _itemInfos.get(index) : null;
|
||||
}
|
||||
|
||||
public double getTaxRate()
|
||||
{
|
||||
return isApplyTaxes() ? _taxRate : 0;
|
||||
}
|
||||
|
||||
public boolean isInventoryOnly()
|
||||
{
|
||||
return _inventoryOnly;
|
||||
}
|
||||
|
||||
public final boolean checkNpcObjectId(int npcObjectId)
|
||||
{
|
||||
return (_npcObjectId == 0) || (_npcObjectId == npcObjectId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ingredient
|
||||
* @return the new count of the given ingredient after applying ingredient multiplier and adena tax rate.
|
||||
*/
|
||||
public long getIngredientCount(ItemHolder ingredient)
|
||||
{
|
||||
return (ingredient.getId() == Inventory.ADENA_ID) ? Math.round(ingredient.getCount() * getIngredientMultiplier() * (1 + _taxRate)) : Math.round(ingredient.getCount() * getIngredientMultiplier());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param product
|
||||
* @return the new count of the given product after applying product multiplier.
|
||||
*/
|
||||
public long getProductCount(ItemChanceHolder product)
|
||||
{
|
||||
return Math.round(product.getCount() * getProductMultiplier());
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,10 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.itemauction;
|
||||
|
||||
import com.l2jmobius.gameserver.datatables.AugmentationData;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.model.L2Augmentation;
|
||||
import com.l2jmobius.gameserver.model.Augmentation;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
@@ -83,10 +84,10 @@ public final class AuctionItem
|
||||
L2World.getInstance().storeObject(item);
|
||||
item.setCount(_itemCount);
|
||||
item.setEnchantLevel(item.getItem().getDefaultEnchantLevel());
|
||||
final int augmentationId = _itemExtra.getInt("augmentation_id", 0);
|
||||
if (augmentationId > 0)
|
||||
final Augmentation augmentation = AugmentationData.getInstance().getAugmentation(_itemExtra.getInt("augmentation_id", 0));
|
||||
if (augmentation != null)
|
||||
{
|
||||
item.setAugmentation(new L2Augmentation(augmentationId));
|
||||
item.setAugmentation(augmentation, false);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.enums.ItemLocation;
|
||||
import com.l2jmobius.gameserver.enums.ItemSkillType;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.Augmentation;
|
||||
import com.l2jmobius.gameserver.model.L2ArmorSet;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.PcCondOverride;
|
||||
@@ -1021,10 +1022,10 @@ public abstract class Inventory extends ItemContainer
|
||||
return (item != null) ? item.getVisualId() : 0;
|
||||
}
|
||||
|
||||
public int getPaperdollAugmentationId(int slot)
|
||||
public Augmentation getPaperdollAugmentation(int slot)
|
||||
{
|
||||
final L2ItemInstance item = _paperdoll[slot];
|
||||
return ((item != null) && (item.getAugmentation() != null)) ? item.getAugmentation().getId() : 0;
|
||||
return (item != null) ? item.getAugmentation() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -159,50 +159,6 @@ public class PcInventory extends Inventory
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of items in inventory available for transaction Allows an item to appear twice if and only if there is a difference in enchantment level.
|
||||
* @param allowAdena
|
||||
* @param allowAncientAdena
|
||||
* @return L2ItemInstance : items in inventory
|
||||
*/
|
||||
public Collection<L2ItemInstance> getUniqueItemsByEnchantLevel(boolean allowAdena, boolean allowAncientAdena)
|
||||
{
|
||||
return getUniqueItemsByEnchantLevel(allowAdena, allowAncientAdena, true);
|
||||
}
|
||||
|
||||
public Collection<L2ItemInstance> getUniqueItemsByEnchantLevel(boolean allowAdena, boolean allowAncientAdena, boolean onlyAvailable)
|
||||
{
|
||||
final Collection<L2ItemInstance> list = new LinkedList<>();
|
||||
for (L2ItemInstance item : _items.values())
|
||||
{
|
||||
if (!allowAdena && (item.getId() == ADENA_ID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!allowAncientAdena && (item.getId() == ANCIENT_ADENA_ID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean isDuplicate = false;
|
||||
for (L2ItemInstance litem : list)
|
||||
{
|
||||
if ((litem.getId() == item.getId()) && (litem.getEnchantLevel() == item.getEnchantLevel()))
|
||||
{
|
||||
isDuplicate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isDuplicate && (!onlyAvailable || (item.isSellable() && item.isAvailable(getOwner(), false, false))))
|
||||
{
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemId
|
||||
* @return
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.AttributeType;
|
||||
import com.l2jmobius.gameserver.model.Augmentation;
|
||||
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.items.type.CrystalType;
|
||||
@@ -44,8 +45,7 @@ public class L2WarehouseItem
|
||||
private final int _locationSlot;
|
||||
private final int _enchant;
|
||||
private final CrystalType _grade;
|
||||
private boolean _isAugmented;
|
||||
private int _augmentationId;
|
||||
private final Augmentation _augmentation;
|
||||
private final int _customType1;
|
||||
private final int _customType2;
|
||||
private final int _mana;
|
||||
@@ -81,15 +81,7 @@ public class L2WarehouseItem
|
||||
_customType1 = item.getCustomType1();
|
||||
_customType2 = item.getCustomType2();
|
||||
_grade = item.getItem().getCrystalType();
|
||||
if (item.isAugmented())
|
||||
{
|
||||
_isAugmented = true;
|
||||
_augmentationId = item.getAugmentation().getId();
|
||||
}
|
||||
else
|
||||
{
|
||||
_isAugmented = false;
|
||||
}
|
||||
_augmentation = item.getAugmentation();
|
||||
_mana = item.getMana();
|
||||
_time = item.isTimeLimitedItem() ? (int) (item.getRemainingTime() / 1000) : -1;
|
||||
|
||||
@@ -232,20 +224,12 @@ public class L2WarehouseItem
|
||||
return _item.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the item is augmented, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isAugmented()
|
||||
{
|
||||
return _isAugmented;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the augmentation If.
|
||||
*/
|
||||
public int getAugmentationId()
|
||||
public Augmentation getAugmentation()
|
||||
{
|
||||
return _augmentationId;
|
||||
return _augmentation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.l2jmobius.gameserver.data.xml.impl.AppearanceItemData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EnchantItemOptionsData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EnsoulData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.OptionData;
|
||||
import com.l2jmobius.gameserver.datatables.AugmentationData;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.enums.AttributeType;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
@@ -53,8 +54,8 @@ import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.SiegeGuardManager;
|
||||
import com.l2jmobius.gameserver.model.Augmentation;
|
||||
import com.l2jmobius.gameserver.model.DropProtection;
|
||||
import com.l2jmobius.gameserver.model.L2Augmentation;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||
@@ -135,7 +136,7 @@ public final class L2ItemInstance extends L2Object
|
||||
private boolean _wear;
|
||||
|
||||
/** Augmented Item */
|
||||
private L2Augmentation _augmentation = null;
|
||||
private Augmentation _augmentation = null;
|
||||
|
||||
/** Shadow item */
|
||||
private int _mana = -1;
|
||||
@@ -948,7 +949,7 @@ public final class L2ItemInstance extends L2Object
|
||||
* Returns the augmentation object for this item
|
||||
* @return augmentation
|
||||
*/
|
||||
public L2Augmentation getAugmentation()
|
||||
public Augmentation getAugmentation()
|
||||
{
|
||||
return _augmentation;
|
||||
}
|
||||
@@ -956,9 +957,10 @@ public final class L2ItemInstance extends L2Object
|
||||
/**
|
||||
* Sets a new augmentation
|
||||
* @param augmentation
|
||||
* @param updateDatabase
|
||||
* @return return true if successfully
|
||||
*/
|
||||
public boolean setAugmentation(L2Augmentation augmentation)
|
||||
public boolean setAugmentation(Augmentation augmentation, boolean updateDatabase)
|
||||
{
|
||||
// there shall be no previous augmentation..
|
||||
if (_augmentation != null)
|
||||
@@ -968,13 +970,9 @@ public final class L2ItemInstance extends L2Object
|
||||
}
|
||||
|
||||
_augmentation = augmentation;
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection())
|
||||
if (updateDatabase)
|
||||
{
|
||||
updateItemAttributes(con);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Could not update atributes for item: " + this + " from DB:", e);
|
||||
updateItemOptions();
|
||||
}
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerAugment(getActingPlayer(), this, augmentation, true), getItem());
|
||||
return true;
|
||||
@@ -991,7 +989,7 @@ public final class L2ItemInstance extends L2Object
|
||||
}
|
||||
|
||||
// Copy augmentation before removing it.
|
||||
final L2Augmentation augment = _augmentation;
|
||||
final Augmentation augment = _augmentation;
|
||||
_augmentation = null;
|
||||
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
@@ -1023,7 +1021,7 @@ public final class L2ItemInstance extends L2Object
|
||||
final int aug_attributes = rs.getInt(1);
|
||||
if (aug_attributes != -1)
|
||||
{
|
||||
_augmentation = new L2Augmentation(rs.getInt("augAttributes"));
|
||||
_augmentation = AugmentationData.getInstance().getAugmentation(rs.getInt("augAttributes"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1048,7 +1046,19 @@ public final class L2ItemInstance extends L2Object
|
||||
}
|
||||
}
|
||||
|
||||
private void updateItemAttributes(Connection con)
|
||||
public void updateItemOptions()
|
||||
{
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection())
|
||||
{
|
||||
updateItemOptions(con);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Could not update atributes for item: " + toString() + " from DB:", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateItemOptions(Connection con)
|
||||
{
|
||||
try (PreparedStatement ps = con.prepareStatement("REPLACE INTO item_attributes VALUES(?,?)"))
|
||||
{
|
||||
@@ -1062,6 +1072,18 @@ public final class L2ItemInstance extends L2Object
|
||||
}
|
||||
}
|
||||
|
||||
public void updateItemElementals()
|
||||
{
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection())
|
||||
{
|
||||
updateItemElements(con);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Could not update elementals for item: " + toString() + " from DB: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateItemElements(Connection con)
|
||||
{
|
||||
try (PreparedStatement ps = con.prepareStatement("DELETE FROM item_elementals WHERE itemId = ?"))
|
||||
@@ -1187,17 +1209,14 @@ public final class L2ItemInstance extends L2Object
|
||||
/**
|
||||
* Add elemental attribute to item and save to db
|
||||
* @param holder
|
||||
* @param updateDatabase
|
||||
*/
|
||||
public void setAttribute(AttributeHolder holder)
|
||||
public void setAttribute(AttributeHolder holder, boolean updateDatabase)
|
||||
{
|
||||
applyAttribute(holder);
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection())
|
||||
if (updateDatabase)
|
||||
{
|
||||
updateItemElements(con);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Could not update elementals for item: " + this + " from DB:", e);
|
||||
updateItemElementals();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1646,12 +1665,16 @@ public final class L2ItemInstance extends L2Object
|
||||
|
||||
if (_augmentation != null)
|
||||
{
|
||||
updateItemAttributes(con);
|
||||
updateItemOptions(con);
|
||||
}
|
||||
if (_elementals != null)
|
||||
{
|
||||
updateItemElements(con);
|
||||
}
|
||||
if ((_ensoulOptions != null) || (_ensoulSpecialOptions != null))
|
||||
{
|
||||
updateSpecialAbilities(con);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -2217,10 +2240,21 @@ public final class L2ItemInstance extends L2Object
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSpecialAbilities()
|
||||
public void updateSpecialAbilities()
|
||||
{
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("INSERT INTO item_special_abilities (`objectId`, `type`, `optionId`, `position`) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE type = ?, optionId = ?, position = ?"))
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection())
|
||||
{
|
||||
updateSpecialAbilities(con);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Couldn't update item special abilities", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSpecialAbilities(Connection con)
|
||||
{
|
||||
try (PreparedStatement ps = con.prepareStatement("INSERT INTO item_special_abilities (`objectId`, `type`, `optionId`, `position`) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE type = ?, optionId = ?, position = ?"))
|
||||
{
|
||||
ps.setInt(1, getObjectId());
|
||||
for (Entry<Integer, EnsoulOption> entry : _ensoulOptions.entrySet())
|
||||
|
||||
@@ -1,91 +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.multisell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author DS
|
||||
*/
|
||||
public class Entry
|
||||
{
|
||||
protected int _entryId;
|
||||
protected boolean _stackable = true;
|
||||
|
||||
protected List<Ingredient> _products;
|
||||
protected List<Ingredient> _ingredients;
|
||||
|
||||
public Entry(int entryId)
|
||||
{
|
||||
_entryId = entryId;
|
||||
_products = new ArrayList<>();
|
||||
_ingredients = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor used in PreparedEntry only, ArrayLists not created.
|
||||
*/
|
||||
protected Entry()
|
||||
{
|
||||
}
|
||||
|
||||
public final void setEntryId(int id)
|
||||
{
|
||||
_entryId = id;
|
||||
}
|
||||
|
||||
public final int getEntryId()
|
||||
{
|
||||
return _entryId;
|
||||
}
|
||||
|
||||
public final void addProduct(Ingredient product)
|
||||
{
|
||||
_products.add(product);
|
||||
|
||||
if (!product.isStackable())
|
||||
{
|
||||
_stackable = false;
|
||||
}
|
||||
}
|
||||
|
||||
public final List<Ingredient> getProducts()
|
||||
{
|
||||
return _products;
|
||||
}
|
||||
|
||||
public final void addIngredient(Ingredient ingredient)
|
||||
{
|
||||
_ingredients.add(ingredient);
|
||||
}
|
||||
|
||||
public final List<Ingredient> getIngredients()
|
||||
{
|
||||
return _ingredients;
|
||||
}
|
||||
|
||||
public final boolean isStackable()
|
||||
{
|
||||
return _stackable;
|
||||
}
|
||||
|
||||
public long getTaxAmount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,151 +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.multisell;
|
||||
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.items.L2Armor;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.model.items.L2Weapon;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
|
||||
/**
|
||||
* @author DS
|
||||
*/
|
||||
public class Ingredient
|
||||
{
|
||||
private int _itemId;
|
||||
private long _itemCount;
|
||||
private final int _enchantmentLevel;
|
||||
private boolean _isTaxIngredient;
|
||||
private boolean _maintainIngredient;
|
||||
private L2Item _template = null;
|
||||
private ItemInfo _itemInfo = null;
|
||||
private final double _chance;
|
||||
|
||||
public Ingredient(StatsSet set)
|
||||
{
|
||||
this(set.getInt("id"), set.getLong("count"), set.getInt("enchantmentLevel", 0), set.getDouble("chance", 0), set.getBoolean("isTaxIngredient", false), set.getBoolean("maintainIngredient", false));
|
||||
}
|
||||
|
||||
public Ingredient(int itemId, long itemCount, int enchantmentLevel, double chance, boolean isTaxIngredient, boolean maintainIngredient)
|
||||
{
|
||||
_itemId = itemId;
|
||||
_itemCount = itemCount;
|
||||
_enchantmentLevel = enchantmentLevel;
|
||||
_chance = chance;
|
||||
_isTaxIngredient = isTaxIngredient;
|
||||
_maintainIngredient = maintainIngredient;
|
||||
if (_itemId > 0)
|
||||
{
|
||||
_template = ItemTable.getInstance().getTemplate(_itemId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a new Ingredient instance with the same values as this.
|
||||
*/
|
||||
public Ingredient getCopy()
|
||||
{
|
||||
return new Ingredient(_itemId, _itemCount, _enchantmentLevel, _chance, _isTaxIngredient, _maintainIngredient);
|
||||
}
|
||||
|
||||
public final L2Item getTemplate()
|
||||
{
|
||||
return _template;
|
||||
}
|
||||
|
||||
public final void setItemInfo(L2ItemInstance item)
|
||||
{
|
||||
_itemInfo = new ItemInfo(item);
|
||||
}
|
||||
|
||||
public final void setItemInfo(ItemInfo info)
|
||||
{
|
||||
_itemInfo = info;
|
||||
}
|
||||
|
||||
public final ItemInfo getItemInfo()
|
||||
{
|
||||
return _itemInfo;
|
||||
}
|
||||
|
||||
public final int getEnchantLevel()
|
||||
{
|
||||
return _itemInfo == null ? _enchantmentLevel : _itemInfo.getEnchantLevel();
|
||||
}
|
||||
|
||||
public final void setItemId(int itemId)
|
||||
{
|
||||
_itemId = itemId;
|
||||
}
|
||||
|
||||
public final int getItemId()
|
||||
{
|
||||
return _itemId;
|
||||
}
|
||||
|
||||
public final void setItemCount(long itemCount)
|
||||
{
|
||||
_itemCount = itemCount;
|
||||
}
|
||||
|
||||
public final long getItemCount()
|
||||
{
|
||||
return _itemCount;
|
||||
}
|
||||
|
||||
public double getChance()
|
||||
{
|
||||
return _chance;
|
||||
}
|
||||
|
||||
public final void setIsTaxIngredient(boolean isTaxIngredient)
|
||||
{
|
||||
_isTaxIngredient = isTaxIngredient;
|
||||
}
|
||||
|
||||
public final boolean isTaxIngredient()
|
||||
{
|
||||
return _isTaxIngredient;
|
||||
}
|
||||
|
||||
public final void setMaintainIngredient(boolean maintainIngredient)
|
||||
{
|
||||
_maintainIngredient = maintainIngredient;
|
||||
}
|
||||
|
||||
public final boolean getMaintainIngredient()
|
||||
{
|
||||
return _maintainIngredient;
|
||||
}
|
||||
|
||||
public final boolean isStackable()
|
||||
{
|
||||
return (_template == null) || _template.isStackable();
|
||||
}
|
||||
|
||||
public final boolean isArmorOrWeapon()
|
||||
{
|
||||
return (_template != null) && ((_template instanceof L2Armor) || (_template instanceof L2Weapon));
|
||||
}
|
||||
|
||||
public final int getWeight()
|
||||
{
|
||||
return _template == null ? 0 : _template.getWeight();
|
||||
}
|
||||
}
|
||||
@@ -1,104 +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.multisell;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
|
||||
import com.l2jmobius.gameserver.model.items.enchant.attribute.AttributeHolder;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.variables.ItemVariables;
|
||||
|
||||
/**
|
||||
* @author DS
|
||||
*/
|
||||
public class ItemInfo
|
||||
{
|
||||
private final int _enchantLevel, _augmentId;
|
||||
private final byte _elementId;
|
||||
private final int _elementPower;
|
||||
private final AttributeHolder[] _attributes;
|
||||
private final int _visualId;
|
||||
private final int _visualStoneId;
|
||||
private final long _visualIdLifetime;
|
||||
private final Collection<EnsoulOption> _specialAbilities;
|
||||
private final Collection<EnsoulOption> _additionalSpecialAbilities;
|
||||
|
||||
public ItemInfo(L2ItemInstance item)
|
||||
{
|
||||
_enchantLevel = item.getEnchantLevel();
|
||||
_augmentId = item.getAugmentation() != null ? item.getAugmentation().getId() : 0;
|
||||
_elementId = item.getAttackAttributeType().getClientId();
|
||||
_elementPower = item.getAttackAttributePower();
|
||||
_attributes = item.getAttributes() != null ? item.getAttributes().toArray(new AttributeHolder[6]) : new AttributeHolder[6];
|
||||
_visualId = item.getVisualId();
|
||||
_visualStoneId = item.getVariables().getInt(ItemVariables.VISUAL_APPEARANCE_STONE_ID, 0);
|
||||
_visualIdLifetime = item.getVisualLifeTime();
|
||||
_specialAbilities = item.getSpecialAbilities();
|
||||
_additionalSpecialAbilities = item.getAdditionalSpecialAbilities();
|
||||
}
|
||||
|
||||
public final int getEnchantLevel()
|
||||
{
|
||||
return _enchantLevel;
|
||||
}
|
||||
|
||||
public final int getAugmentId()
|
||||
{
|
||||
return _augmentId;
|
||||
}
|
||||
|
||||
public final byte getElementId()
|
||||
{
|
||||
return _elementId;
|
||||
}
|
||||
|
||||
public final int getElementPower()
|
||||
{
|
||||
return _elementPower;
|
||||
}
|
||||
|
||||
public final AttributeHolder[] getElementals()
|
||||
{
|
||||
return _attributes;
|
||||
}
|
||||
|
||||
public int getVisualId()
|
||||
{
|
||||
return _visualId;
|
||||
}
|
||||
|
||||
public int getVisualStoneId()
|
||||
{
|
||||
return _visualStoneId;
|
||||
}
|
||||
|
||||
public long getVisualIdLifeTime()
|
||||
{
|
||||
return _visualIdLifetime;
|
||||
}
|
||||
|
||||
public Collection<EnsoulOption> getSpecialAbilities()
|
||||
{
|
||||
return _specialAbilities;
|
||||
}
|
||||
|
||||
public Collection<EnsoulOption> getAdditionalSpecialAbilities()
|
||||
{
|
||||
return _additionalSpecialAbilities;
|
||||
}
|
||||
}
|
||||
@@ -1,123 +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.multisell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author DS
|
||||
*/
|
||||
public class ListContainer
|
||||
{
|
||||
private final int _listId;
|
||||
private boolean _isChanceMultisell;
|
||||
private boolean _applyTaxes = false;
|
||||
private boolean _maintainEnchantment = false;
|
||||
private double _useRate = 1.0;
|
||||
|
||||
protected List<Entry> _entries = new ArrayList<>();
|
||||
protected Set<Integer> _npcsAllowed = null;
|
||||
|
||||
public ListContainer(int listId)
|
||||
{
|
||||
_listId = listId;
|
||||
}
|
||||
|
||||
public ListContainer(ListContainer container)
|
||||
{
|
||||
_listId = container.getListId();
|
||||
_isChanceMultisell = container.isChanceMultisell();
|
||||
_maintainEnchantment = container.getMaintainEnchantment();
|
||||
}
|
||||
|
||||
public final List<Entry> getEntries()
|
||||
{
|
||||
return _entries;
|
||||
}
|
||||
|
||||
public final int getListId()
|
||||
{
|
||||
return _listId;
|
||||
}
|
||||
|
||||
public boolean isChanceMultisell()
|
||||
{
|
||||
return _isChanceMultisell;
|
||||
}
|
||||
|
||||
public void setIsChanceMultisell(boolean val)
|
||||
{
|
||||
_isChanceMultisell = val;
|
||||
}
|
||||
|
||||
public final void setApplyTaxes(boolean applyTaxes)
|
||||
{
|
||||
_applyTaxes = applyTaxes;
|
||||
}
|
||||
|
||||
public final boolean getApplyTaxes()
|
||||
{
|
||||
return _applyTaxes;
|
||||
}
|
||||
|
||||
public final void setMaintainEnchantment(boolean maintainEnchantment)
|
||||
{
|
||||
_maintainEnchantment = maintainEnchantment;
|
||||
}
|
||||
|
||||
public double getUseRate()
|
||||
{
|
||||
return _useRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this to create multisell with increased products, all product counts will be multiplied by the rate specified.<br>
|
||||
* <b>NOTE:</b> It affects only parser, it won't change values of already parsed multisell since MultiSells' parseEntry method handles this feature.
|
||||
* @param rate
|
||||
*/
|
||||
public void setUseRate(double rate)
|
||||
{
|
||||
_useRate = rate;
|
||||
}
|
||||
|
||||
public final boolean getMaintainEnchantment()
|
||||
{
|
||||
return _maintainEnchantment;
|
||||
}
|
||||
|
||||
public void allowNpc(int npcId)
|
||||
{
|
||||
if (_npcsAllowed == null)
|
||||
{
|
||||
_npcsAllowed = new HashSet<>();
|
||||
}
|
||||
_npcsAllowed.add(npcId);
|
||||
}
|
||||
|
||||
public boolean isNpcAllowed(int npcId)
|
||||
{
|
||||
return (_npcsAllowed == null) || _npcsAllowed.contains(npcId);
|
||||
}
|
||||
|
||||
public boolean isNpcOnly()
|
||||
{
|
||||
return _npcsAllowed != null;
|
||||
}
|
||||
}
|
||||
@@ -1,107 +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.multisell;
|
||||
|
||||
import static com.l2jmobius.gameserver.model.itemcontainer.Inventory.ADENA_ID;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
|
||||
/**
|
||||
* @author DS
|
||||
*/
|
||||
public class PreparedEntry extends Entry
|
||||
{
|
||||
private long _taxAmount = 0;
|
||||
|
||||
public PreparedEntry(Entry template, L2ItemInstance item, boolean applyTaxes, boolean maintainEnchantment, double taxRate)
|
||||
{
|
||||
_entryId = template.getEntryId() * 100000;
|
||||
if (maintainEnchantment && (item != null))
|
||||
{
|
||||
_entryId += item.getEnchantLevel();
|
||||
}
|
||||
|
||||
ItemInfo info = null;
|
||||
long adenaAmount = 0;
|
||||
|
||||
_ingredients = new ArrayList<>(template.getIngredients().size());
|
||||
for (Ingredient ing : template.getIngredients())
|
||||
{
|
||||
if (ing.getItemId() == ADENA_ID)
|
||||
{
|
||||
// Tax ingredients added only if taxes enabled
|
||||
if (ing.isTaxIngredient())
|
||||
{
|
||||
// if taxes are to be applied, modify/add the adena count based on the template adena/ancient adena count
|
||||
if (applyTaxes)
|
||||
{
|
||||
_taxAmount += Math.round(ing.getItemCount() * taxRate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
adenaAmount += ing.getItemCount();
|
||||
}
|
||||
// do not yet add this adena amount to the list as non-taxIngredient adena might be entered later (order not guaranteed)
|
||||
continue;
|
||||
}
|
||||
if (maintainEnchantment && (item != null) && ing.isArmorOrWeapon())
|
||||
{
|
||||
info = new ItemInfo(item);
|
||||
final Ingredient newIngredient = ing.getCopy();
|
||||
newIngredient.setItemInfo(info);
|
||||
_ingredients.add(newIngredient);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ingredients.add(ing.getCopy());
|
||||
}
|
||||
}
|
||||
|
||||
// now add the adena, if any.
|
||||
adenaAmount += _taxAmount; // do not forget tax
|
||||
if (adenaAmount > 0)
|
||||
{
|
||||
_ingredients.add(new Ingredient(ADENA_ID, adenaAmount, 0, 0, false, false));
|
||||
}
|
||||
|
||||
// now copy products
|
||||
_products = new ArrayList<>(template.getProducts().size());
|
||||
for (Ingredient ing : template.getProducts())
|
||||
{
|
||||
if (!ing.isStackable())
|
||||
{
|
||||
_stackable = false;
|
||||
}
|
||||
|
||||
final Ingredient newProduct = ing.getCopy();
|
||||
if (maintainEnchantment && ing.isArmorOrWeapon())
|
||||
{
|
||||
newProduct.setItemInfo(info);
|
||||
}
|
||||
_products.add(newProduct);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getTaxAmount()
|
||||
{
|
||||
return _taxAmount;
|
||||
}
|
||||
}
|
||||
@@ -1,104 +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.multisell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.items.L2Armor;
|
||||
import com.l2jmobius.gameserver.model.items.L2Weapon;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
|
||||
public class PreparedListContainer extends ListContainer
|
||||
{
|
||||
private int _npcObjectId = 0;
|
||||
|
||||
public PreparedListContainer(ListContainer template, boolean inventoryOnly, L2PcInstance player, L2Npc npc)
|
||||
{
|
||||
super(template);
|
||||
|
||||
setMaintainEnchantment(template.getMaintainEnchantment());
|
||||
setApplyTaxes(false);
|
||||
double taxRate = 0;
|
||||
if (npc != null)
|
||||
{
|
||||
_npcObjectId = npc.getObjectId();
|
||||
if (template.getApplyTaxes() && npc.isInTown() && (npc.getCastle().getOwnerId() > 0))
|
||||
{
|
||||
setApplyTaxes(true);
|
||||
taxRate = npc.getCastle().getTaxRate();
|
||||
}
|
||||
}
|
||||
|
||||
if (inventoryOnly)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Collection<L2ItemInstance> items;
|
||||
if (getMaintainEnchantment())
|
||||
{
|
||||
items = player.getInventory().getUniqueItemsByEnchantLevel(false, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
items = player.getInventory().getUniqueItems(false, false, false);
|
||||
}
|
||||
|
||||
_entries = new LinkedList<>();
|
||||
for (L2ItemInstance item : items)
|
||||
{
|
||||
// only do the match up on equippable items that are not currently equipped
|
||||
// so for each appropriate item, produce a set of entries for the multisell list.
|
||||
if (!item.isEquipped() && ((item.getItem() instanceof L2Armor) || (item.getItem() instanceof L2Weapon)))
|
||||
{
|
||||
// loop through the entries to see which ones we wish to include
|
||||
for (Entry ent : template.getEntries())
|
||||
{
|
||||
// check ingredients of this entry to see if it's an entry we'd like to include.
|
||||
for (Ingredient ing : ent.getIngredients())
|
||||
{
|
||||
if (item.getId() == ing.getItemId())
|
||||
{
|
||||
_entries.add(new PreparedEntry(ent, item, getApplyTaxes(), getMaintainEnchantment(), taxRate));
|
||||
break; // next entry
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_entries = new ArrayList<>(template.getEntries().size());
|
||||
for (Entry ent : template.getEntries())
|
||||
{
|
||||
_entries.add(new PreparedEntry(ent, null, getApplyTaxes(), false, taxRate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean checkNpcObjectId(int npcObjectId)
|
||||
{
|
||||
return (_npcObjectId == 0) || (_npcObjectId == npcObjectId);
|
||||
}
|
||||
}
|
||||
@@ -32,12 +32,10 @@ import com.l2jmobius.gameserver.network.serverpackets.SkillCoolTime;
|
||||
public class Options
|
||||
{
|
||||
private final int _id;
|
||||
private final List<AbstractEffect> _effects = new ArrayList<>();
|
||||
|
||||
private SkillHolder _activeSkill = null;
|
||||
private SkillHolder _passiveSkill = null;
|
||||
|
||||
private final List<OptionsSkillHolder> _activationSkills = new ArrayList<>();
|
||||
private List<AbstractEffect> _effects = null;
|
||||
private List<SkillHolder> _activeSkill = null;
|
||||
private List<SkillHolder> _passiveSkill = null;
|
||||
private List<OptionsSkillHolder> _activationSkills = null;
|
||||
|
||||
/**
|
||||
* @param id
|
||||
@@ -54,6 +52,10 @@ public class Options
|
||||
|
||||
public void addEffect(AbstractEffect effect)
|
||||
{
|
||||
if (_effects == null)
|
||||
{
|
||||
_effects = new ArrayList<>();
|
||||
}
|
||||
_effects.add(effect);
|
||||
}
|
||||
|
||||
@@ -64,51 +66,62 @@ public class Options
|
||||
|
||||
public boolean hasEffects()
|
||||
{
|
||||
return !_effects.isEmpty();
|
||||
return _effects != null;
|
||||
}
|
||||
|
||||
public boolean hasActiveSkill()
|
||||
public boolean hasActiveSkills()
|
||||
{
|
||||
return _activeSkill != null;
|
||||
}
|
||||
|
||||
public SkillHolder getActiveSkill()
|
||||
public List<SkillHolder> getActiveSkills()
|
||||
{
|
||||
return _activeSkill;
|
||||
}
|
||||
|
||||
public void setActiveSkill(SkillHolder holder)
|
||||
public void addActiveSkill(SkillHolder holder)
|
||||
{
|
||||
_activeSkill = holder;
|
||||
if (_activeSkill == null)
|
||||
{
|
||||
_activeSkill = new ArrayList<>();
|
||||
}
|
||||
_activeSkill.add(holder);
|
||||
}
|
||||
|
||||
public boolean hasPassiveSkill()
|
||||
public boolean hasPassiveSkills()
|
||||
{
|
||||
return _passiveSkill != null;
|
||||
}
|
||||
|
||||
public SkillHolder getPassiveSkill()
|
||||
public List<SkillHolder> getPassiveSkills()
|
||||
{
|
||||
return _passiveSkill;
|
||||
}
|
||||
|
||||
public void setPassiveSkill(SkillHolder holder)
|
||||
public void addPassiveSkill(SkillHolder holder)
|
||||
{
|
||||
_passiveSkill = holder;
|
||||
if (_passiveSkill == null)
|
||||
{
|
||||
_passiveSkill = new ArrayList<>();
|
||||
}
|
||||
_passiveSkill.add(holder);
|
||||
}
|
||||
|
||||
public boolean hasActivationSkills()
|
||||
{
|
||||
return !_activationSkills.isEmpty();
|
||||
return _activationSkills != null;
|
||||
}
|
||||
|
||||
public boolean hasActivationSkills(OptionsSkillType type)
|
||||
{
|
||||
for (OptionsSkillHolder holder : _activationSkills)
|
||||
if (_activationSkills != null)
|
||||
{
|
||||
if (holder.getSkillType() == type)
|
||||
for (OptionsSkillHolder holder : _activationSkills)
|
||||
{
|
||||
return true;
|
||||
if (holder.getSkillType() == type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -121,12 +134,15 @@ public class Options
|
||||
|
||||
public List<OptionsSkillHolder> getActivationsSkills(OptionsSkillType type)
|
||||
{
|
||||
final List<OptionsSkillHolder> temp = new ArrayList<>();
|
||||
for (OptionsSkillHolder holder : _activationSkills)
|
||||
List<OptionsSkillHolder> temp = new ArrayList<>();
|
||||
if (_activationSkills != null)
|
||||
{
|
||||
if (holder.getSkillType() == type)
|
||||
for (OptionsSkillHolder holder : _activationSkills)
|
||||
{
|
||||
temp.add(holder);
|
||||
if (holder.getSkillType() == type)
|
||||
{
|
||||
temp.add(holder);
|
||||
}
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
@@ -134,6 +150,10 @@ public class Options
|
||||
|
||||
public void addActivationSkill(OptionsSkillHolder holder)
|
||||
{
|
||||
if (_activationSkills == null)
|
||||
{
|
||||
_activationSkills = new ArrayList<>();
|
||||
}
|
||||
_activationSkills.add(holder);
|
||||
}
|
||||
|
||||
@@ -171,15 +191,21 @@ public class Options
|
||||
player.getEffectList().add(info);
|
||||
}
|
||||
}
|
||||
if (hasActiveSkill())
|
||||
if (hasActiveSkills())
|
||||
{
|
||||
addSkill(player, getActiveSkill().getSkill());
|
||||
player.sendDebugMessage("Adding active skill: " + getActiveSkill());
|
||||
for (SkillHolder holder : getActiveSkills())
|
||||
{
|
||||
addSkill(player, holder.getSkill());
|
||||
player.sendDebugMessage("Adding active skill: " + getActiveSkills());
|
||||
}
|
||||
}
|
||||
if (hasPassiveSkill())
|
||||
if (hasPassiveSkills())
|
||||
{
|
||||
addSkill(player, getPassiveSkill().getSkill());
|
||||
player.sendDebugMessage("Adding passive skill: " + getPassiveSkill());
|
||||
for (SkillHolder holder : getPassiveSkills())
|
||||
{
|
||||
addSkill(player, holder.getSkill());
|
||||
player.sendDebugMessage("Adding passive skill: " + getPassiveSkills());
|
||||
}
|
||||
}
|
||||
if (hasActivationSkills())
|
||||
{
|
||||
@@ -208,15 +234,21 @@ public class Options
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasActiveSkill())
|
||||
if (hasActiveSkills())
|
||||
{
|
||||
player.removeSkill(getActiveSkill().getSkill(), false, false);
|
||||
player.sendDebugMessage("Removing active skill: " + getActiveSkill());
|
||||
for (SkillHolder holder : getActiveSkills())
|
||||
{
|
||||
player.removeSkill(holder.getSkill(), false, false);
|
||||
player.sendDebugMessage("Removing active skill: " + getActiveSkills());
|
||||
}
|
||||
}
|
||||
if (hasPassiveSkill())
|
||||
if (hasPassiveSkills())
|
||||
{
|
||||
player.removeSkill(getPassiveSkill().getSkill(), false, true);
|
||||
player.sendDebugMessage("Removing passive skill: " + getPassiveSkill());
|
||||
for (SkillHolder holder : getPassiveSkills())
|
||||
{
|
||||
player.removeSkill(holder.getSkill(), false, true);
|
||||
player.sendDebugMessage("Removing passive skill: " + getPassiveSkills());
|
||||
}
|
||||
}
|
||||
if (hasActivationSkills())
|
||||
{
|
||||
|
||||
@@ -59,6 +59,7 @@ public class PlayerVariables extends AbstractVariables
|
||||
public static final String EXTEND_DROP = "EXTEND_DROP";
|
||||
public static final String FORTUNE_TELLING_VARIABLE = "FortuneTelling";
|
||||
public static final String FORTUNE_TELLING_BLACK_CAT_VARIABLE = "FortuneTellingBlackCat";
|
||||
public static final String DELUSION_RETURN = "DELUSION_RETURN";
|
||||
|
||||
private final int _objectId;
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ public enum ZoneId
|
||||
NO_SUMMON_FRIEND,
|
||||
FORT,
|
||||
NO_STORE,
|
||||
TOWN,
|
||||
SCRIPT,
|
||||
HQ,
|
||||
DANGER_AREA,
|
||||
@@ -47,7 +46,8 @@ public enum ZoneId
|
||||
NO_RESTART,
|
||||
SAYUNE,
|
||||
FISHING,
|
||||
UNDYING;
|
||||
UNDYING,
|
||||
TAX;
|
||||
|
||||
public static int getZoneCount()
|
||||
{
|
||||
|
||||
@@ -1,85 +1,86 @@
|
||||
/*
|
||||
* 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.zone.type;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
|
||||
/**
|
||||
* A Town zone
|
||||
* @author durgus
|
||||
*/
|
||||
public class L2TownZone extends L2ZoneType
|
||||
{
|
||||
private int _townId;
|
||||
private int _taxById;
|
||||
|
||||
public L2TownZone(int id)
|
||||
{
|
||||
super(id);
|
||||
|
||||
_taxById = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameter(String name, String value)
|
||||
{
|
||||
if (name.equals("townId"))
|
||||
{
|
||||
_townId = Integer.parseInt(value);
|
||||
}
|
||||
else if (name.equals("taxById"))
|
||||
{
|
||||
_taxById = Integer.parseInt(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.setParameter(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnter(L2Character character)
|
||||
{
|
||||
character.setInsideZone(ZoneId.TOWN, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onExit(L2Character character)
|
||||
{
|
||||
character.setInsideZone(ZoneId.TOWN, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this zones town id (if any)
|
||||
* @return
|
||||
*/
|
||||
public int getTownId()
|
||||
{
|
||||
return _townId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this town zones castle id
|
||||
* @return
|
||||
*/
|
||||
public final int getTaxById()
|
||||
{
|
||||
return _taxById;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.zone.type;
|
||||
|
||||
import com.l2jmobius.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
|
||||
/**
|
||||
* Tax zone type.
|
||||
* @author malyelfik
|
||||
*/
|
||||
public class L2TaxZone extends L2ZoneType
|
||||
{
|
||||
private int _domainId;
|
||||
private Castle _castle;
|
||||
|
||||
public L2TaxZone(int id)
|
||||
{
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameter(String name, String value)
|
||||
{
|
||||
if (name.equalsIgnoreCase("domainId"))
|
||||
{
|
||||
_domainId = Integer.parseInt(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.setParameter(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnter(L2Character character)
|
||||
{
|
||||
character.setInsideZone(ZoneId.TAX, true);
|
||||
if (character.isNpc())
|
||||
{
|
||||
((L2Npc) character).setTaxZone(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onExit(L2Character character)
|
||||
{
|
||||
character.setInsideZone(ZoneId.TAX, false);
|
||||
if (character.isNpc())
|
||||
{
|
||||
((L2Npc) character).setTaxZone(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets castle associated with tax zone.<br>
|
||||
* @return instance of {@link Castle} if found otherwise {@code null}
|
||||
*/
|
||||
public Castle getCastle()
|
||||
{
|
||||
// Lazy loading is used because zone is loaded before residence
|
||||
if (_castle == null)
|
||||
{
|
||||
_castle = CastleManager.getInstance().getCastleById(_domainId);
|
||||
}
|
||||
return _castle;
|
||||
}
|
||||
}
|
||||
@@ -16,31 +16,39 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EnsoulData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.MultisellData;
|
||||
import com.l2jmobius.gameserver.model.L2Augmentation;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.enums.AttributeType;
|
||||
import com.l2jmobius.gameserver.enums.SpecialItemType;
|
||||
import com.l2jmobius.gameserver.model.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.PcInventory;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.model.items.enchant.attribute.AttributeHolder;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.multisell.Entry;
|
||||
import com.l2jmobius.gameserver.model.multisell.Ingredient;
|
||||
import com.l2jmobius.gameserver.model.multisell.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.multisell.PreparedListContainer;
|
||||
import com.l2jmobius.gameserver.model.variables.ItemVariables;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
||||
|
||||
/**
|
||||
* The Class MultiSellChoose.
|
||||
@@ -50,6 +58,19 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
private int _listId;
|
||||
private int _entryId;
|
||||
private long _amount;
|
||||
private int _enchantLevel;
|
||||
private int _augmentOption1;
|
||||
private int _augmentOption2;
|
||||
private short _attackAttribute;
|
||||
private short _attributePower;
|
||||
private short _fireDefence;
|
||||
private short _waterDefence;
|
||||
private short _windDefence;
|
||||
private short _earthDefence;
|
||||
private short _holyDefence;
|
||||
private short _darkDefence;
|
||||
private EnsoulOption[] _soulCrystalOptions;
|
||||
private EnsoulOption[] _soulCrystalSpecialOptions;
|
||||
|
||||
@Override
|
||||
public boolean read(L2GameClient client, PacketReader packet)
|
||||
@@ -57,17 +78,29 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
_listId = packet.readD();
|
||||
_entryId = packet.readD();
|
||||
_amount = packet.readQ();
|
||||
// _unk1 = packet.readH();
|
||||
// _unk2 = packet.readD();
|
||||
// _unk3 = packet.readD();
|
||||
// _unk4 = packet.readH(); // elemental attributes
|
||||
// _unk5 = packet.readH(); // elemental attributes
|
||||
// _unk6 = packet.readH(); // elemental attributes
|
||||
// _unk7 = packet.readH(); // elemental attributes
|
||||
// _unk8 = packet.readH(); // elemental attributes
|
||||
// _unk9 = packet.readH(); // elemental attributes
|
||||
// _unk10 = packet.readH(); // elemental attributes
|
||||
// _unk11 = packet.readH(); // elemental attributes
|
||||
_enchantLevel = packet.readH();
|
||||
_augmentOption1 = packet.readD();
|
||||
_augmentOption2 = packet.readD();
|
||||
_attackAttribute = (short) packet.readH();
|
||||
_attributePower = (short) packet.readH();
|
||||
_fireDefence = (short) packet.readH();
|
||||
_waterDefence = (short) packet.readH();
|
||||
_windDefence = (short) packet.readH();
|
||||
_earthDefence = (short) packet.readH();
|
||||
_holyDefence = (short) packet.readH();
|
||||
_darkDefence = (short) packet.readH();
|
||||
_soulCrystalOptions = new EnsoulOption[packet.readC()]; // Ensoul size
|
||||
for (int i = 0; i < _soulCrystalOptions.length; i++)
|
||||
{
|
||||
final int ensoulId = packet.readD(); // Ensoul option id
|
||||
_soulCrystalOptions[i] = EnsoulData.getInstance().getOption(ensoulId);
|
||||
}
|
||||
_soulCrystalSpecialOptions = new EnsoulOption[packet.readC()]; // Special ensoul size
|
||||
for (int i = 0; i < _soulCrystalSpecialOptions.length; i++)
|
||||
{
|
||||
final int ensoulId = packet.readD(); // Special ensoul option id.
|
||||
_soulCrystalSpecialOptions[i] = EnsoulData.getInstance().getOption(ensoulId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,411 +119,471 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if ((_amount < 1) || (_amount > 5000))
|
||||
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max.
|
||||
{
|
||||
player.setMultiSell(null);
|
||||
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
|
||||
return;
|
||||
}
|
||||
|
||||
final PreparedListContainer list = player.getMultiSell();
|
||||
if ((list == null) || (list.getListId() != _listId))
|
||||
PreparedMultisellListHolder list = player.getMultiSell();
|
||||
if ((list == null) || (list.getId() != _listId))
|
||||
{
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Npc npc = player.getLastFolkNPC();
|
||||
if (!list.isNpcAllowed(-1) && !isAllowedToUse(player, npc, list))
|
||||
if (!isAllowedToUse(player, npc, list))
|
||||
{
|
||||
if (player.isGM())
|
||||
{
|
||||
player.sendMessage("Multisell " + _listId + " is restricted. Under current conditions cannot be used. Only GMs are allowed to use it.");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (((_soulCrystalOptions != null) && CommonUtil.contains(_soulCrystalOptions, null)) || ((_soulCrystalSpecialOptions != null) && CommonUtil.contains(_soulCrystalSpecialOptions, null)))
|
||||
{
|
||||
_log.severe("Character: " + player.getName() + " requested multisell entry with invalid soul crystal options. Multisell: " + _listId + " entry: " + _entryId);
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
|
||||
for (Entry entry : list.getEntries())
|
||||
final MultisellEntryHolder entry = list.getEntries().get(_entryId - 1); // Entry Id begins from 1. We currently use entry IDs as index pointer.
|
||||
if (entry == null)
|
||||
{
|
||||
if (entry.getEntryId() == _entryId)
|
||||
_log.severe("Character: " + player.getName() + " requested inexistant prepared multisell entry. Multisell: " + _listId + " entry: " + _entryId);
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!entry.isStackable() && (_amount > 1))
|
||||
{
|
||||
_log.severe("Character: " + player.getName() + " is trying to set amount > 1 on non-stackable multisell. Id: " + _listId + " entry: " + _entryId);
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemInfo itemEnchantment = list.getItemEnchantment(_entryId - 1); // Entry Id begins from 1. We currently use entry IDs as index pointer.
|
||||
|
||||
// Validate the requested item with its full stats.
|
||||
//@formatter:off
|
||||
if ((itemEnchantment != null) && ((_amount > 1)
|
||||
|| (itemEnchantment.getEnchantLevel() != _enchantLevel)
|
||||
|| (itemEnchantment.getAttackElementType() != _attackAttribute)
|
||||
|| (itemEnchantment.getAttackElementPower() != _attributePower)
|
||||
|| (itemEnchantment.getAttributeDefence(AttributeType.FIRE) != _fireDefence)
|
||||
|| (itemEnchantment.getAttributeDefence(AttributeType.WATER) != _waterDefence)
|
||||
|| (itemEnchantment.getAttributeDefence(AttributeType.WIND) != _windDefence)
|
||||
|| (itemEnchantment.getAttributeDefence(AttributeType.EARTH) != _earthDefence)
|
||||
|| (itemEnchantment.getAttributeDefence(AttributeType.HOLY) != _holyDefence)
|
||||
|| (itemEnchantment.getAttributeDefence(AttributeType.DARK) != _darkDefence)
|
||||
|| ((itemEnchantment.getAugmentation() == null) && ((_augmentOption1 != 0) || (_augmentOption2 != 0)))
|
||||
|| ((itemEnchantment.getAugmentation() != null) && ((itemEnchantment.getAugmentation().getOptionId(0) != _augmentOption1) || (itemEnchantment.getAugmentation().getOptionId(1) != _augmentOption2)))
|
||||
|| ((_soulCrystalOptions != null) && itemEnchantment.getSoulCrystalOptions().stream().anyMatch(e -> !CommonUtil.contains(_soulCrystalOptions, e)))
|
||||
|| ((_soulCrystalOptions == null) && !itemEnchantment.getSoulCrystalOptions().isEmpty())
|
||||
|| ((_soulCrystalSpecialOptions != null) && itemEnchantment.getSoulCrystalOptions().stream().anyMatch(e -> !CommonUtil.contains(_soulCrystalSpecialOptions, e)))
|
||||
|| ((_soulCrystalSpecialOptions == null) && !itemEnchantment.getSoulCrystalSpecialOptions().isEmpty())
|
||||
))
|
||||
//@formatter:on
|
||||
{
|
||||
_log.severe("Character: " + player.getName() + " is trying to upgrade equippable item, but the stats doesn't match. Id: " + _listId + " entry: " + _entryId);
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Clan clan = player.getClan();
|
||||
final PcInventory inventory = player.getInventory();
|
||||
|
||||
try
|
||||
{
|
||||
int slots = 0;
|
||||
int weight = 0;
|
||||
for (ItemChanceHolder product : entry.getProducts())
|
||||
{
|
||||
if (!entry.isStackable() && (_amount > 1))
|
||||
if (product.getId() < 0)
|
||||
{
|
||||
// Check if clan exists for clan reputation products.
|
||||
if ((clan == null) && (SpecialItemType.CLAN_REPUTATION.getClientId() == product.getId()))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_A_CLAN_MEMBER_AND_CANNOT_PERFORM_THIS_ACTION);
|
||||
return;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(product.getId());
|
||||
if (template == null)
|
||||
{
|
||||
_log.severe("Character: " + player.getName() + " is trying to set amount > 1 on non-stackable multisell, id:" + _listId + ":" + _entryId);
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final PcInventory inv = player.getInventory();
|
||||
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
|
||||
|
||||
int slots = 0;
|
||||
int weight = 0;
|
||||
for (Ingredient e : entry.getProducts())
|
||||
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
|
||||
{
|
||||
if (e.getItemId() < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!e.isStackable())
|
||||
{
|
||||
slots += e.getItemCount() * _amount;
|
||||
}
|
||||
else if (player.getInventory().getItemByItemId(e.getItemId()) == null)
|
||||
{
|
||||
slots++;
|
||||
}
|
||||
weight += e.getItemCount() * _amount * e.getWeight();
|
||||
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inv.validateWeight(weight))
|
||||
if (!template.isStackable() || (player.getInventory().getItemByItemId(product.getId()) == null))
|
||||
{
|
||||
slots++;
|
||||
}
|
||||
|
||||
weight += totalCount * template.getWeight();
|
||||
|
||||
if (!inventory.validateWeight(weight))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_WEIGHT_LIMIT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inv.validateCapacity(slots))
|
||||
if ((slots > 0) && !inventory.validateCapacity(slots))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOUR_INVENTORY_IS_FULL);
|
||||
return;
|
||||
}
|
||||
|
||||
final ArrayList<Ingredient> ingredientsList = new ArrayList<>(entry.getIngredients().size());
|
||||
// Generate a list of distinct ingredients and counts in order to check if the correct item-counts are possessed by the player
|
||||
boolean newIng;
|
||||
for (Ingredient e : entry.getIngredients())
|
||||
// If this is a chance multisell, reset slots and weight because only one item should be seleted. We just need to check if conditions for every item is met.
|
||||
if (list.isChanceMultisell())
|
||||
{
|
||||
newIng = true;
|
||||
// at this point, the template has already been modified so that enchantments are properly included
|
||||
// whenever they need to be applied. Uniqueness of items is thus judged by item id AND enchantment level
|
||||
for (int i = ingredientsList.size(); --i >= 0;)
|
||||
slots = 0;
|
||||
weight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for enchanted item if its present in the inventory.
|
||||
if ((itemEnchantment != null) && (inventory.getItemByObjectId(itemEnchantment.getObjectId()) == null))
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addItemName(itemEnchantment.getItem().getId());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count.
|
||||
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
|
||||
|
||||
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
|
||||
boolean allOk = true;
|
||||
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
|
||||
{
|
||||
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
|
||||
}
|
||||
|
||||
// The above operation should not be short-circuited, in order to show all missing ingredients.
|
||||
if (!allOk)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final InventoryUpdate iu = new InventoryUpdate();
|
||||
boolean itemEnchantmentProcessed = (itemEnchantment == null);
|
||||
|
||||
// Take all ingredients
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
final long totalCount = Math.multiplyExact(list.getIngredientCount(ingredient), _amount);
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredient.getId());
|
||||
if (specialItem != null)
|
||||
{
|
||||
// Take special item.
|
||||
switch (specialItem)
|
||||
{
|
||||
final Ingredient ex = ingredientsList.get(i);
|
||||
// if the item was already added in the list, merely increment the count
|
||||
// this happens if 1 list entry has the same ingredient twice (example 2 swords = 1 dual)
|
||||
if ((ex.getItemId() == e.getItemId()) && (ex.getEnchantLevel() == e.getEnchantLevel()))
|
||||
case CLAN_REPUTATION:
|
||||
{
|
||||
if ((ex.getItemCount() + e.getItemCount()) > Integer.MAX_VALUE)
|
||||
if (clan != null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
|
||||
return;
|
||||
clan.takeReputationScore((int) totalCount, true);
|
||||
SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.S1_POINT_S_HAVE_BEEN_DEDUCTED_FROM_THE_CLAN_S_REPUTATION);
|
||||
smsg.addLong(totalCount);
|
||||
player.sendPacket(smsg);
|
||||
}
|
||||
// two same ingredients, merge into one and replace old
|
||||
final Ingredient ing = ex.getCopy();
|
||||
ing.setItemCount(ex.getItemCount() + e.getItemCount());
|
||||
ingredientsList.set(i, ing);
|
||||
newIng = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newIng)
|
||||
{
|
||||
// if it's a new ingredient, just store its info directly (item id, count, enchantment)
|
||||
ingredientsList.add(e);
|
||||
case FAME:
|
||||
{
|
||||
player.setFame(player.getFame() - (int) totalCount);
|
||||
player.sendPacket(new UserInfo(player));
|
||||
// player.sendPacket(new ExBrExtraUserInfo(player));
|
||||
break;
|
||||
}
|
||||
case RAIDBOSS_POINTS:
|
||||
{
|
||||
player.setRaidbossPoints(player.getRaidbossPoints() - (int) totalCount);
|
||||
player.sendPacket(new UserInfo(player));
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CONSUMED_S1_RAID_POINTS).addLong(totalCount));
|
||||
break;
|
||||
}
|
||||
case PC_CAFE_POINTS:
|
||||
{
|
||||
player.setPcCafePoints((int) (player.getPcCafePoints() - totalCount));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_log.severe("Character: " + player.getName() + " has suffered possible item loss by using multisell " + _listId + " which has non-implemented special ingredient with id: " + ingredient.getId() + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now check if the player has sufficient items in the inventory to cover the ingredient expenses
|
||||
for (Ingredient e : ingredientsList)
|
||||
else if (!itemEnchantmentProcessed && (itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId()))
|
||||
{
|
||||
if ((e.getItemCount() * _amount) > Integer.MAX_VALUE)
|
||||
// Take the enchanted item.
|
||||
final L2ItemInstance destroyedItem = inventory.destroyItem("Multisell", itemEnchantment.getObjectId(), totalCount, player, npc);
|
||||
if (destroyedItem != null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
|
||||
itemEnchantmentProcessed = true;
|
||||
iu.addItem(destroyedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
|
||||
sm.addItemName(ingredient.getId());
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
if (e.getItemId() < 0)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Take a regular item.
|
||||
final L2ItemInstance destroyedItem = inventory.destroyItemByItemId("Multisell", ingredient.getId(), totalCount, player, npc);
|
||||
if (destroyedItem != null)
|
||||
{
|
||||
if (!MultisellData.hasSpecialIngredient(e.getItemId(), e.getItemCount() * _amount, player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
iu.addItem(destroyedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if this is not a list that maintains enchantment, check the count of all items that have the given id.
|
||||
// otherwise, check only the count of items with exactly the needed enchantment level
|
||||
final long required = (Config.ALT_BLACKSMITH_USE_RECIPES || !e.getMaintainIngredient()) ? (e.getItemCount() * _amount) : e.getItemCount();
|
||||
if (inv.getInventoryItemCount(e.getItemId(), (list.getMaintainEnchantment() || (e.getEnchantLevel() > 0)) ? e.getEnchantLevel() : -1, false) < required)
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_S1_S);
|
||||
sm.addItemName(ingredient.getId());
|
||||
sm.addLong(totalCount);
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the appropriate items
|
||||
List<ItemChanceHolder> products = entry.getProducts();
|
||||
if (list.isChanceMultisell())
|
||||
{
|
||||
final ItemChanceHolder randomProduct = ItemChanceHolder.getRandomHolder(entry.getProducts());
|
||||
products = randomProduct != null ? Collections.singletonList(randomProduct) : Collections.emptyList();
|
||||
}
|
||||
|
||||
for (ItemChanceHolder product : products)
|
||||
{
|
||||
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(product.getId());
|
||||
if (specialItem != null)
|
||||
{
|
||||
// Give special item.
|
||||
switch (specialItem)
|
||||
{
|
||||
case CLAN_REPUTATION:
|
||||
{
|
||||
if (e.getEnchantLevel() > 0)
|
||||
if (clan != null)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_S1_S);
|
||||
sm.addString("+" + e.getEnchantLevel() + " " + e.getTemplate().getName());
|
||||
sm.addLong(required);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_S1_S);
|
||||
sm.addItemName(e.getTemplate());
|
||||
sm.addLong(required);
|
||||
player.sendPacket(sm);
|
||||
clan.addReputationScore((int) totalCount, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAME:
|
||||
{
|
||||
player.setFame((int) (player.getFame() + totalCount));
|
||||
player.sendPacket(new UserInfo(player));
|
||||
// player.sendPacket(new ExBrExtraUserInfo(player));
|
||||
break;
|
||||
}
|
||||
case RAIDBOSS_POINTS:
|
||||
{
|
||||
player.increaseRaidbossPoints((int) totalCount);
|
||||
player.sendPacket(new UserInfo(player));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_log.severe("Character: " + player.getName() + " has suffered possible item loss by using multisell " + _listId + " which has non-implemented special product with id: " + product.getId() + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Map<Integer, ItemInfo> originalInfos = new LinkedHashMap<>();
|
||||
/** All ok, remove items and add final product */
|
||||
|
||||
for (Ingredient e : entry.getIngredients())
|
||||
else
|
||||
{
|
||||
if (e.getItemId() < 0)
|
||||
// Give item.
|
||||
final L2ItemInstance addedItem = inventory.addItem("Multisell", product.getId(), totalCount, player, npc);
|
||||
iu.addItem(addedItem);
|
||||
|
||||
// Check if the newly given item should be enchanted.
|
||||
if (itemEnchantmentProcessed && list.isMaintainEnchantment() && (itemEnchantment != null) && addedItem.isEquipable() && addedItem.getItem().getClass().equals(itemEnchantment.getItem().getClass()))
|
||||
{
|
||||
if (!MultisellData.takeSpecialIngredient(e.getItemId(), e.getItemCount() * _amount, player))
|
||||
addedItem.setEnchantLevel(itemEnchantment.getEnchantLevel());
|
||||
addedItem.setAugmentation(itemEnchantment.getAugmentation(), false);
|
||||
addedItem.setAttribute(new AttributeHolder(AttributeType.findByClientId(itemEnchantment.getAttackElementType()), itemEnchantment.getAttackElementPower()), false);
|
||||
addedItem.setAttribute(new AttributeHolder(AttributeType.FIRE, itemEnchantment.getAttributeDefence(AttributeType.FIRE)), false);
|
||||
addedItem.setAttribute(new AttributeHolder(AttributeType.WATER, itemEnchantment.getAttributeDefence(AttributeType.WATER)), false);
|
||||
addedItem.setAttribute(new AttributeHolder(AttributeType.WIND, itemEnchantment.getAttributeDefence(AttributeType.WIND)), false);
|
||||
addedItem.setAttribute(new AttributeHolder(AttributeType.EARTH, itemEnchantment.getAttributeDefence(AttributeType.EARTH)), false);
|
||||
addedItem.setAttribute(new AttributeHolder(AttributeType.HOLY, itemEnchantment.getAttributeDefence(AttributeType.HOLY)), false);
|
||||
addedItem.setAttribute(new AttributeHolder(AttributeType.DARK, itemEnchantment.getAttributeDefence(AttributeType.DARK)), false);
|
||||
if (_soulCrystalOptions != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
L2ItemInstance itemToTake = inv.getItemByItemId(e.getItemId()); // initialize and initial guess for the item to take.
|
||||
if (itemToTake == null)
|
||||
{ // this is a cheat, transaction will be aborted and if any items already taken will not be returned back to inventory!
|
||||
_log.severe("Character: " + player.getName() + " is trying to cheat in multisell, id:" + _listId + ":" + _entryId);
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// if (itemToTake.isEquipped())
|
||||
// {
|
||||
// this is a cheat, transaction will be aborted and if any items already taken will not be returned back to inventory!
|
||||
// LOGGER.severe("Character: " + player.getName() + " is trying to cheat in multisell, exchanging equipped item, merchatnt id:" + merchant.getNpcId());
|
||||
// player.setMultiSell(null);
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (Config.ALT_BLACKSMITH_USE_RECIPES || !e.getMaintainIngredient())
|
||||
{
|
||||
// if it's a stackable item, just reduce the amount from the first (only) instance that is found in the inventory
|
||||
if (itemToTake.isStackable())
|
||||
for (int i = 0; i < _soulCrystalOptions.length; i++)
|
||||
{
|
||||
if (!player.destroyItem("Multisell", itemToTake.getObjectId(), e.getItemCount() * _amount, player.getTarget(), true))
|
||||
{
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// for non-stackable items, one of two scenaria are possible:
|
||||
// a) list maintains enchantment: get the instances that exactly match the requested enchantment level
|
||||
// b) list does not maintain enchantment: get the instances with the LOWEST enchantment level
|
||||
|
||||
// a) if enchantment is maintained, then get a list of items that exactly match this enchantment
|
||||
if (list.getMaintainEnchantment() || (e.getEnchantLevel() > 0))
|
||||
{
|
||||
// loop through this list and remove (one by one) each item until the required amount is taken.
|
||||
final L2ItemInstance[] inventoryContents = inv.getAllItemsByItemId(e.getItemId(), e.getEnchantLevel(), false).toArray(new L2ItemInstance[0]);
|
||||
for (int i = 0; i < (e.getItemCount() * _amount); i++)
|
||||
{
|
||||
originalInfos.put(i, new ItemInfo(inventoryContents[i]));
|
||||
if (!player.destroyItem("Multisell", inventoryContents[i].getObjectId(), 1, player.getTarget(), true))
|
||||
{
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
// b) enchantment is not maintained. Get the instances with the LOWEST enchantment level
|
||||
{
|
||||
// NOTE: There are 2 ways to achieve the above goal.
|
||||
// 1) Get all items that have the correct itemId, loop through them until the lowest enchantment
|
||||
// level is found. Repeat all this for the next item until proper count of items is reached.
|
||||
// 2) Get all items that have the correct itemId, sort them once based on enchantment level,
|
||||
// and get the range of items that is necessary.
|
||||
// Method 1 is faster for a small number of items to be exchanged.
|
||||
// Method 2 is faster for large amounts.
|
||||
//
|
||||
// EXPLANATION:
|
||||
// Worst case scenario for algorithm 1 will make it run in a number of cycles given by:
|
||||
// m*(2n-m+1)/2 where m is the number of items to be exchanged and n is the total
|
||||
// number of inventory items that have a matching id.
|
||||
// With algorithm 2 (sort), sorting takes n*log(n) time and the choice is done in a single cycle
|
||||
// for case b (just grab the m first items) or in linear time for case a (find the beginning of items
|
||||
// with correct enchantment, index x, and take all items from x to x+m).
|
||||
// Basically, whenever m > log(n) we have: m*(2n-m+1)/2 = (2nm-m*m+m)/2 >
|
||||
// (2nlogn-logn*logn+logn)/2 = nlog(n) - log(n*n) + log(n) = nlog(n) + log(n/n*n) =
|
||||
// nlog(n) + log(1/n) = nlog(n) - log(n) = (n-1)log(n)
|
||||
// So for m < log(n) then m*(2n-m+1)/2 > (n-1)log(n) and m*(2n-m+1)/2 > nlog(n)
|
||||
//
|
||||
// IDEALLY:
|
||||
// In order to best optimize the performance, choose which algorithm to run, based on whether 2^m > n
|
||||
// if ( (2<<(e.getItemCount()// _amount)) < inventoryContents.length )
|
||||
// // do Algorithm 1, no sorting
|
||||
// else
|
||||
// // do Algorithm 2, sorting
|
||||
//
|
||||
// CURRENT IMPLEMENTATION:
|
||||
// In general, it is going to be very rare for a person to do a massive exchange of non-stackable items
|
||||
// For this reason, we assume that algorithm 1 will always suffice and we keep things simple.
|
||||
// If, in the future, it becomes necessary that we optimize, the above discussion should make it clear
|
||||
// what optimization exactly is necessary (based on the comments under "IDEALLY").
|
||||
//
|
||||
|
||||
// choice 1. Small number of items exchanged. No sorting.
|
||||
for (int i = 1; i <= (e.getItemCount() * _amount); i++)
|
||||
{
|
||||
final Collection<L2ItemInstance> inventoryContents = inv.getAllItemsByItemId(e.getItemId(), false);
|
||||
|
||||
itemToTake = inventoryContents.iterator().next();
|
||||
// get item with the LOWEST enchantment level from the inventory...
|
||||
// +0 is lowest by default...
|
||||
if (itemToTake.getEnchantLevel() > 0)
|
||||
{
|
||||
for (L2ItemInstance item : inventoryContents)
|
||||
{
|
||||
if ((item.getEnchantLevel() < itemToTake.getEnchantLevel()) && (item.getEnchantLevel() >= e.getEnchantLevel()))
|
||||
{
|
||||
itemToTake = item;
|
||||
// nothing will have enchantment less than 0. If a zero-enchanted
|
||||
// item is found, just take it
|
||||
if (itemToTake.getEnchantLevel() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!player.destroyItem("Multisell", itemToTake.getObjectId(), 1, player.getTarget(), true))
|
||||
{
|
||||
player.setMultiSell(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
addedItem.addSpecialAbility(_soulCrystalOptions[i], i + 1, 1, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final double itemRandom = 100 * Rnd.nextDouble();
|
||||
float cumulativeChance = 0;
|
||||
|
||||
boolean matched = false;
|
||||
// Generate the appropriate items
|
||||
for (Ingredient e : entry.getProducts())
|
||||
{
|
||||
if (list.isChanceMultisell())
|
||||
{
|
||||
// Skip first entry.
|
||||
if (e.getChance() < 1)
|
||||
if (_soulCrystalSpecialOptions != null)
|
||||
{
|
||||
continue;
|
||||
for (int i = 0; i < _soulCrystalSpecialOptions.length; i++)
|
||||
{
|
||||
addedItem.addSpecialAbility(_soulCrystalSpecialOptions[i], i + 1, 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate chance
|
||||
matched = itemRandom < (cumulativeChance += e.getChance());
|
||||
if (!matched)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
addedItem.updateDatabase();
|
||||
|
||||
// Mark that we have already upgraded the item.
|
||||
itemEnchantmentProcessed = false;
|
||||
}
|
||||
|
||||
if (e.getItemId() < 0)
|
||||
if (addedItem.getCount() > 1)
|
||||
{
|
||||
MultisellData.giveSpecialProduct(e.getItemId(), e.getItemCount() * _amount, player);
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(addedItem.getId());
|
||||
sm.addLong(totalCount);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
else if (addedItem.getEnchantLevel() > 0)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.ACQUIRED_S1_S2);
|
||||
sm.addLong(addedItem.getEnchantLevel());
|
||||
sm.addItemName(addedItem.getId());
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.isStackable())
|
||||
{
|
||||
inv.addItem("Multisell", e.getItemId(), e.getItemCount() * _amount, player, player.getTarget());
|
||||
}
|
||||
else
|
||||
{
|
||||
L2ItemInstance product = null;
|
||||
for (int i = 0; i < (e.getItemCount() * _amount); i++)
|
||||
{
|
||||
product = inv.addItem("Multisell", e.getItemId(), 1, player, player.getTarget());
|
||||
if ((product != null) && (list.getMaintainEnchantment() || (e.getEnchantLevel() > 0)))
|
||||
{
|
||||
final ItemInfo info = originalInfos.get(i);
|
||||
if (info != null)
|
||||
{
|
||||
if (info.getAugmentId() > 0)
|
||||
{
|
||||
product.setAugmentation(new L2Augmentation(info.getAugmentId()));
|
||||
}
|
||||
if (info.getElementals().length > 0)
|
||||
{
|
||||
Arrays.stream(info.getElementals()).filter(Objects::nonNull).forEach(product::setAttribute);
|
||||
}
|
||||
if (info.getVisualId() > 0)
|
||||
{
|
||||
product.setVisualId(info.getVisualId());
|
||||
if (info.getVisualStoneId() > 0)
|
||||
{
|
||||
product.getVariables().set(ItemVariables.VISUAL_APPEARANCE_STONE_ID, info.getVisualStoneId());
|
||||
}
|
||||
if (info.getVisualIdLifeTime() > 0)
|
||||
{
|
||||
product.getVariables().set(ItemVariables.VISUAL_APPEARANCE_LIFE_TIME, info.getVisualIdLifeTime());
|
||||
product.scheduleVisualLifeTime();
|
||||
}
|
||||
}
|
||||
if (!info.getSpecialAbilities().isEmpty())
|
||||
{
|
||||
int position = 0;
|
||||
for (EnsoulOption option : info.getSpecialAbilities())
|
||||
{
|
||||
product.addSpecialAbility(option, position++, 1, true);
|
||||
}
|
||||
}
|
||||
if (!info.getAdditionalSpecialAbilities().isEmpty())
|
||||
{
|
||||
int position = 0;
|
||||
for (EnsoulOption option : info.getAdditionalSpecialAbilities())
|
||||
{
|
||||
product.addSpecialAbility(option, position++, 2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
product.setEnchantLevel(e.getEnchantLevel());
|
||||
product.updateDatabase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final SystemMessage sm;
|
||||
if ((e.getItemCount() * _amount) > 1)
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S);
|
||||
sm.addItemName(e.getItemId());
|
||||
sm.addLong(e.getItemCount() * _amount);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (list.getMaintainEnchantment() && (e.getEnchantLevel() > 0))
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.ACQUIRED_S1_S2);
|
||||
sm.addLong(e.getEnchantLevel());
|
||||
sm.addItemName(e.getItemId());
|
||||
}
|
||||
else
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S1);
|
||||
sm.addItemName(e.getItemId());
|
||||
}
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
}
|
||||
|
||||
if (matched)
|
||||
{
|
||||
break;
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S1);
|
||||
sm.addItemName(addedItem);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
}
|
||||
player.sendItemList(false);
|
||||
|
||||
// finally, give the tax to the castle...
|
||||
if ((npc != null) && (entry.getTaxAmount() > 0))
|
||||
}
|
||||
|
||||
// Update inventory and weight.
|
||||
player.sendInventoryUpdate(iu);
|
||||
|
||||
// finally, give the tax to the castle...
|
||||
if ((npc != null) && list.isApplyTaxes())
|
||||
{
|
||||
final OptionalLong taxPaid = entry.getIngredients().stream().filter(i -> i.getId() == Inventory.ADENA_ID).mapToLong(i -> Math.round(i.getCount() * list.getIngredientMultiplier() * list.getTaxRate()) * _amount).reduce(Math::multiplyExact);
|
||||
if (taxPaid.isPresent())
|
||||
{
|
||||
npc.getCastle().addToTreasury(entry.getTaxAmount() * _amount);
|
||||
npc.handleTaxPayment(taxPaid.getAsLong());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (ArithmeticException ae)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-send multisell after successful exchange of inventory-only shown items.
|
||||
if (list.isInventoryOnly())
|
||||
{
|
||||
MultisellData.getInstance().separateAndSend(list.getId(), player, npc, list.isInventoryOnly(), list.getProductMultiplier(), list.getIngredientMultiplier());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player
|
||||
* @param list
|
||||
* @param inventory
|
||||
* @param clan
|
||||
* @param ingredientId
|
||||
* @param totalCount
|
||||
* @return {@code false} if ingredient amount is not enough, {@code true} otherwise.
|
||||
*/
|
||||
private boolean checkIngredients(final L2PcInstance player, PreparedMultisellListHolder list, final PcInventory inventory, final L2Clan clan, final int ingredientId, final long totalCount)
|
||||
{
|
||||
final SpecialItemType specialItem = SpecialItemType.getByClientId(ingredientId);
|
||||
if (specialItem != null)
|
||||
{
|
||||
// Check special item.
|
||||
switch (specialItem)
|
||||
{
|
||||
case CLAN_REPUTATION:
|
||||
{
|
||||
if (clan == null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_A_CLAN_MEMBER_AND_CANNOT_PERFORM_THIS_ACTION);
|
||||
return false;
|
||||
}
|
||||
else if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.ONLY_THE_CLAN_LEADER_IS_ENABLED);
|
||||
return false;
|
||||
}
|
||||
else if (clan.getReputationScore() < totalCount)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_CLAN_REPUTATION_IS_TOO_LOW);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case FAME:
|
||||
{
|
||||
if (player.getFame() < totalCount)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_DON_T_HAVE_ENOUGH_FAME_TO_DO_THAT);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case RAIDBOSS_POINTS:
|
||||
{
|
||||
if (player.getRaidbossPoints() < totalCount)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.NOT_ENOUGH_RAID_POINTS);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case PC_CAFE_POINTS:
|
||||
{
|
||||
if (player.getPcCafePoints() < totalCount)
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_SHORT_OF_PC_POINTS));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_log.severe("Multisell: " + _listId + " is using a non-implemented special ingredient with id: " + ingredientId + ".");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if the necessary items are there. If list maintains enchantment, allow all enchanted items, otherwise only unenchanted. TODO: Check how retail does it.
|
||||
else if (inventory.getInventoryItemCount(ingredientId, list.isMaintainEnchantment() ? -1 : 0, false) < totalCount)
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_S1_S);
|
||||
sm.addItemName(ingredientId);
|
||||
sm.addLong(totalCount);
|
||||
player.sendPacket(sm);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -499,7 +592,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
* @param list
|
||||
* @return {@code true} if player can buy stuff from the multisell, {@code false} otherwise.
|
||||
*/
|
||||
private boolean isAllowedToUse(L2PcInstance player, L2Npc npc, PreparedListContainer list)
|
||||
private boolean isAllowedToUse(L2PcInstance player, L2Npc npc, PreparedMultisellListHolder list)
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
@@ -507,7 +600,7 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (list.isNpcOnly() && ((npc.getInstanceWorld() != player.getInstanceWorld()) || !player.isInsideRadius(npc, L2Npc.INTERACTION_DISTANCE, true, false)))
|
||||
else if (list.isNpcOnly() && (!list.checkNpcObjectId(npc.getObjectId()) || (npc.getInstanceWorld() != player.getInstanceWorld()) || !player.isInsideRadius(npc, L2Npc.INTERACTION_DISTANCE, true, false)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -518,4 +611,4 @@ public class MultiSellChoose implements IClientIncomingPacket
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,8 +29,8 @@ import com.l2jmobius.gameserver.enums.TaxType;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MerchantInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.buylist.Product;
|
||||
import com.l2jmobius.gameserver.model.buylist.ProductList;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
@@ -110,7 +110,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
|
||||
client.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
merchant = (L2MerchantInstance) target;
|
||||
merchant = (L2MerchantInstance) target; // FIXME: Doesn't work for GMs.
|
||||
}
|
||||
|
||||
if ((merchant == null) && !player.isGM() && (_listId != CUSTOM_CB_SELL_LIST))
|
||||
@@ -119,7 +119,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
final L2BuyList buyList = BuyListData.getInstance().getBuyList(_listId);
|
||||
final ProductList buyList = BuyListData.getInstance().getBuyList(_listId);
|
||||
if (buyList == null)
|
||||
{
|
||||
Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " sent a false BuyList list_id " + _listId, Config.DEFAULT_PUNISH);
|
||||
@@ -134,7 +134,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
|
||||
client.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
castleTaxRate = merchant.getTotalTaxRate(TaxType.BUY);
|
||||
castleTaxRate = merchant.getCastleTaxRate(TaxType.BUY);
|
||||
}
|
||||
|
||||
long subTotal = 0;
|
||||
@@ -159,11 +159,6 @@ public final class RequestBuyItem implements IClientIncomingPacket
|
||||
}
|
||||
|
||||
long price = product.getPrice();
|
||||
if ((product.getItemId() >= 3960) && (product.getItemId() <= 4026))
|
||||
{
|
||||
price *= Config.RATE_SIEGE_GUARDS_PRICE;
|
||||
}
|
||||
|
||||
if (price < 0)
|
||||
{
|
||||
_log.warning("ERROR, no price found .. wrong buylist ??");
|
||||
@@ -194,7 +189,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
// first calculate price per item with tax, then multiply by count
|
||||
price = (long) (price * (1 + castleTaxRate));
|
||||
price = (long) (price * (1 + castleTaxRate + product.getBaseTaxRate()));
|
||||
subTotal += i.getCount() * price;
|
||||
if (subTotal > MAX_ADENA)
|
||||
{
|
||||
@@ -257,7 +252,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
|
||||
// add to castle treasury
|
||||
if (merchant != null)
|
||||
{
|
||||
merchant.getCastle().addToTreasury((long) (subTotal * castleTaxRate));
|
||||
merchant.handleTaxPayment((long) (subTotal * castleTaxRate));
|
||||
}
|
||||
|
||||
client.sendPacket(new ExUserInfoInvenWeight(player));
|
||||
|
||||
@@ -202,6 +202,7 @@ public class RequestExEnchantItemAttribute implements IClientIncomingPacket
|
||||
}
|
||||
}
|
||||
|
||||
item.updateItemElementals();
|
||||
player.destroyItem("AttrEnchant", stone, usedStones, player, true);
|
||||
final AttributeHolder newElement = item.getAttribute(elementToAdd);
|
||||
final int newValue = newElement != null ? newElement.getValue() : 0;
|
||||
@@ -345,7 +346,7 @@ public class RequestExEnchantItemAttribute implements IClientIncomingPacket
|
||||
|
||||
if (success)
|
||||
{
|
||||
item.setAttribute(new AttributeHolder(elementToAdd, newPower));
|
||||
item.setAttribute(new AttributeHolder(elementToAdd, newPower), false);
|
||||
}
|
||||
|
||||
return success ? 1 : 0;
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MerchantInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.buylist.ProductList;
|
||||
import com.l2jmobius.gameserver.model.buylist.Product;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jmobius.gameserver.model.items.L2Armor;
|
||||
@@ -157,7 +157,7 @@ public final class RequestPreviewItem implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
final L2BuyList buyList = BuyListData.getInstance().getBuyList(_listId);
|
||||
final ProductList buyList = BuyListData.getInstance().getBuyList(_listId);
|
||||
if (buyList == null)
|
||||
{
|
||||
Util.handleIllegalPlayerAction(activeChar, "Warning!! Character " + activeChar.getName() + " of account " + activeChar.getAccountName() + " sent a false BuyList list_id " + _listId, Config.DEFAULT_PUNISH);
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.datatables.AugmentationData;
|
||||
import com.l2jmobius.gameserver.model.L2Augmentation;
|
||||
import com.l2jmobius.gameserver.model.Augmentation;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
@@ -118,12 +118,10 @@ public final class RequestRefine extends AbstractRefinePacket
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Augmentation aug = AugmentationData.getInstance().generateRandomAugmentation(lifeStoneLevel, lifeStoneGrade, targetItem.getItem().getBodyPart(), refinerItem.getId(), targetItem);
|
||||
targetItem.setAugmentation(aug);
|
||||
final Augmentation aug = AugmentationData.getInstance().generateRandomAugmentation(lifeStoneLevel, lifeStoneGrade, targetItem.getItem().getBodyPart(), refinerItem.getId(), targetItem);
|
||||
targetItem.setAugmentation(aug, true);
|
||||
|
||||
final int stat12 = 0x0000FFFF & aug.getId();
|
||||
final int stat34 = aug.getId() >> 16;
|
||||
activeChar.sendPacket(new ExVariationResult(stat12, stat34, 1));
|
||||
activeChar.sendPacket(new ExVariationResult(aug.getOptionId(0), aug.getOptionId(1), 1));
|
||||
|
||||
final InventoryUpdate iu = new InventoryUpdate();
|
||||
iu.addModifiedItem(targetItem);
|
||||
|
||||
@@ -21,11 +21,10 @@ import static com.l2jmobius.gameserver.model.actor.L2Npc.INTERACTION_DISTANCE;
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
|
||||
import com.l2jmobius.gameserver.enums.TaxType;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MerchantInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.buylist.ProductList;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
@@ -79,13 +78,7 @@ public final class RequestRefundItem implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (_items == null)
|
||||
{
|
||||
client.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.hasRefund())
|
||||
if ((_items == null) || !player.hasRefund())
|
||||
{
|
||||
client.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
@@ -109,7 +102,7 @@ public final class RequestRefundItem implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
final L2BuyList buyList = BuyListData.getInstance().getBuyList(_listId);
|
||||
final ProductList buyList = BuyListData.getInstance().getBuyList(_listId);
|
||||
if (buyList == null)
|
||||
{
|
||||
Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " sent a false BuyList list_id " + _listId, Config.DEFAULT_PUNISH);
|
||||
@@ -164,12 +157,7 @@ public final class RequestRefundItem implements IClientIncomingPacket
|
||||
|
||||
final long count = item.getCount();
|
||||
weight += count * template.getWeight();
|
||||
long price = item.getReferencePrice() / 2;
|
||||
if (merchant != null)
|
||||
{
|
||||
price -= (price * merchant.getTotalTaxRate(TaxType.SELL));
|
||||
}
|
||||
adena += price * count;
|
||||
adena += (count * template.getReferencePrice()) / 2;
|
||||
if (!template.isStackable())
|
||||
{
|
||||
slots += count;
|
||||
@@ -213,6 +201,6 @@ public final class RequestRefundItem implements IClientIncomingPacket
|
||||
|
||||
// Update current load status on player
|
||||
client.sendPacket(new ExUserInfoInvenWeight(player));
|
||||
client.sendPacket(new ExBuySellList(player, true, merchant != null ? merchant.getTotalTaxRate(TaxType.SELL) : 0));
|
||||
client.sendPacket(new ExBuySellList(player, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.l2jmobius.gameserver.enums.TaxType;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MerchantInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.buylist.ProductList;
|
||||
import com.l2jmobius.gameserver.model.holders.UniqueItemHolder;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
@@ -129,7 +129,7 @@ public final class RequestSellItem implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
final L2BuyList buyList = BuyListData.getInstance().getBuyList(_listId);
|
||||
final ProductList buyList = BuyListData.getInstance().getBuyList(_listId);
|
||||
if (buyList == null)
|
||||
{
|
||||
Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " sent a false BuyList list_id " + _listId, Config.DEFAULT_PUNISH);
|
||||
@@ -153,10 +153,6 @@ public final class RequestSellItem implements IClientIncomingPacket
|
||||
}
|
||||
|
||||
long price = item.getReferencePrice() / 2;
|
||||
if (merchant != null)
|
||||
{
|
||||
price -= (price * merchant.getTotalTaxRate(TaxType.SELL));
|
||||
}
|
||||
totalPrice += price * i.getCount();
|
||||
if (((MAX_ADENA / i.getCount()) < price) || (totalPrice > MAX_ADENA))
|
||||
{
|
||||
@@ -166,25 +162,27 @@ public final class RequestSellItem implements IClientIncomingPacket
|
||||
|
||||
if (Config.ALLOW_REFUND)
|
||||
{
|
||||
item = player.getInventory().transferItem("Sell", i.getObjectId(), i.getCount(), player.getRefund(), player, merchant);
|
||||
player.getInventory().transferItem("Sell", i.getObjectId(), i.getCount(), player.getRefund(), player, merchant);
|
||||
}
|
||||
else
|
||||
{
|
||||
item = player.getInventory().destroyItem("Sell", i.getObjectId(), i.getCount(), player, merchant);
|
||||
player.getInventory().destroyItem("Sell", i.getObjectId(), i.getCount(), player, merchant);
|
||||
}
|
||||
}
|
||||
|
||||
// add to castle treasury
|
||||
if (merchant != null)
|
||||
{
|
||||
// Keep here same formula as in {@link ExBuySellList} to produce same result.
|
||||
final long profit = (long) (totalPrice * (1.0 - merchant.getCastleTaxRate(TaxType.SELL)));
|
||||
merchant.handleTaxPayment(totalPrice - profit);
|
||||
totalPrice = profit;
|
||||
}
|
||||
|
||||
player.addAdena("Sell", totalPrice, merchant, false);
|
||||
|
||||
// add to castle treasury?
|
||||
if (merchant != null)
|
||||
{
|
||||
final long taxCollection = (long) (totalPrice * (1.0 - merchant.getTotalTaxRate(TaxType.SELL)));
|
||||
merchant.getCastle().addToTreasury(taxCollection);
|
||||
}
|
||||
|
||||
// Update current load as well
|
||||
client.sendPacket(new ExUserInfoInvenWeight(player));
|
||||
client.sendPacket(new ExBuySellList(player, true, merchant != null ? merchant.getTotalTaxRate(TaxType.SELL) : 0));
|
||||
client.sendPacket(new ExBuySellList(player, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class RequestChangeAttributeItem implements IClientIncomingPacket
|
||||
final int oldElementId = item.getAttackAttributeType().getClientId();
|
||||
final int elementValue = item.getAttackAttribute().getValue();
|
||||
item.clearAllAttributes();
|
||||
item.setAttribute(new AttributeHolder(AttributeType.findByClientId(_newElementId), elementValue));
|
||||
item.setAttribute(new AttributeHolder(AttributeType.findByClientId(_newElementId), elementValue), true);
|
||||
|
||||
// send packets
|
||||
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.S1_S_S2_ATTRIBUTE_HAS_SUCCESSFULLY_CHANGED_TO_S3_ATTRIBUTE);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.enums.AttributeType;
|
||||
import com.l2jmobius.gameserver.enums.ItemListType;
|
||||
import com.l2jmobius.gameserver.model.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.TradeItem;
|
||||
@@ -75,15 +76,14 @@ public abstract class AbstractItemPacket extends AbstractMaskPacket<ItemListType
|
||||
packet.writeC(item.getCustomType1()); // Filler (always 0)
|
||||
packet.writeH(item.getEquipped()); // Equipped : 00-No, 01-yes
|
||||
packet.writeQ(item.getItem().getBodyPart()); // Slot : 0006-lr.ear, 0008-neck, 0030-lr.finger, 0040-head, 0100-l.hand, 0200-gloves, 0400-chest, 0800-pants, 1000-feet, 4000-r.hand, 8000-r.hand
|
||||
packet.writeC(item.getEnchant()); // Enchant level (pet level shown in control item)
|
||||
packet.writeC(item.getEnchantLevel()); // Enchant level (pet level shown in control item)
|
||||
packet.writeC(0x01); // TODO : Find me
|
||||
packet.writeD(item.getMana());
|
||||
packet.writeD(item.getTime());
|
||||
packet.writeC(0x01); // GOD Item enabled = 1 disabled (red) = 0
|
||||
if (containsMask(mask, ItemListType.AUGMENT_BONUS))
|
||||
{
|
||||
packet.writeD(item.get1stAugmentationId());
|
||||
packet.writeD(item.get2ndAugmentationId());
|
||||
writeItemAugment(packet, item);
|
||||
}
|
||||
if (containsMask(mask, ItemListType.ELEMENTAL_ATTRIBUTE))
|
||||
{
|
||||
@@ -99,43 +99,22 @@ public abstract class AbstractItemPacket extends AbstractMaskPacket<ItemListType
|
||||
}
|
||||
if (containsMask(mask, ItemListType.SOUL_CRYSTAL))
|
||||
{
|
||||
packet.writeC(item.getSoulCrystalOptions().size()); // Size of regular soul crystal options.
|
||||
for (EnsoulOption option : item.getSoulCrystalOptions())
|
||||
{
|
||||
packet.writeD(option.getId()); // Regular Soul Crystal Ability ID.
|
||||
}
|
||||
|
||||
packet.writeC(item.getSoulCrystalSpecialOptions().size()); // Size of special soul crystal options.
|
||||
for (EnsoulOption option : item.getSoulCrystalSpecialOptions())
|
||||
{
|
||||
packet.writeD(option.getId()); // Special Soul Crystal Ability ID.
|
||||
}
|
||||
writeItemEnsoulOptions(packet, item);
|
||||
}
|
||||
}
|
||||
|
||||
protected static int calculateMask(ItemInfo item)
|
||||
{
|
||||
int mask = 0;
|
||||
if (item.getAugmentationBonus() > 0)
|
||||
if (item.getAugmentation() != null)
|
||||
{
|
||||
mask |= ItemListType.AUGMENT_BONUS.getMask();
|
||||
}
|
||||
|
||||
if (item.getAttackElementType() >= 0)
|
||||
if ((item.getAttackElementType() >= 0) || (item.getAttributeDefence(AttributeType.FIRE) > 0) || (item.getAttributeDefence(AttributeType.WATER) > 0) || (item.getAttributeDefence(AttributeType.WIND) > 0) || (item.getAttributeDefence(AttributeType.EARTH) > 0) || (item.getAttributeDefence(AttributeType.HOLY) > 0) || (item.getAttributeDefence(AttributeType.DARK) > 0))
|
||||
{
|
||||
mask |= ItemListType.ELEMENTAL_ATTRIBUTE.getMask();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (byte i = 0; i < 6; i++)
|
||||
{
|
||||
if (item.getElementDefAttr(i) > 0)
|
||||
{
|
||||
mask |= ItemListType.ELEMENTAL_ATTRIBUTE.getMask();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (item.getEnchantOptions() != null)
|
||||
{
|
||||
@@ -162,6 +141,20 @@ public abstract class AbstractItemPacket extends AbstractMaskPacket<ItemListType
|
||||
return mask;
|
||||
}
|
||||
|
||||
protected void writeItemAugment(PacketWriter packet, ItemInfo item)
|
||||
{
|
||||
if ((item != null) && (item.getAugmentation() != null))
|
||||
{
|
||||
packet.writeD(item.getAugmentation().getOptionId(0));
|
||||
packet.writeD(item.getAugmentation().getOptionId(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeD(0);
|
||||
packet.writeD(0);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeItemElementalAndEnchant(PacketWriter packet, ItemInfo item)
|
||||
{
|
||||
writeItemElemental(packet, item);
|
||||
@@ -170,11 +163,27 @@ public abstract class AbstractItemPacket extends AbstractMaskPacket<ItemListType
|
||||
|
||||
protected void writeItemElemental(PacketWriter packet, ItemInfo item)
|
||||
{
|
||||
packet.writeH(item.getAttackElementType());
|
||||
packet.writeH(item.getAttackElementPower());
|
||||
for (byte i = 0; i < 6; i++)
|
||||
if (item != null)
|
||||
{
|
||||
packet.writeH(item.getElementDefAttr(i));
|
||||
packet.writeH(item.getAttackElementType());
|
||||
packet.writeH(item.getAttackElementPower());
|
||||
packet.writeH(item.getAttributeDefence(AttributeType.FIRE));
|
||||
packet.writeH(item.getAttributeDefence(AttributeType.WATER));
|
||||
packet.writeH(item.getAttributeDefence(AttributeType.WIND));
|
||||
packet.writeH(item.getAttributeDefence(AttributeType.EARTH));
|
||||
packet.writeH(item.getAttributeDefence(AttributeType.HOLY));
|
||||
packet.writeH(item.getAttributeDefence(AttributeType.DARK));
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeH(0);
|
||||
packet.writeH(0);
|
||||
packet.writeH(0);
|
||||
packet.writeH(0);
|
||||
packet.writeH(0);
|
||||
packet.writeH(0);
|
||||
packet.writeH(0);
|
||||
packet.writeH(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +196,29 @@ public abstract class AbstractItemPacket extends AbstractMaskPacket<ItemListType
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeItemEnsoulOptions(PacketWriter packet, ItemInfo item)
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
packet.writeC(item.getSoulCrystalOptions().size()); // Size of regular soul crystal options.
|
||||
for (EnsoulOption option : item.getSoulCrystalOptions())
|
||||
{
|
||||
packet.writeD(option.getId()); // Regular Soul Crystal Ability ID.
|
||||
}
|
||||
|
||||
packet.writeC(item.getSoulCrystalSpecialOptions().size()); // Size of special soul crystal options.
|
||||
for (EnsoulOption option : item.getSoulCrystalSpecialOptions())
|
||||
{
|
||||
packet.writeD(option.getId()); // Special Soul Crystal Ability ID.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeC(0); // Size of regular soul crystal options.
|
||||
packet.writeC(0); // Size of special soul crystal options.
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeInventoryBlock(PacketWriter packet, PcInventory inventory)
|
||||
{
|
||||
if (inventory.hasInventoryBlock())
|
||||
|
||||
@@ -18,10 +18,10 @@ package com.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.buylist.Product;
|
||||
import com.l2jmobius.gameserver.model.buylist.ProductList;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
public final class BuyList extends AbstractItemPacket
|
||||
@@ -29,14 +29,16 @@ public final class BuyList extends AbstractItemPacket
|
||||
private final int _listId;
|
||||
private final Collection<Product> _list;
|
||||
private final long _money;
|
||||
private double _taxRate = 0;
|
||||
private final int _inventorySlots;
|
||||
private final double _castleTaxRate;
|
||||
|
||||
public BuyList(L2BuyList list, long currentMoney, double taxRate)
|
||||
public BuyList(ProductList list, L2PcInstance player, double castleTaxRate)
|
||||
{
|
||||
_listId = list.getListId();
|
||||
_list = list.getProducts();
|
||||
_money = currentMoney;
|
||||
_taxRate = taxRate;
|
||||
_money = player.getAdena();
|
||||
_inventorySlots = player.getInventory().getItems((item) -> !item.isQuestItem()).size();
|
||||
_castleTaxRate = castleTaxRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,23 +49,14 @@ public final class BuyList extends AbstractItemPacket
|
||||
packet.writeD(0x00); // Type BUY
|
||||
packet.writeQ(_money); // current money
|
||||
packet.writeD(_listId);
|
||||
packet.writeD(0x00); // TODO: inventory count
|
||||
packet.writeD(_inventorySlots);
|
||||
packet.writeH(_list.size());
|
||||
|
||||
for (Product product : _list)
|
||||
{
|
||||
if ((product.getCount() > 0) || !product.hasLimitedStock())
|
||||
{
|
||||
writeItem(packet, product);
|
||||
|
||||
if ((product.getItemId() >= 3960) && (product.getItemId() <= 4026))
|
||||
{
|
||||
packet.writeQ((long) (product.getPrice() * Config.RATE_SIEGE_GUARDS_PRICE * (1 + _taxRate)));
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeQ((long) (product.getPrice() * (1 + _taxRate)));
|
||||
}
|
||||
packet.writeQ((long) (product.getPrice() * (1.0 + _castleTaxRate + product.getBaseTaxRate())));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Set;
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||
import com.l2jmobius.gameserver.model.Augmentation;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2DecoyInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.ceremonyofchaos.CeremonyOfChaosEvent;
|
||||
@@ -133,7 +134,9 @@ public class CharInfo implements IClientOutgoingPacket
|
||||
|
||||
for (int slot : getPaperdollOrderAugument())
|
||||
{
|
||||
packet.writeQ(_activeChar.getInventory().getPaperdollAugmentationId(slot)); // Confirmed
|
||||
final Augmentation augment = _activeChar.getInventory().getPaperdollAugmentation(slot);
|
||||
packet.writeD(augment != null ? augment.getOptionId(0) : 0); // Confirmed
|
||||
packet.writeD(augment != null ? augment.getOptionId(1) : 0); // Confirmed
|
||||
}
|
||||
|
||||
packet.writeC(_armorEnchant);
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
|
||||
import com.l2jmobius.gameserver.datatables.AugmentationData;
|
||||
import com.l2jmobius.gameserver.model.CharSelectInfoPackage;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.entity.Hero;
|
||||
@@ -191,7 +192,8 @@ public class CharSelectionInfo implements IClientOutgoingPacket
|
||||
packet.writeD(i == _activeId ? 1 : 0);
|
||||
|
||||
packet.writeC(charInfoPackage.getEnchantEffect() > 127 ? 127 : charInfoPackage.getEnchantEffect());
|
||||
packet.writeQ(charInfoPackage.getAugmentationId());
|
||||
packet.writeD(charInfoPackage.getAugmentation() != null ? charInfoPackage.getAugmentation().getOptionId(0) : 0);
|
||||
packet.writeD(charInfoPackage.getAugmentation() != null ? charInfoPackage.getAugmentation().getOptionId(1) : 0);
|
||||
|
||||
// packet.writeD(charInfoPackage.getTransformId()); // Used to display Transformations
|
||||
packet.writeD(0x00); // Currently on retail when you are on character select you don't see your transformation.
|
||||
@@ -365,7 +367,10 @@ public class CharSelectionInfo implements IClientOutgoingPacket
|
||||
if (result.next())
|
||||
{
|
||||
final int augment = result.getInt("augAttributes");
|
||||
charInfopackage.setAugmentationId(augment == -1 ? 0 : augment);
|
||||
if (augment > 0)
|
||||
{
|
||||
charInfopackage.setAugmentation(AugmentationData.getInstance().getAugmentation(augment));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.l2jmobius.gameserver.network.serverpackets;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
@@ -28,14 +29,17 @@ import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
*/
|
||||
public class ExBuySellList extends AbstractItemPacket
|
||||
{
|
||||
private Collection<L2ItemInstance> _sellList = null;
|
||||
private Collection<L2ItemInstance> _sellList;
|
||||
private Collection<L2ItemInstance> _refundList = null;
|
||||
private final boolean _done;
|
||||
private double _taxRate = 1;
|
||||
private final int _inventorySlots;
|
||||
private double _castleTaxRate = 1;
|
||||
|
||||
public ExBuySellList(L2PcInstance player, boolean done)
|
||||
{
|
||||
_sellList = player.getInventory().getAvailableItems(false, false, false);
|
||||
final L2Summon pet = player.getPet();
|
||||
_sellList = player.getInventory().getItems(item -> !item.isEquipped() && item.isSellable() && ((pet == null) || (item.getObjectId() != pet.getControlObjectId())));
|
||||
_inventorySlots = player.getInventory().getItems((item) -> !item.isQuestItem()).size();
|
||||
if (player.hasRefund())
|
||||
{
|
||||
_refundList = player.getRefund().getItems();
|
||||
@@ -43,10 +47,10 @@ public class ExBuySellList extends AbstractItemPacket
|
||||
_done = done;
|
||||
}
|
||||
|
||||
public ExBuySellList(L2PcInstance player, boolean done, double taxRate)
|
||||
public ExBuySellList(L2PcInstance player, boolean done, double castleTaxRate)
|
||||
{
|
||||
this(player, done);
|
||||
_taxRate = 1 - taxRate;
|
||||
_castleTaxRate = 1 - castleTaxRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,7 +59,7 @@ public class ExBuySellList extends AbstractItemPacket
|
||||
OutgoingPackets.EX_BUY_SELL_LIST.writeId(packet);
|
||||
|
||||
packet.writeD(0x01); // Type SELL
|
||||
packet.writeD(0x00); // TODO: inventory count
|
||||
packet.writeD(_inventorySlots);
|
||||
|
||||
if ((_sellList != null))
|
||||
{
|
||||
@@ -63,15 +67,15 @@ public class ExBuySellList extends AbstractItemPacket
|
||||
for (L2ItemInstance item : _sellList)
|
||||
{
|
||||
writeItem(packet, item);
|
||||
packet.writeQ((long) ((item.getItem().getReferencePrice() / 2) * _taxRate));
|
||||
packet.writeQ((long) ((item.getItem().getReferencePrice() / 2) * _castleTaxRate));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeH(0x00);
|
||||
}
|
||||
|
||||
if ((_refundList != null) && !_refundList.isEmpty())
|
||||
if ((_refundList != null) && !_refundList.isEmpty())
|
||||
{
|
||||
packet.writeH(_refundList.size());
|
||||
int i = 0;
|
||||
@@ -79,7 +83,7 @@ public class ExBuySellList extends AbstractItemPacket
|
||||
{
|
||||
writeItem(packet, item);
|
||||
packet.writeD(i++);
|
||||
packet.writeQ((long) ((item.getItem().getReferencePrice() / 2) * _taxRate));
|
||||
packet.writeQ((item.getItem().getReferencePrice() / 2) * item.getCount());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -26,15 +26,15 @@ public class ExPutItemResultForVariationCancel implements IClientOutgoingPacket
|
||||
private final int _itemId;
|
||||
private final int _itemAug1;
|
||||
private final int _itemAug2;
|
||||
private final int _price;
|
||||
private final long _price;
|
||||
|
||||
public ExPutItemResultForVariationCancel(L2ItemInstance item, int price)
|
||||
public ExPutItemResultForVariationCancel(L2ItemInstance item, long price)
|
||||
{
|
||||
_itemObjId = item.getObjectId();
|
||||
_itemId = item.getDisplayId();
|
||||
_price = price;
|
||||
_itemAug1 = ((short) item.getAugmentation().getId());
|
||||
_itemAug2 = item.getAugmentation().getId() >> 16;
|
||||
_itemAug1 = item.getAugmentation().getOptionId(0);
|
||||
_itemAug2 = item.getAugmentation().getOptionId(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.enums.InventorySlot;
|
||||
import com.l2jmobius.gameserver.model.Augmentation;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.PcInventory;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
@@ -73,10 +74,12 @@ public class ExUserInfoEquipSlot extends AbstractMaskPacket<InventorySlot>
|
||||
{
|
||||
if (containsMask(slot))
|
||||
{
|
||||
final Augmentation augment = inventory.getPaperdollAugmentation(slot.getSlot());
|
||||
packet.writeH(22); // 10 + 4 * 3
|
||||
packet.writeD(inventory.getPaperdollObjectId(slot.getSlot()));
|
||||
packet.writeD(inventory.getPaperdollItemId(slot.getSlot()));
|
||||
packet.writeQ(inventory.getPaperdollAugmentationId(slot.getSlot()));
|
||||
packet.writeD(augment != null ? augment.getOptionId(0) : 0);
|
||||
packet.writeD(augment != null ? augment.getOptionId(1) : 0);
|
||||
packet.writeD(inventory.getPaperdollItemVisualId(slot.getSlot()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,8 @@ public class FakePlayerInfo implements IClientOutgoingPacket
|
||||
for (@SuppressWarnings("unused")
|
||||
int slot : getPaperdollOrderAugument())
|
||||
{
|
||||
packet.writeQ(0x00);
|
||||
packet.writeD(0x00);
|
||||
packet.writeD(0x00);
|
||||
}
|
||||
|
||||
packet.writeC(_fpcHolder.getArmorEnchantLevel());
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.l2jmobius.gameserver.network.serverpackets;
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
|
||||
import com.l2jmobius.gameserver.enums.AttributeType;
|
||||
import com.l2jmobius.gameserver.model.Augmentation;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
@@ -88,7 +89,9 @@ public class GMViewCharacterInfo implements IClientOutgoingPacket
|
||||
|
||||
for (int slot : getPaperdollOrder())
|
||||
{
|
||||
packet.writeQ(_activeChar.getInventory().getPaperdollAugmentationId(slot));
|
||||
final Augmentation augment = _activeChar.getInventory().getPaperdollAugmentation(slot);
|
||||
packet.writeD(augment != null ? augment.getOptionId(0) : 0); // Confirmed
|
||||
packet.writeD(augment != null ? augment.getOptionId(1) : 0); // Confirmed
|
||||
}
|
||||
|
||||
packet.writeC(_activeChar.getInventory().getTalismanSlots()); // CT2.3
|
||||
|
||||
@@ -48,7 +48,7 @@ public class GMViewSkillInfo implements IClientOutgoingPacket
|
||||
{
|
||||
packet.writeD(skill.isPassive() ? 1 : 0);
|
||||
packet.writeH(skill.getDisplayLevel());
|
||||
packet.writeH(0x00); // Sub level
|
||||
packet.writeH(skill.getSubLevel());
|
||||
packet.writeD(skill.getDisplayId());
|
||||
packet.writeD(0x00);
|
||||
packet.writeC(isDisabled && skill.isClanSkill() ? 1 : 0);
|
||||
|
||||
@@ -19,21 +19,22 @@ package com.l2jmobius.gameserver.network.serverpackets;
|
||||
import static com.l2jmobius.gameserver.data.xml.impl.MultisellData.PAGE_SIZE;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
|
||||
import com.l2jmobius.gameserver.model.items.enchant.attribute.AttributeHolder;
|
||||
import com.l2jmobius.gameserver.model.multisell.Entry;
|
||||
import com.l2jmobius.gameserver.model.multisell.Ingredient;
|
||||
import com.l2jmobius.gameserver.model.multisell.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.multisell.ListContainer;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.ItemInfo;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.MultisellEntryHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.PreparedMultisellListHolder;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
public final class MultiSellList implements IClientOutgoingPacket
|
||||
public final class MultiSellList extends AbstractItemPacket
|
||||
{
|
||||
private int _size, _index;
|
||||
private final ListContainer _list;
|
||||
private final PreparedMultisellListHolder _list;
|
||||
private final boolean _finished;
|
||||
|
||||
public MultiSellList(ListContainer list, int index)
|
||||
public MultiSellList(PreparedMultisellListHolder list, int index)
|
||||
{
|
||||
_list = list;
|
||||
_index = index;
|
||||
@@ -54,175 +55,71 @@ public final class MultiSellList implements IClientOutgoingPacket
|
||||
{
|
||||
OutgoingPackets.MULTI_SELL_LIST.writeId(packet);
|
||||
|
||||
packet.writeC(0x00);
|
||||
packet.writeD(_list.getListId()); // list id
|
||||
packet.writeC(0x00); // Helios
|
||||
packet.writeD(_list.getId()); // list id
|
||||
packet.writeC(0x00); // GOD Unknown
|
||||
packet.writeD(1 + (_index / PAGE_SIZE)); // page started from 1
|
||||
packet.writeD(_finished ? 0x01 : 0x00); // finished
|
||||
packet.writeD(PAGE_SIZE); // size of pages
|
||||
packet.writeD(_size); // list length
|
||||
packet.writeC(_list.isChanceMultisell() ? 0x01 : 0x00); // new multisell window
|
||||
packet.writeD(0x20); // Always 32 oO
|
||||
packet.writeD(0x20); // Helios - Always 32
|
||||
|
||||
Entry ent;
|
||||
while (_size-- > 0)
|
||||
{
|
||||
ent = _list.getEntries().get(_index++);
|
||||
packet.writeD(ent.getEntryId());
|
||||
packet.writeC(ent.isStackable() ? 1 : 0);
|
||||
packet.writeH(0x00);
|
||||
packet.writeD(0x00);
|
||||
packet.writeD(0x00);
|
||||
packet.writeH(0x00);
|
||||
packet.writeH(0x00);
|
||||
packet.writeH(0x00);
|
||||
packet.writeH(0x00);
|
||||
packet.writeH(0x00);
|
||||
packet.writeH(0x00);
|
||||
packet.writeH(0x00);
|
||||
packet.writeH(0x00);
|
||||
packet.writeC(0); // Size of regular soul crystal options.
|
||||
// for (EnsoulOption option : item.getSoulCrystalOptions())
|
||||
// {
|
||||
// packet.writeD(option.getId()); // Regular Soul Crystal Ability ID.
|
||||
// }
|
||||
final ItemInfo itemEnchantment = _list.getItemEnchantment(_index);
|
||||
final MultisellEntryHolder entry = _list.getEntries().get(_index++);
|
||||
|
||||
packet.writeC(0); // Size of special soul crystal options.
|
||||
// for (EnsoulOption option : item.getSoulCrystalSpecialOptions())
|
||||
// {
|
||||
// packet.writeD(option.getId()); // Special Soul Crystal Ability ID.
|
||||
// }
|
||||
packet.writeD(_index); // Entry ID. Start from 1.
|
||||
packet.writeC(entry.isStackable() ? 1 : 0);
|
||||
|
||||
packet.writeH(ent.getProducts().size());
|
||||
packet.writeH(ent.getIngredients().size());
|
||||
// Those values will be passed down to MultiSellChoose packet.
|
||||
packet.writeH(itemEnchantment != null ? itemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
writeItemAugment(packet, itemEnchantment);
|
||||
writeItemElemental(packet, itemEnchantment);
|
||||
writeItemEnsoulOptions(packet, itemEnchantment);
|
||||
|
||||
for (Ingredient ing : ent.getProducts())
|
||||
packet.writeH(entry.getProducts().size());
|
||||
packet.writeH(entry.getIngredients().size());
|
||||
|
||||
for (ItemChanceHolder product : entry.getProducts())
|
||||
{
|
||||
packet.writeD(ing.getItemId());
|
||||
if (ing.getTemplate() != null)
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(product.getId());
|
||||
final ItemInfo displayItemEnchantment = (_list.isMaintainEnchantment() && (itemEnchantment != null) && (template != null) && template.getClass().equals(itemEnchantment.getItem().getClass())) ? itemEnchantment : null;
|
||||
|
||||
packet.writeD(product.getId());
|
||||
if (template != null)
|
||||
{
|
||||
packet.writeQ(ing.getTemplate().getBodyPart());
|
||||
packet.writeH(ing.getTemplate().getType2());
|
||||
packet.writeQ(template.getBodyPart());
|
||||
packet.writeH(template.getType2());
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeQ(0);
|
||||
packet.writeH(65535);
|
||||
}
|
||||
packet.writeQ(ing.getItemCount());
|
||||
if (ing.getItemInfo() != null)
|
||||
{
|
||||
final ItemInfo item = ing.getItemInfo();
|
||||
packet.writeH(item.getEnchantLevel()); // enchant level
|
||||
packet.writeD((int) (_list.isChanceMultisell() ? ing.getChance() : item.getAugmentId())); // augment id
|
||||
packet.writeD(0x00); // mana
|
||||
packet.writeD(0x00); // time ?
|
||||
packet.writeH(item.getElementId()); // attack element
|
||||
packet.writeH(item.getElementPower()); // element power
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
final AttributeHolder holder = item.getElementals()[i];
|
||||
packet.writeH(holder != null ? holder.getValue() : 0);
|
||||
}
|
||||
|
||||
packet.writeC(item.getSpecialAbilities().size()); // Size of regular soul crystal options.
|
||||
for (EnsoulOption option : item.getSpecialAbilities())
|
||||
{
|
||||
packet.writeD(option.getId()); // Regular Soul Crystal Ability ID.
|
||||
}
|
||||
|
||||
packet.writeC(item.getAdditionalSpecialAbilities().size()); // Size of special soul crystal options.
|
||||
for (EnsoulOption option : item.getAdditionalSpecialAbilities())
|
||||
{
|
||||
packet.writeD(option.getId()); // Special Soul Crystal Ability ID.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeH(ing.getEnchantLevel()); // enchant level
|
||||
packet.writeD((int) ing.getChance()); // augment id
|
||||
packet.writeD(0x00); // mana
|
||||
packet.writeD(0x00); // time ?
|
||||
packet.writeH(0x00); // attack element
|
||||
packet.writeH(0x00); // element power
|
||||
packet.writeH(0x00); // fire
|
||||
packet.writeH(0x00); // water
|
||||
packet.writeH(0x00); // wind
|
||||
packet.writeH(0x00); // earth
|
||||
packet.writeH(0x00); // holy
|
||||
packet.writeH(0x00); // dark
|
||||
packet.writeC(0); // Size of regular soul crystal options.
|
||||
// for (EnsoulOption option : item.getSoulCrystalOptions())
|
||||
// {
|
||||
// packet.writeD(option.getId()); // Regular Soul Crystal Ability ID.
|
||||
// }
|
||||
|
||||
packet.writeC(0); // Size of special soul crystal options.
|
||||
// for (EnsoulOption option : item.getSoulCrystalSpecialOptions())
|
||||
// {
|
||||
// packet.writeD(option.getId()); // Special Soul Crystal Ability ID.
|
||||
// }
|
||||
}
|
||||
packet.writeQ(_list.getProductCount(product));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
packet.writeD((int) Math.ceil(product.getChance())); // chance
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
}
|
||||
|
||||
for (Ingredient ing : ent.getIngredients())
|
||||
for (ItemHolder ingredient : entry.getIngredients())
|
||||
{
|
||||
packet.writeD(ing.getItemId());
|
||||
packet.writeH(ing.getTemplate() != null ? ing.getTemplate().getType2() : 65535);
|
||||
packet.writeQ(ing.getItemCount());
|
||||
if (ing.getItemInfo() != null)
|
||||
{
|
||||
final ItemInfo item = ing.getItemInfo();
|
||||
packet.writeH(item.getEnchantLevel()); // enchant level
|
||||
packet.writeD((int) (_list.isChanceMultisell() ? ing.getChance() : item.getAugmentId())); // augment id
|
||||
packet.writeD(0x00); // mana
|
||||
packet.writeH(item.getElementId()); // attack element
|
||||
packet.writeH(item.getElementPower()); // element power
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
final AttributeHolder holder = item.getElementals()[i];
|
||||
packet.writeH(holder != null ? holder.getValue() : 0);
|
||||
}
|
||||
packet.writeC(item.getSpecialAbilities().size()); // Size of regular soul crystal options.
|
||||
for (EnsoulOption option : item.getSpecialAbilities())
|
||||
{
|
||||
packet.writeD(option.getId()); // Regular Soul Crystal Ability ID.
|
||||
}
|
||||
|
||||
packet.writeC(item.getAdditionalSpecialAbilities().size()); // Size of special soul crystal options.
|
||||
for (EnsoulOption option : item.getAdditionalSpecialAbilities())
|
||||
{
|
||||
packet.writeD(option.getId()); // Special Soul Crystal Ability ID.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeH(ing.getEnchantLevel()); // enchant level
|
||||
packet.writeD((int) ing.getChance()); // augment id
|
||||
packet.writeD(0x00); // mana
|
||||
packet.writeH(0x00); // attack element
|
||||
packet.writeH(0x00); // element power
|
||||
packet.writeH(0x00); // fire
|
||||
packet.writeH(0x00); // water
|
||||
packet.writeH(0x00); // wind
|
||||
packet.writeH(0x00); // earth
|
||||
packet.writeH(0x00); // holy
|
||||
packet.writeH(0x00); // dark
|
||||
packet.writeC(0); // Size of regular soul crystal options.
|
||||
// for (EnsoulOption option : item.getSoulCrystalOptions())
|
||||
// {
|
||||
// packet.writeD(option.getId()); // Regular Soul Crystal Ability ID.
|
||||
// }
|
||||
|
||||
packet.writeC(0); // Size of special soul crystal options.
|
||||
// for (EnsoulOption option : item.getSoulCrystalSpecialOptions())
|
||||
// {
|
||||
// packet.writeD(option.getId()); // Special Soul Crystal Ability ID.
|
||||
// }
|
||||
}
|
||||
final L2Item template = ItemTable.getInstance().getTemplate(ingredient.getId());
|
||||
final ItemInfo displayItemEnchantment = ((itemEnchantment != null) && (itemEnchantment.getItem().getId() == ingredient.getId())) ? itemEnchantment : null;
|
||||
|
||||
packet.writeD(ingredient.getId());
|
||||
packet.writeH(template != null ? template.getType2() : 65535);
|
||||
packet.writeQ(_list.getIngredientCount(ingredient));
|
||||
packet.writeH(displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
writeItemAugment(packet, displayItemEnchantment);
|
||||
writeItemElemental(packet, displayItemEnchantment);
|
||||
writeItemEnsoulOptions(packet, displayItemEnchantment);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,111 +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.network.serverpackets;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.enums.AttributeType;
|
||||
import com.l2jmobius.gameserver.enums.TaxType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MerchantInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
public class SellList implements IClientOutgoingPacket
|
||||
{
|
||||
private final L2PcInstance _activeChar;
|
||||
private final L2MerchantInstance _merchant;
|
||||
private final long _money;
|
||||
private final List<L2ItemInstance> _sellList;
|
||||
|
||||
public SellList(L2PcInstance player)
|
||||
{
|
||||
this(player, null);
|
||||
}
|
||||
|
||||
public SellList(L2PcInstance player, L2MerchantInstance lease)
|
||||
{
|
||||
_activeChar = player;
|
||||
_merchant = lease;
|
||||
_money = _activeChar.getAdena();
|
||||
|
||||
if (_merchant == null)
|
||||
{
|
||||
_sellList = new LinkedList<>();
|
||||
final L2Summon pet = _activeChar.getPet();
|
||||
for (L2ItemInstance item : _activeChar.getInventory().getItems())
|
||||
{
|
||||
if (!item.isEquipped() && item.isSellable() && ((pet == null) || (item.getObjectId() != pet.getControlObjectId()))) // Pet is summoned and not the item that summoned the pet
|
||||
{
|
||||
_sellList.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_sellList = Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean write(PacketWriter packet)
|
||||
{
|
||||
OutgoingPackets.SELL_LIST.writeId(packet);
|
||||
|
||||
packet.writeQ(_money);
|
||||
packet.writeD(_merchant == null ? 0x00 : 1000000 + _merchant.getTemplate().getId());
|
||||
packet.writeH(_sellList.size());
|
||||
|
||||
for (L2ItemInstance item : _sellList)
|
||||
{
|
||||
int price = item.getItem().getReferencePrice() / 2;
|
||||
if (_merchant != null)
|
||||
{
|
||||
price -= (price * _merchant.getTotalTaxRate(TaxType.SELL));
|
||||
}
|
||||
|
||||
packet.writeH(item.getItem().getType1());
|
||||
packet.writeD(item.getObjectId());
|
||||
packet.writeD(item.getDisplayId());
|
||||
packet.writeQ(item.getCount());
|
||||
packet.writeH(item.getItem().getType2());
|
||||
packet.writeH(item.isEquipped() ? 0x01 : 0x00);
|
||||
packet.writeD(item.getItem().getBodyPart());
|
||||
packet.writeH(item.getEnchantLevel());
|
||||
packet.writeH(0x00); // TODO: Verify me
|
||||
packet.writeH(item.getCustomType2());
|
||||
packet.writeQ(price);
|
||||
// T1
|
||||
packet.writeH(item.getAttackAttributeType().getClientId());
|
||||
packet.writeH(item.getAttackAttributePower());
|
||||
for (AttributeType type : AttributeType.ATTRIBUTE_TYPES)
|
||||
{
|
||||
packet.writeH(item.getDefenceAttribute(type));
|
||||
}
|
||||
// Enchant Effects
|
||||
for (int op : item.getEnchantOptions())
|
||||
{
|
||||
packet.writeH(op);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,8 @@ import java.util.Collection;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.model.buylist.Product;
|
||||
import com.l2jmobius.gameserver.model.buylist.ProductList;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
@@ -32,7 +32,7 @@ public class ShopPreviewList implements IClientOutgoingPacket
|
||||
private final long _money;
|
||||
private int _expertise;
|
||||
|
||||
public ShopPreviewList(L2BuyList list, long currentMoney, int expertiseIndex)
|
||||
public ShopPreviewList(ProductList list, long currentMoney, int expertiseIndex)
|
||||
{
|
||||
_listId = list.getListId();
|
||||
_list = list.getProducts();
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ExResponseCommissionBuyItem implements IClientOutgoingPacket
|
||||
if (_commissionItem != null)
|
||||
{
|
||||
final ItemInfo itemInfo = _commissionItem.getItemInfo();
|
||||
packet.writeD(itemInfo.getEnchant());
|
||||
packet.writeD(itemInfo.getEnchantLevel());
|
||||
packet.writeD(itemInfo.getItem().getId());
|
||||
packet.writeQ(itemInfo.getCount());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user