Dropped MerchantPriceConfigTable to match retail.

This commit is contained in:
MobiusDev 2017-08-04 16:00:27 +00:00
parent 53f1a866cc
commit 1f3396c8e3
21 changed files with 78 additions and 1113 deletions

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Documentation: -->
<!-- defaultPriceConfig -> ID of one of the price configs defined to be used when NPC has no price config. Can be ANY of the defined priceConfigs. Cannot be ommited, althrough you can emulate this by creating a dummy priceConfig. -->
<!-- id -> Defines the ID for relational references. -->
<!-- name -> Name of the area, for human-friendlyness and debugging, cannot be ommited. -->
<!-- baseTax -> Used on merchant item price calculation (see formula in the end), cannot be ommited. -->
<!-- castleId -> ID of the castle that controls merchants of this config, castle tax will apply to merchants price. Can be ommited (causes it to assume that no castle controls this config). -->
<!-- zoneId -> Attaches a given Town Zone to this priceConfig for convenience. -->
<!-- Merchant NPCs that dont explicit define an priceConfig will check if they are inside of the zone of an priceConfig, if yes that priceConfig is used for that npc. Can be ommited, then no NPC will be added based on zone (ie priceConfig direct assigned to NPCs through config or when used as the default priceConfig). -->
<!-- Merchant Price Formula price = baseItemPrice * (1 + baseTax/100 + castleTax/100) -->
<merchantPriceConfig defaultPriceConfig="18" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/MerchantPriceConfig.xsd">
<priceConfig id="0" name="Giran Town" baseTax="10" castleId="3" zoneId="11020" />
<priceConfig id="1" name="DE Village" baseTax="15" castleId="4" zoneId="11021" />
<priceConfig id="2" name="Talking Island" baseTax="15" castleId="1" zoneId="11022" />
<priceConfig id="3" name="Elven Village" baseTax="15" castleId="4" zoneId="11023" />
<priceConfig id="4" name="Orc Village" baseTax="15" castleId="9" zoneId="11024" />
<priceConfig id="5" name="Gludin Village" baseTax="20" castleId="1" zoneId="11025" />
<priceConfig id="6" name="Dwarven Village" baseTax="15" castleId="9" zoneId="11026" />
<priceConfig id="7" name="Kamael Village" baseTax="15" castleId="5" zoneId="11038" />
<priceConfig id="8" name="Gludio Town" baseTax="20" castleId="1" zoneId="11027" />
<priceConfig id="9" name="Dion Town" baseTax="20" castleId="2" zoneId="11028" />
<priceConfig id="10" name="Oren Town" baseTax="15" castleId="4" zoneId="11029" />
<priceConfig id="11" name="Hunters Village" baseTax="30" castleId="5" zoneId="11030" />
<priceConfig id="12" name="Aden Town" baseTax="20" castleId="5" zoneId="11031" />
<priceConfig id="13" name="Goddard Town" baseTax="20" castleId="7" zoneId="11032" />
<priceConfig id="14" name="Rune Town" baseTax="20" castleId="8" zoneId="11033" />
<priceConfig id="15" name="Heine Town" baseTax="20" castleId="6" zoneId="11034" />
<priceConfig id="16" name="Schuttgart Town" baseTax="20" castleId="9" zoneId="11035" />
<priceConfig id="17" name="Floran Village" baseTax="50" castleId="2" zoneId="11036" />
<priceConfig id="18" name="Neutral Territory" baseTax="50" />
<priceConfig id="19" name="Gludio Castle" baseTax="10" castleId="1" zoneId="11200" />
<priceConfig id="20" name="Dion Castle" baseTax="10" castleId="2" zoneId="11201" />
<priceConfig id="21" name="Giran Castle" baseTax="10" castleId="3" zoneId="11202" />
<priceConfig id="22" name="Oren Castle" baseTax="10" castleId="4" zoneId="11203" />
<priceConfig id="23" name="Aden Castle" baseTax="10" castleId="5" zoneId="11204" />
<priceConfig id="24" name="Innadril Castle" baseTax="10" castleId="6" zoneId="11205" />
<priceConfig id="25" name="Goddard Castle" baseTax="10" castleId="7" zoneId="11206" />
<priceConfig id="26" name="Rune Castle" baseTax="10" castleId="8" zoneId="11207" />
<priceConfig id="27" name="Schuttgart Castle" baseTax="10" castleId="9" zoneId="11208" />
</merchantPriceConfig>

View File

@ -97,7 +97,6 @@ import com.l2jmobius.gameserver.datatables.AugmentationData;
import com.l2jmobius.gameserver.datatables.BotReportTable;
import com.l2jmobius.gameserver.datatables.EventDroplist;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
import com.l2jmobius.gameserver.geodata.GeoData;
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
import com.l2jmobius.gameserver.handler.ConditionHandler;
@ -229,7 +228,6 @@ public class GameServer
OptionData.getInstance();
EnsoulData.getInstance();
EnchantItemHPBonusData.getInstance();
MerchantPriceConfigTable.getInstance().loadInstances();
BuyListData.getInstance();
MultisellData.getInstance();
RecipeData.getInstance();
@ -362,7 +360,6 @@ public class GameServer
// FortSiegeManager.getInstance();
SiegeScheduleData.getInstance();
MerchantPriceConfigTable.getInstance().updateReferences();
CastleManorManager.getInstance();
SiegeGuardManager.getInstance();
QuestManager.getInstance().report();

View File

@ -1,291 +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.datatables;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.InstanceListManager;
import com.l2jmobius.gameserver.enums.TaxType;
import com.l2jmobius.gameserver.instancemanager.CastleManager;
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
import com.l2jmobius.gameserver.model.actor.instance.L2MerchantInstance;
import com.l2jmobius.gameserver.model.entity.Castle;
/**
* @author KenM
*/
public class MerchantPriceConfigTable implements InstanceListManager
{
// Zoey76: TODO: Implement using IGameXmlReader.
private static Logger LOGGER = Logger.getLogger(MerchantPriceConfigTable.class.getName());
public static MerchantPriceConfigTable getInstance()
{
return SingletonHolder._instance;
}
private static final String MPCS_FILE = "MerchantPriceConfig.xml";
private final Map<Integer, MerchantPriceConfig> _mpcs = new HashMap<>();
private MerchantPriceConfig _defaultMpc;
public MerchantPriceConfig getMerchantPriceConfig(L2MerchantInstance npc)
{
for (MerchantPriceConfig mpc : _mpcs.values())
{
if (ZoneManager.getInstance().getRegion(npc).getZones().containsKey(mpc.getZoneId()))
{
return mpc;
}
}
return _defaultMpc;
}
public MerchantPriceConfig getMerchantPriceConfig(int id)
{
return _mpcs.get(id);
}
public void loadXML() throws SAXException, IOException, ParserConfigurationException
{
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setIgnoringComments(true);
final File file = new File(Config.DATAPACK_ROOT + "/data/" + MPCS_FILE);
if (file.exists())
{
int defaultPriceConfigId;
final Document doc = factory.newDocumentBuilder().parse(file);
Node n = doc.getDocumentElement();
final Node dpcNode = n.getAttributes().getNamedItem("defaultPriceConfig");
if (dpcNode == null)
{
throw new IllegalStateException("merchantPriceConfig must define an 'defaultPriceConfig'");
}
defaultPriceConfigId = Integer.parseInt(dpcNode.getNodeValue());
MerchantPriceConfig mpc;
for (n = n.getFirstChild(); n != null; n = n.getNextSibling())
{
mpc = parseMerchantPriceConfig(n);
if (mpc != null)
{
_mpcs.put(mpc.getId(), mpc);
}
}
final MerchantPriceConfig defaultMpc = getMerchantPriceConfig(defaultPriceConfigId);
if (defaultMpc == null)
{
throw new IllegalStateException("'defaultPriceConfig' points to an non-loaded priceConfig");
}
_defaultMpc = defaultMpc;
}
}
private MerchantPriceConfig parseMerchantPriceConfig(Node n)
{
if (n.getNodeName().equals("priceConfig"))
{
final int id;
final int baseTax;
int castleId = -1;
int zoneId = -1;
final String name;
Node node = n.getAttributes().getNamedItem("id");
if (node == null)
{
throw new IllegalStateException("Must define the priceConfig 'id'");
}
id = Integer.parseInt(node.getNodeValue());
node = n.getAttributes().getNamedItem("name");
if (node == null)
{
throw new IllegalStateException("Must define the priceConfig 'name'");
}
name = node.getNodeValue();
node = n.getAttributes().getNamedItem("baseTax");
if (node == null)
{
throw new IllegalStateException("Must define the priceConfig 'baseTax'");
}
baseTax = Integer.parseInt(node.getNodeValue());
node = n.getAttributes().getNamedItem("castleId");
if (node != null)
{
castleId = Integer.parseInt(node.getNodeValue());
}
node = n.getAttributes().getNamedItem("zoneId");
if (node != null)
{
zoneId = Integer.parseInt(node.getNodeValue());
}
return new MerchantPriceConfig(id, name, baseTax, castleId, zoneId);
}
return null;
}
@Override
public void loadInstances()
{
try
{
loadXML();
LOGGER.info("Loaded " + _mpcs.size() + " merchant price configs.");
}
catch (Exception e)
{
LOGGER.severe("Failed loading MerchantPriceConfigTable: " + e);
}
}
@Override
public void updateReferences()
{
for (MerchantPriceConfig mpc : _mpcs.values())
{
mpc.updateReferences();
}
}
@Override
public void activateInstances()
{
}
/**
* @author KenM
*/
public static final class MerchantPriceConfig
{
private final int _id;
private final String _name;
private final int _baseTax;
private final int _castleId;
private Castle _castle;
private final int _zoneId;
public MerchantPriceConfig(int id, String name, int baseTax, int castleId, int zoneId)
{
_id = id;
_name = name;
_baseTax = baseTax;
_castleId = castleId;
_zoneId = zoneId;
}
/**
* @return Returns the id.
*/
public int getId()
{
return _id;
}
/**
* @return Returns the name.
*/
public String getName()
{
return _name;
}
/**
* @return Returns the baseTax.
*/
public int getBaseTax()
{
return _baseTax;
}
/**
* @return Returns the baseTax / 100.0.
*/
public double getBaseTaxRate()
{
return _baseTax / 100.0;
}
/**
* @return Returns the castle.
*/
public Castle getCastle()
{
return _castle;
}
/**
* @return Returns the zoneId.
*/
public int getZoneId()
{
return _zoneId;
}
public boolean hasCastle()
{
return getCastle() != null;
}
public double getCastleTaxRate()
{
return hasCastle() ? getCastle().getTaxRate() : 0.0;
}
public int getTotalTax(TaxType taxType)
{
return hasCastle() ? (getCastle().getTaxPercent(taxType) + getBaseTax()) : getBaseTax();
}
public double getTotalTaxRate(TaxType taxType)
{
return getTotalTax(taxType) / 100.0;
}
public void updateReferences()
{
if (_castleId > 0)
{
_castle = CastleManager.getInstance().getCastleById(_castleId);
}
}
}
private static class SingletonHolder
{
protected static final MerchantPriceConfigTable _instance = new MerchantPriceConfigTable();
}
}

View File

@ -17,8 +17,6 @@
package com.l2jmobius.gameserver.model.actor.instance;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable.MerchantPriceConfig;
import com.l2jmobius.gameserver.enums.InstanceType;
import com.l2jmobius.gameserver.enums.TaxType;
import com.l2jmobius.gameserver.model.actor.L2Character;
@ -34,8 +32,6 @@ import com.l2jmobius.gameserver.network.serverpackets.ExBuySellList;
*/
public class L2MerchantInstance extends L2NpcInstance
{
private MerchantPriceConfig _mpc;
public L2MerchantInstance(L2NpcTemplate template)
{
super(template);
@ -53,13 +49,6 @@ public class L2MerchantInstance extends L2NpcInstance
return super.isAutoAttackable(attacker);
}
@Override
public void onSpawn()
{
super.onSpawn();
_mpc = MerchantPriceConfigTable.getInstance().getMerchantPriceConfig(this);
}
@Override
public String getHtmlPath(int npcId, int val)
{
@ -77,14 +66,6 @@ public class L2MerchantInstance extends L2NpcInstance
return "data/html/merchant/" + pom + ".htm";
}
/**
* @return Returns the mpc.
*/
public MerchantPriceConfig getMpc()
{
return _mpc;
}
public final void showBuyWindow(L2PcInstance player, int val)
{
showBuyWindow(player, val, true);
@ -107,13 +88,30 @@ public class L2MerchantInstance extends L2NpcInstance
return;
}
final double buyTaxRate = (applyTax) ? getMpc().getTotalTaxRate(TaxType.BUY) : 0;
final double sellTaxRate = (applyTax) ? getMpc().getTotalTaxRate(TaxType.SELL) : 0;
player.setInventoryBlockingStatus(true);
player.sendPacket(new BuyList(buyList, player.getAdena(), buyTaxRate));
player.sendPacket(new ExBuySellList(player, false, sellTaxRate));
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 double getCastleTaxRate()
{
return hasCastle() ? getCastle().getTaxRate() : 0.0;
}
public int getTotalTax(TaxType taxType)
{
return hasCastle() ? getCastle().getTaxPercent(taxType) : 0;
}
public double getTotalTaxRate(TaxType taxType)
{
return getTotalTax(taxType) / 100.0;
}
}

View File

@ -114,7 +114,6 @@ public final class RequestBuyItem implements IClientIncomingPacket
}
double castleTaxRate = 0;
double baseTaxRate = 0;
if ((merchant == null) && !player.isGM() && (_listId != CUSTOM_CB_SELL_LIST))
{
@ -137,15 +136,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
return;
}
if (merchant instanceof L2MerchantInstance)
{
castleTaxRate = ((L2MerchantInstance) merchant).getMpc().getCastleTaxRate();
baseTaxRate = ((L2MerchantInstance) merchant).getMpc().getBaseTaxRate();
}
else
{
baseTaxRate = 0.5;
}
castleTaxRate = ((L2MerchantInstance) merchant).getCastleTaxRate();
}
long subTotal = 0;
@ -207,7 +198,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
return;
}
// first calculate price per item with tax, then multiply by count
price = (long) (price * (1 + castleTaxRate + baseTaxRate));
price = (long) (price * (1 + castleTaxRate));
subTotal += i.getCount() * price;
if (subTotal > MAX_ADENA)
{

View File

@ -175,7 +175,7 @@ public final class RequestSellItem implements IClientIncomingPacket
if (merchant instanceof L2MerchantInstance)
{
final L2MerchantInstance npc = ((L2MerchantInstance) merchant);
final long taxCollection = (long) (totalPrice * npc.getMpc().getTotalTaxRate(TaxType.SELL));
final long taxCollection = (long) (totalPrice * (1.0 - npc.getTotalTaxRate(TaxType.SELL)));
npc.getCastle().addToTreasury(taxCollection);
totalPrice -= taxCollection;
}

View File

@ -79,7 +79,7 @@ public class SellList implements IClientOutgoingPacket
int price = item.getItem().getReferencePrice() / 2;
if (_lease != null)
{
price -= (price * _lease.getMpc().getTotalTaxRate(TaxType.SELL));
price -= (price * _lease.getTotalTaxRate(TaxType.SELL));
}
packet.writeH(item.getItem().getType1());

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Documentation: -->
<!-- defaultPriceConfig -> ID of one of the price configs defined to be used when NPC has no price config. Can be ANY of the defined priceConfigs. Cannot be ommited, althrough you can emulate this by creating a dummy priceConfig. -->
<!-- id -> Defines the ID for relational references. -->
<!-- name -> Name of the area, for human-friendlyness and debugging, cannot be ommited. -->
<!-- baseTax -> Used on merchant item price calculation (see formula in the end), cannot be ommited. -->
<!-- castleId -> ID of the castle that controls merchants of this config, castle tax will apply to merchants price. Can be ommited (causes it to assume that no castle controls this config). -->
<!-- zoneId -> Attaches a given Town Zone to this priceConfig for convenience. -->
<!-- Merchant NPCs that dont explicit define an priceConfig will check if they are inside of the zone of an priceConfig, if yes that priceConfig is used for that npc. Can be ommited, then no NPC will be added based on zone (ie priceConfig direct assigned to NPCs through config or when used as the default priceConfig). -->
<!-- Merchant Price Formula price = baseItemPrice * (1 + baseTax/100 + castleTax/100) -->
<merchantPriceConfig defaultPriceConfig="18" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/MerchantPriceConfig.xsd">
<priceConfig id="0" name="Giran Town" baseTax="10" castleId="3" zoneId="11020" />
<priceConfig id="1" name="DE Village" baseTax="15" castleId="4" zoneId="11021" />
<priceConfig id="2" name="Talking Island" baseTax="15" castleId="1" zoneId="11022" />
<priceConfig id="3" name="Elven Village" baseTax="15" castleId="4" zoneId="11023" />
<priceConfig id="4" name="Orc Village" baseTax="15" castleId="9" zoneId="11024" />
<priceConfig id="5" name="Gludin Village" baseTax="20" castleId="1" zoneId="11025" />
<priceConfig id="6" name="Dwarven Village" baseTax="15" castleId="9" zoneId="11026" />
<priceConfig id="7" name="Kamael Village" baseTax="15" castleId="5" zoneId="11038" />
<priceConfig id="8" name="Gludio Town" baseTax="20" castleId="1" zoneId="11027" />
<priceConfig id="9" name="Dion Town" baseTax="20" castleId="2" zoneId="11028" />
<priceConfig id="10" name="Oren Town" baseTax="15" castleId="4" zoneId="11029" />
<priceConfig id="11" name="Hunters Village" baseTax="30" castleId="5" zoneId="11030" />
<priceConfig id="12" name="Aden Town" baseTax="20" castleId="5" zoneId="11031" />
<priceConfig id="13" name="Goddard Town" baseTax="20" castleId="7" zoneId="11032" />
<priceConfig id="14" name="Rune Town" baseTax="20" castleId="8" zoneId="11033" />
<priceConfig id="15" name="Heine Town" baseTax="20" castleId="6" zoneId="11034" />
<priceConfig id="16" name="Schuttgart Town" baseTax="20" castleId="9" zoneId="11035" />
<priceConfig id="17" name="Floran Village" baseTax="50" castleId="2" zoneId="11036" />
<priceConfig id="18" name="Neutral Territory" baseTax="50" />
<priceConfig id="19" name="Gludio Castle" baseTax="10" castleId="1" zoneId="11200" />
<priceConfig id="20" name="Dion Castle" baseTax="10" castleId="2" zoneId="11201" />
<priceConfig id="21" name="Giran Castle" baseTax="10" castleId="3" zoneId="11202" />
<priceConfig id="22" name="Oren Castle" baseTax="10" castleId="4" zoneId="11203" />
<priceConfig id="23" name="Aden Castle" baseTax="10" castleId="5" zoneId="11204" />
<priceConfig id="24" name="Innadril Castle" baseTax="10" castleId="6" zoneId="11205" />
<priceConfig id="25" name="Goddard Castle" baseTax="10" castleId="7" zoneId="11206" />
<priceConfig id="26" name="Rune Castle" baseTax="10" castleId="8" zoneId="11207" />
<priceConfig id="27" name="Schuttgart Castle" baseTax="10" castleId="9" zoneId="11208" />
</merchantPriceConfig>

View File

@ -97,7 +97,6 @@ import com.l2jmobius.gameserver.datatables.AugmentationData;
import com.l2jmobius.gameserver.datatables.BotReportTable;
import com.l2jmobius.gameserver.datatables.EventDroplist;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
import com.l2jmobius.gameserver.geodata.GeoData;
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
import com.l2jmobius.gameserver.handler.ConditionHandler;
@ -231,7 +230,6 @@ public class GameServer
OptionData.getInstance();
EnsoulData.getInstance();
EnchantItemHPBonusData.getInstance();
MerchantPriceConfigTable.getInstance().loadInstances();
BuyListData.getInstance();
MultisellData.getInstance();
RecipeData.getInstance();
@ -363,7 +361,6 @@ public class GameServer
FortSiegeManager.getInstance();
SiegeScheduleData.getInstance();
MerchantPriceConfigTable.getInstance().updateReferences();
CastleManorManager.getInstance();
SiegeGuardManager.getInstance();
QuestManager.getInstance().report();

View File

@ -1,291 +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.datatables;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.InstanceListManager;
import com.l2jmobius.gameserver.enums.TaxType;
import com.l2jmobius.gameserver.instancemanager.CastleManager;
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
import com.l2jmobius.gameserver.model.actor.instance.L2MerchantInstance;
import com.l2jmobius.gameserver.model.entity.Castle;
/**
* @author KenM
*/
public class MerchantPriceConfigTable implements InstanceListManager
{
// Zoey76: TODO: Implement using IGameXmlReader.
private static Logger LOGGER = Logger.getLogger(MerchantPriceConfigTable.class.getName());
public static MerchantPriceConfigTable getInstance()
{
return SingletonHolder._instance;
}
private static final String MPCS_FILE = "MerchantPriceConfig.xml";
private final Map<Integer, MerchantPriceConfig> _mpcs = new HashMap<>();
private MerchantPriceConfig _defaultMpc;
public MerchantPriceConfig getMerchantPriceConfig(L2MerchantInstance npc)
{
for (MerchantPriceConfig mpc : _mpcs.values())
{
if (ZoneManager.getInstance().getRegion(npc).getZones().containsKey(mpc.getZoneId()))
{
return mpc;
}
}
return _defaultMpc;
}
public MerchantPriceConfig getMerchantPriceConfig(int id)
{
return _mpcs.get(id);
}
public void loadXML() throws SAXException, IOException, ParserConfigurationException
{
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setIgnoringComments(true);
final File file = new File(Config.DATAPACK_ROOT + "/data/" + MPCS_FILE);
if (file.exists())
{
int defaultPriceConfigId;
final Document doc = factory.newDocumentBuilder().parse(file);
Node n = doc.getDocumentElement();
final Node dpcNode = n.getAttributes().getNamedItem("defaultPriceConfig");
if (dpcNode == null)
{
throw new IllegalStateException("merchantPriceConfig must define an 'defaultPriceConfig'");
}
defaultPriceConfigId = Integer.parseInt(dpcNode.getNodeValue());
MerchantPriceConfig mpc;
for (n = n.getFirstChild(); n != null; n = n.getNextSibling())
{
mpc = parseMerchantPriceConfig(n);
if (mpc != null)
{
_mpcs.put(mpc.getId(), mpc);
}
}
final MerchantPriceConfig defaultMpc = getMerchantPriceConfig(defaultPriceConfigId);
if (defaultMpc == null)
{
throw new IllegalStateException("'defaultPriceConfig' points to an non-loaded priceConfig");
}
_defaultMpc = defaultMpc;
}
}
private MerchantPriceConfig parseMerchantPriceConfig(Node n)
{
if (n.getNodeName().equals("priceConfig"))
{
final int id;
final int baseTax;
int castleId = -1;
int zoneId = -1;
final String name;
Node node = n.getAttributes().getNamedItem("id");
if (node == null)
{
throw new IllegalStateException("Must define the priceConfig 'id'");
}
id = Integer.parseInt(node.getNodeValue());
node = n.getAttributes().getNamedItem("name");
if (node == null)
{
throw new IllegalStateException("Must define the priceConfig 'name'");
}
name = node.getNodeValue();
node = n.getAttributes().getNamedItem("baseTax");
if (node == null)
{
throw new IllegalStateException("Must define the priceConfig 'baseTax'");
}
baseTax = Integer.parseInt(node.getNodeValue());
node = n.getAttributes().getNamedItem("castleId");
if (node != null)
{
castleId = Integer.parseInt(node.getNodeValue());
}
node = n.getAttributes().getNamedItem("zoneId");
if (node != null)
{
zoneId = Integer.parseInt(node.getNodeValue());
}
return new MerchantPriceConfig(id, name, baseTax, castleId, zoneId);
}
return null;
}
@Override
public void loadInstances()
{
try
{
loadXML();
LOGGER.info("Loaded " + _mpcs.size() + " merchant price configs.");
}
catch (Exception e)
{
LOGGER.severe("Failed loading MerchantPriceConfigTable: " + e);
}
}
@Override
public void updateReferences()
{
for (MerchantPriceConfig mpc : _mpcs.values())
{
mpc.updateReferences();
}
}
@Override
public void activateInstances()
{
}
/**
* @author KenM
*/
public static final class MerchantPriceConfig
{
private final int _id;
private final String _name;
private final int _baseTax;
private final int _castleId;
private Castle _castle;
private final int _zoneId;
public MerchantPriceConfig(int id, String name, int baseTax, int castleId, int zoneId)
{
_id = id;
_name = name;
_baseTax = baseTax;
_castleId = castleId;
_zoneId = zoneId;
}
/**
* @return Returns the id.
*/
public int getId()
{
return _id;
}
/**
* @return Returns the name.
*/
public String getName()
{
return _name;
}
/**
* @return Returns the baseTax.
*/
public int getBaseTax()
{
return _baseTax;
}
/**
* @return Returns the baseTax / 100.0.
*/
public double getBaseTaxRate()
{
return _baseTax / 100.0;
}
/**
* @return Returns the castle.
*/
public Castle getCastle()
{
return _castle;
}
/**
* @return Returns the zoneId.
*/
public int getZoneId()
{
return _zoneId;
}
public boolean hasCastle()
{
return getCastle() != null;
}
public double getCastleTaxRate()
{
return hasCastle() ? getCastle().getTaxRate() : 0.0;
}
public int getTotalTax(TaxType taxType)
{
return hasCastle() ? (getCastle().getTaxPercent(taxType) + getBaseTax()) : getBaseTax();
}
public double getTotalTaxRate(TaxType taxType)
{
return getTotalTax(taxType) / 100.0;
}
public void updateReferences()
{
if (_castleId > 0)
{
_castle = CastleManager.getInstance().getCastleById(_castleId);
}
}
}
private static class SingletonHolder
{
protected static final MerchantPriceConfigTable _instance = new MerchantPriceConfigTable();
}
}

View File

@ -17,8 +17,6 @@
package com.l2jmobius.gameserver.model.actor.instance;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable.MerchantPriceConfig;
import com.l2jmobius.gameserver.enums.InstanceType;
import com.l2jmobius.gameserver.enums.TaxType;
import com.l2jmobius.gameserver.model.actor.L2Character;
@ -34,8 +32,6 @@ import com.l2jmobius.gameserver.network.serverpackets.ExBuySellList;
*/
public class L2MerchantInstance extends L2NpcInstance
{
private MerchantPriceConfig _mpc;
public L2MerchantInstance(L2NpcTemplate template)
{
super(template);
@ -53,13 +49,6 @@ public class L2MerchantInstance extends L2NpcInstance
return super.isAutoAttackable(attacker);
}
@Override
public void onSpawn()
{
super.onSpawn();
_mpc = MerchantPriceConfigTable.getInstance().getMerchantPriceConfig(this);
}
@Override
public String getHtmlPath(int npcId, int val)
{
@ -77,14 +66,6 @@ public class L2MerchantInstance extends L2NpcInstance
return "data/html/merchant/" + pom + ".htm";
}
/**
* @return Returns the mpc.
*/
public MerchantPriceConfig getMpc()
{
return _mpc;
}
public final void showBuyWindow(L2PcInstance player, int val)
{
showBuyWindow(player, val, true);
@ -107,13 +88,30 @@ public class L2MerchantInstance extends L2NpcInstance
return;
}
final double buyTaxRate = (applyTax) ? getMpc().getTotalTaxRate(TaxType.BUY) : 0;
final double sellTaxRate = (applyTax) ? getMpc().getTotalTaxRate(TaxType.SELL) : 0;
player.setInventoryBlockingStatus(true);
player.sendPacket(new BuyList(buyList, player.getAdena(), buyTaxRate));
player.sendPacket(new ExBuySellList(player, false, sellTaxRate));
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 double getCastleTaxRate()
{
return hasCastle() ? getCastle().getTaxRate() : 0.0;
}
public int getTotalTax(TaxType taxType)
{
return hasCastle() ? getCastle().getTaxPercent(taxType) : 0;
}
public double getTotalTaxRate(TaxType taxType)
{
return getTotalTax(taxType) / 100.0;
}
}

View File

@ -114,7 +114,6 @@ public final class RequestBuyItem implements IClientIncomingPacket
}
double castleTaxRate = 0;
double baseTaxRate = 0;
if ((merchant == null) && !player.isGM() && (_listId != CUSTOM_CB_SELL_LIST))
{
@ -137,15 +136,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
return;
}
if (merchant instanceof L2MerchantInstance)
{
castleTaxRate = ((L2MerchantInstance) merchant).getMpc().getCastleTaxRate();
baseTaxRate = ((L2MerchantInstance) merchant).getMpc().getBaseTaxRate();
}
else
{
baseTaxRate = 0.5;
}
castleTaxRate = ((L2MerchantInstance) merchant).getCastleTaxRate();
}
long subTotal = 0;
@ -207,7 +198,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
return;
}
// first calculate price per item with tax, then multiply by count
price = (long) (price * (1 + castleTaxRate + baseTaxRate));
price = (long) (price * (1 + castleTaxRate));
subTotal += i.getCount() * price;
if (subTotal > MAX_ADENA)
{

View File

@ -175,7 +175,7 @@ public final class RequestSellItem implements IClientIncomingPacket
if (merchant instanceof L2MerchantInstance)
{
final L2MerchantInstance npc = ((L2MerchantInstance) merchant);
final long taxCollection = (long) (totalPrice * npc.getMpc().getTotalTaxRate(TaxType.SELL));
final long taxCollection = (long) (totalPrice * (1.0 - npc.getTotalTaxRate(TaxType.SELL)));
npc.getCastle().addToTreasury(taxCollection);
totalPrice -= taxCollection;
}

View File

@ -79,7 +79,7 @@ public class SellList implements IClientOutgoingPacket
int price = item.getItem().getReferencePrice() / 2;
if (_lease != null)
{
price -= (price * _lease.getMpc().getTotalTaxRate(TaxType.SELL));
price -= (price * _lease.getTotalTaxRate(TaxType.SELL));
}
packet.writeH(item.getItem().getType1());

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Documentation: -->
<!-- defaultPriceConfig -> ID of one of the price configs defined to be used when NPC has no price config. Can be ANY of the defined priceConfigs. Cannot be ommited, althrough you can emulate this by creating a dummy priceConfig. -->
<!-- id -> Defines the ID for relational references. -->
<!-- name -> Name of the area, for human-friendlyness and debugging, cannot be ommited. -->
<!-- baseTax -> Used on merchant item price calculation (see formula in the end), cannot be ommited. -->
<!-- castleId -> ID of the castle that controls merchants of this config, castle tax will apply to merchants price. Can be ommited (causes it to assume that no castle controls this config). -->
<!-- zoneId -> Attaches a given Town Zone to this priceConfig for convenience. -->
<!-- Merchant NPCs that dont explicit define an priceConfig will check if they are inside of the zone of an priceConfig, if yes that priceConfig is used for that npc. Can be ommited, then no NPC will be added based on zone (ie priceConfig direct assigned to NPCs through config or when used as the default priceConfig). -->
<!-- Merchant Price Formula price = baseItemPrice * (1 + baseTax/100 + castleTax/100) -->
<merchantPriceConfig defaultPriceConfig="18" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/MerchantPriceConfig.xsd">
<priceConfig id="0" name="Giran Town" baseTax="10" castleId="3" zoneId="11020" />
<priceConfig id="1" name="DE Village" baseTax="15" castleId="4" zoneId="11021" />
<priceConfig id="2" name="Talking Island" baseTax="15" castleId="1" zoneId="11022" />
<priceConfig id="3" name="Elven Village" baseTax="15" castleId="4" zoneId="11023" />
<priceConfig id="4" name="Orc Village" baseTax="15" castleId="9" zoneId="11024" />
<priceConfig id="5" name="Gludin Village" baseTax="20" castleId="1" zoneId="11025" />
<priceConfig id="6" name="Dwarven Village" baseTax="15" castleId="9" zoneId="11026" />
<priceConfig id="7" name="Kamael Village" baseTax="15" castleId="5" zoneId="11038" />
<priceConfig id="8" name="Gludio Town" baseTax="20" castleId="1" zoneId="11027" />
<priceConfig id="9" name="Dion Town" baseTax="20" castleId="2" zoneId="11028" />
<priceConfig id="10" name="Oren Town" baseTax="15" castleId="4" zoneId="11029" />
<priceConfig id="11" name="Hunters Village" baseTax="30" castleId="5" zoneId="11030" />
<priceConfig id="12" name="Aden Town" baseTax="20" castleId="5" zoneId="11031" />
<priceConfig id="13" name="Goddard Town" baseTax="20" castleId="7" zoneId="11032" />
<priceConfig id="14" name="Rune Town" baseTax="20" castleId="8" zoneId="11033" />
<priceConfig id="15" name="Heine Town" baseTax="20" castleId="6" zoneId="11034" />
<priceConfig id="16" name="Schuttgart Town" baseTax="20" castleId="9" zoneId="11035" />
<priceConfig id="17" name="Floran Village" baseTax="50" castleId="2" zoneId="11036" />
<priceConfig id="18" name="Neutral Territory" baseTax="50" />
<priceConfig id="19" name="Gludio Castle" baseTax="10" castleId="1" zoneId="11200" />
<priceConfig id="20" name="Dion Castle" baseTax="10" castleId="2" zoneId="11201" />
<priceConfig id="21" name="Giran Castle" baseTax="10" castleId="3" zoneId="11202" />
<priceConfig id="22" name="Oren Castle" baseTax="10" castleId="4" zoneId="11203" />
<priceConfig id="23" name="Aden Castle" baseTax="10" castleId="5" zoneId="11204" />
<priceConfig id="24" name="Innadril Castle" baseTax="10" castleId="6" zoneId="11205" />
<priceConfig id="25" name="Goddard Castle" baseTax="10" castleId="7" zoneId="11206" />
<priceConfig id="26" name="Rune Castle" baseTax="10" castleId="8" zoneId="11207" />
<priceConfig id="27" name="Schuttgart Castle" baseTax="10" castleId="9" zoneId="11208" />
</merchantPriceConfig>

View File

@ -97,7 +97,6 @@ import com.l2jmobius.gameserver.datatables.AugmentationData;
import com.l2jmobius.gameserver.datatables.BotReportTable;
import com.l2jmobius.gameserver.datatables.EventDroplist;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
import com.l2jmobius.gameserver.geodata.GeoData;
import com.l2jmobius.gameserver.geodata.pathfinding.PathFinding;
import com.l2jmobius.gameserver.handler.ConditionHandler;
@ -231,7 +230,6 @@ public class GameServer
OptionData.getInstance();
EnsoulData.getInstance();
EnchantItemHPBonusData.getInstance();
MerchantPriceConfigTable.getInstance().loadInstances();
BuyListData.getInstance();
MultisellData.getInstance();
RecipeData.getInstance();
@ -363,7 +361,6 @@ public class GameServer
FortSiegeManager.getInstance();
SiegeScheduleData.getInstance();
MerchantPriceConfigTable.getInstance().updateReferences();
CastleManorManager.getInstance();
SiegeGuardManager.getInstance();
QuestManager.getInstance().report();

View File

@ -1,291 +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.datatables;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.InstanceListManager;
import com.l2jmobius.gameserver.enums.TaxType;
import com.l2jmobius.gameserver.instancemanager.CastleManager;
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
import com.l2jmobius.gameserver.model.actor.instance.L2MerchantInstance;
import com.l2jmobius.gameserver.model.entity.Castle;
/**
* @author KenM
*/
public class MerchantPriceConfigTable implements InstanceListManager
{
// Zoey76: TODO: Implement using IGameXmlReader.
private static Logger LOGGER = Logger.getLogger(MerchantPriceConfigTable.class.getName());
public static MerchantPriceConfigTable getInstance()
{
return SingletonHolder._instance;
}
private static final String MPCS_FILE = "MerchantPriceConfig.xml";
private final Map<Integer, MerchantPriceConfig> _mpcs = new HashMap<>();
private MerchantPriceConfig _defaultMpc;
public MerchantPriceConfig getMerchantPriceConfig(L2MerchantInstance npc)
{
for (MerchantPriceConfig mpc : _mpcs.values())
{
if (ZoneManager.getInstance().getRegion(npc).getZones().containsKey(mpc.getZoneId()))
{
return mpc;
}
}
return _defaultMpc;
}
public MerchantPriceConfig getMerchantPriceConfig(int id)
{
return _mpcs.get(id);
}
public void loadXML() throws SAXException, IOException, ParserConfigurationException
{
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setIgnoringComments(true);
final File file = new File(Config.DATAPACK_ROOT + "/data/" + MPCS_FILE);
if (file.exists())
{
int defaultPriceConfigId;
final Document doc = factory.newDocumentBuilder().parse(file);
Node n = doc.getDocumentElement();
final Node dpcNode = n.getAttributes().getNamedItem("defaultPriceConfig");
if (dpcNode == null)
{
throw new IllegalStateException("merchantPriceConfig must define an 'defaultPriceConfig'");
}
defaultPriceConfigId = Integer.parseInt(dpcNode.getNodeValue());
MerchantPriceConfig mpc;
for (n = n.getFirstChild(); n != null; n = n.getNextSibling())
{
mpc = parseMerchantPriceConfig(n);
if (mpc != null)
{
_mpcs.put(mpc.getId(), mpc);
}
}
final MerchantPriceConfig defaultMpc = getMerchantPriceConfig(defaultPriceConfigId);
if (defaultMpc == null)
{
throw new IllegalStateException("'defaultPriceConfig' points to an non-loaded priceConfig");
}
_defaultMpc = defaultMpc;
}
}
private MerchantPriceConfig parseMerchantPriceConfig(Node n)
{
if (n.getNodeName().equals("priceConfig"))
{
final int id;
final int baseTax;
int castleId = -1;
int zoneId = -1;
final String name;
Node node = n.getAttributes().getNamedItem("id");
if (node == null)
{
throw new IllegalStateException("Must define the priceConfig 'id'");
}
id = Integer.parseInt(node.getNodeValue());
node = n.getAttributes().getNamedItem("name");
if (node == null)
{
throw new IllegalStateException("Must define the priceConfig 'name'");
}
name = node.getNodeValue();
node = n.getAttributes().getNamedItem("baseTax");
if (node == null)
{
throw new IllegalStateException("Must define the priceConfig 'baseTax'");
}
baseTax = Integer.parseInt(node.getNodeValue());
node = n.getAttributes().getNamedItem("castleId");
if (node != null)
{
castleId = Integer.parseInt(node.getNodeValue());
}
node = n.getAttributes().getNamedItem("zoneId");
if (node != null)
{
zoneId = Integer.parseInt(node.getNodeValue());
}
return new MerchantPriceConfig(id, name, baseTax, castleId, zoneId);
}
return null;
}
@Override
public void loadInstances()
{
try
{
loadXML();
LOGGER.info("Loaded " + _mpcs.size() + " merchant price configs.");
}
catch (Exception e)
{
LOGGER.severe("Failed loading MerchantPriceConfigTable: " + e);
}
}
@Override
public void updateReferences()
{
for (MerchantPriceConfig mpc : _mpcs.values())
{
mpc.updateReferences();
}
}
@Override
public void activateInstances()
{
}
/**
* @author KenM
*/
public static final class MerchantPriceConfig
{
private final int _id;
private final String _name;
private final int _baseTax;
private final int _castleId;
private Castle _castle;
private final int _zoneId;
public MerchantPriceConfig(int id, String name, int baseTax, int castleId, int zoneId)
{
_id = id;
_name = name;
_baseTax = baseTax;
_castleId = castleId;
_zoneId = zoneId;
}
/**
* @return Returns the id.
*/
public int getId()
{
return _id;
}
/**
* @return Returns the name.
*/
public String getName()
{
return _name;
}
/**
* @return Returns the baseTax.
*/
public int getBaseTax()
{
return _baseTax;
}
/**
* @return Returns the baseTax / 100.0.
*/
public double getBaseTaxRate()
{
return _baseTax / 100.0;
}
/**
* @return Returns the castle.
*/
public Castle getCastle()
{
return _castle;
}
/**
* @return Returns the zoneId.
*/
public int getZoneId()
{
return _zoneId;
}
public boolean hasCastle()
{
return getCastle() != null;
}
public double getCastleTaxRate()
{
return hasCastle() ? getCastle().getTaxRate() : 0.0;
}
public int getTotalTax(TaxType taxType)
{
return hasCastle() ? (getCastle().getTaxPercent(taxType) + getBaseTax()) : getBaseTax();
}
public double getTotalTaxRate(TaxType taxType)
{
return getTotalTax(taxType) / 100.0;
}
public void updateReferences()
{
if (_castleId > 0)
{
_castle = CastleManager.getInstance().getCastleById(_castleId);
}
}
}
private static class SingletonHolder
{
protected static final MerchantPriceConfigTable _instance = new MerchantPriceConfigTable();
}
}

View File

@ -17,8 +17,6 @@
package com.l2jmobius.gameserver.model.actor.instance;
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable.MerchantPriceConfig;
import com.l2jmobius.gameserver.enums.InstanceType;
import com.l2jmobius.gameserver.enums.TaxType;
import com.l2jmobius.gameserver.model.actor.L2Character;
@ -34,8 +32,6 @@ import com.l2jmobius.gameserver.network.serverpackets.ExBuySellList;
*/
public class L2MerchantInstance extends L2NpcInstance
{
private MerchantPriceConfig _mpc;
public L2MerchantInstance(L2NpcTemplate template)
{
super(template);
@ -53,13 +49,6 @@ public class L2MerchantInstance extends L2NpcInstance
return super.isAutoAttackable(attacker);
}
@Override
public void onSpawn()
{
super.onSpawn();
_mpc = MerchantPriceConfigTable.getInstance().getMerchantPriceConfig(this);
}
@Override
public String getHtmlPath(int npcId, int val)
{
@ -77,14 +66,6 @@ public class L2MerchantInstance extends L2NpcInstance
return "data/html/merchant/" + pom + ".htm";
}
/**
* @return Returns the mpc.
*/
public MerchantPriceConfig getMpc()
{
return _mpc;
}
public final void showBuyWindow(L2PcInstance player, int val)
{
showBuyWindow(player, val, true);
@ -107,13 +88,30 @@ public class L2MerchantInstance extends L2NpcInstance
return;
}
final double buyTaxRate = (applyTax) ? getMpc().getTotalTaxRate(TaxType.BUY) : 0;
final double sellTaxRate = (applyTax) ? getMpc().getTotalTaxRate(TaxType.SELL) : 0;
player.setInventoryBlockingStatus(true);
player.sendPacket(new BuyList(buyList, player.getAdena(), buyTaxRate));
player.sendPacket(new ExBuySellList(player, false, sellTaxRate));
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 double getCastleTaxRate()
{
return hasCastle() ? getCastle().getTaxRate() : 0.0;
}
public int getTotalTax(TaxType taxType)
{
return hasCastle() ? getCastle().getTaxPercent(taxType) : 0;
}
public double getTotalTaxRate(TaxType taxType)
{
return getTotalTax(taxType) / 100.0;
}
}

View File

@ -114,7 +114,6 @@ public final class RequestBuyItem implements IClientIncomingPacket
}
double castleTaxRate = 0;
double baseTaxRate = 0;
if ((merchant == null) && !player.isGM() && (_listId != CUSTOM_CB_SELL_LIST))
{
@ -137,15 +136,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
return;
}
if (merchant instanceof L2MerchantInstance)
{
castleTaxRate = ((L2MerchantInstance) merchant).getMpc().getCastleTaxRate();
baseTaxRate = ((L2MerchantInstance) merchant).getMpc().getBaseTaxRate();
}
else
{
baseTaxRate = 0.5;
}
castleTaxRate = ((L2MerchantInstance) merchant).getCastleTaxRate();
}
long subTotal = 0;
@ -207,7 +198,7 @@ public final class RequestBuyItem implements IClientIncomingPacket
return;
}
// first calculate price per item with tax, then multiply by count
price = (long) (price * (1 + castleTaxRate + baseTaxRate));
price = (long) (price * (1 + castleTaxRate));
subTotal += i.getCount() * price;
if (subTotal > MAX_ADENA)
{

View File

@ -175,7 +175,7 @@ public final class RequestSellItem implements IClientIncomingPacket
if (merchant instanceof L2MerchantInstance)
{
final L2MerchantInstance npc = ((L2MerchantInstance) merchant);
final long taxCollection = (long) (totalPrice * npc.getMpc().getTotalTaxRate(TaxType.SELL));
final long taxCollection = (long) (totalPrice * (1.0 - npc.getTotalTaxRate(TaxType.SELL)));
npc.getCastle().addToTreasury(taxCollection);
totalPrice -= taxCollection;
}

View File

@ -79,7 +79,7 @@ public class SellList implements IClientOutgoingPacket
int price = item.getItem().getReferencePrice() / 2;
if (_lease != null)
{
price -= (price * _lease.getMpc().getTotalTaxRate(TaxType.SELL));
price -= (price * _lease.getTotalTaxRate(TaxType.SELL));
}
packet.writeH(item.getItem().getType1());