Noticias:

Debes de estar registrado para poder ver el contenido indicado. Registrate o Conectate

Menú Principal

Market Npc

Iniciado por Swarlog, Ago 19, 2022, 01:05 AM

Tema anterior - Siguiente tema

Swarlog

En model.actor.instance y crear nueva clase con el nombre "L2MarketNpcInstance"

package net.sf.l2j.gameserver.model.actor.instance;
 
import Market.Bid;
import Market.Market;
import Market.MarketTaxType;
 
import net.sf.l2j.gameserver.ai.CtrlIntention;
import net.sf.l2j.gameserver.model.L2ItemInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
import net.sf.l2j.gameserver.network.serverpackets.MyTargetSelected;
import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
import net.sf.l2j.gameserver.network.serverpackets.PledgeCrest;
import net.sf.l2j.gameserver.network.serverpackets.ValidateLocation;
import net.sf.l2j.gameserver.templates.chars.L2NpcTemplate;
import net.sf.l2j.gameserver.templates.item.L2Armor;
import net.sf.l2j.gameserver.templates.item.L2EtcItem;
import net.sf.l2j.gameserver.templates.item.L2Item;
import net.sf.l2j.gameserver.templates.item.L2Weapon;
 
import java.util.StringTokenizer;
import java.io.File;
import java.util.ArrayList;
 
 
@SuppressWarnings("unused")
public class L2MarketNpcInstance extends L2NpcInstance
{
 
/**
* @author Elfocrash
*/
 
public static final String HTML_FOLDER = "data/html/market/";
public static final String INDEX_PAGE = HTML_FOLDER + "Market.htm";
public static final String MAIN_PAGE = HTML_FOLDER + "MarketMain.htm";
public static final String BID_INFO_PAGE = HTML_FOLDER + "MarketBidInfo.htm";
public static final String ADD_PAGE = HTML_FOLDER + "MarketAdd.htm";
public static final String CAB_PAGE = HTML_FOLDER + "MarketCabinet.htm";
 
public L2MarketNpcInstance(int objectId, L2NpcTemplate template) {
super(objectId, template);
}
 
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
StringTokenizer st = new StringTokenizer(command, " ");
String curCommand = st.nextToken();
NpcHtmlMessage html;
if(curCommand.startsWith("marketpage"))
{
String type = st.nextToken();
if(type.startsWith("index"))
{
html = new NpcHtmlMessage(1);
html.setFile(INDEX_PAGE);
html.replace("%totalbids%", String.valueOf(Market.getInstance().getBidsCount()));
sendHtmlMessage(player, html);
}
else if(type.startsWith("main"))
{
int page = Integer.parseInt(st.nextToken());
html = new NpcHtmlMessage(1);
html.setFile(MAIN_PAGE);
html.replace("%CONTENT%", getMarketPage(page));
sendHtmlMessage(player, html);
}
else if(type.startsWith("add"))
{
html = genAddPage(player);
sendHtmlMessage(player,html);
}
else if(type.startsWith("info"))
{
html = genBidInfoPage(player, Integer.parseInt(st.nextToken()));
sendHtmlMessage(player, html);
}
else if(type.startsWith("cab"))
{
html = genCabPage(player);
sendHtmlMessage(player, html);
}
}
else if(curCommand.startsWith("marketadd"))
{
int costItemCount = Integer.parseInt(st.nextToken());
int costItemId = Market.getInstance().getShortItemId(st.nextToken());
String tax = st.nextToken();
int itemObjId = Integer.parseInt(st.nextToken());
Market.getInstance().addLot(player.getObjectId(), itemObjId, costItemId, costItemCount, tax);
}
else if(curCommand.startsWith("marketdel"))
{
Market.getInstance().deleteLot(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()));
}
else if(curCommand.startsWith("marketbuy"))
{
Market.getInstance().buyLot(player.getObjectId(), Integer.parseInt(st.nextToken()));
}
}
 
@Override
public void onAction(L2PcInstance player)
{
 
if(this != player.getTarget())
{
player.setTarget(this);
MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
player.sendPacket(my);
player.sendPacket(new ValidateLocation(this));
}
else
{
if(!canInteract(player))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
}
else
{
       
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(INDEX_PAGE);
html.replace("%totalbids%", String.valueOf(Market.getInstance().getBidsCount()));
sendHtmlMessage(player, html);
}
}
player.sendPacket(ActionFailed.STATIC_PACKET);
}
 
private String getMarketPage(int page)
{
 
ArrayList<Bid> items = Market.getInstance().getAllBids();
StringBuilder sb = new StringBuilder();
int numlines = page * Market.LOTS_PER_PAGE + Market.LOTS_PER_PAGE;
if(items.size() != 0)
{
sb.append("<table width=\"300\">");
for(int i = page * Market.LOTS_PER_PAGE;i < numlines;i++)
{
if(items.size() - i <= 0)
break;
sb.append(BidItem(items.get(i)));
sb.append("<tr><td><font color=\"808080\">Type: " + getItemType(items.get(i).getBidItem().getItem()) + ". Seller: " + items.get(i).getBidder().getName() + "</font></td></tr>");
}
sb.append("</table>");
sb.append("<br>Page:&nbsp;");
int pg = getMarketPagesCount();
for(int i = 0;i < pg;i++)
{
sb.append("<a action=\"bypass -h npc_%objectId%_marketpage main "+i+"\">"+i+ "</a>&nbsp;");
}
}
else
{
sb.append("No item is on the market!");
}
 
return sb.toString();
}
 
private static String getAddItemsList(L2PcInstance player)
{
StringBuilder tx = new StringBuilder();
ArrayList<L2ItemInstance> charItems = new ArrayList<L2ItemInstance>();
for(L2ItemInstance item : player.getInventory().getItems())
{
if(Market.getInstance().checkItemForMarket(item))
charItems.add(item);
}
for(int i = 0;i < charItems.size();i++)
{
if(isAlreadyAdded(player, charItems.get(i)))
continue;
tx.append("<a action=\"bypass -h npc_%objectId%_marketadd $count $value $tax "+charItems.get(i).getObjectId()+"\">"+charItems.get(i).getItemName() + " +" + charItems.get(i).getEnchantLevel() + "</a><br>");
}
return tx.toString();
}
 
private static NpcHtmlMessage genBidInfoPage(L2PcInstance player, int bidId)
{
       
Bid bid = Market.getInstance().getBidById(bidId);
String priceName = Market.getInstance().getShortItemName(bid.getCostItemId());
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(BID_INFO_PAGE);
html.replace("%itemtitle%", bid.getBidItem().getItemName());
html.replace("%itemname%", bid.getBidItem().getItemName() + " (" + getItemGrade(bid.getBidItem().getItem()) + " Grade)");
html.replace("%itemtype%", getItemType(bid.getBidItem().getItem()));
html.replace("%itemaugmentation%", bid.getBidItem().isAugmented() ? "Yes" : "No");
html.replace("%enchantlevel%", String.valueOf(bid.getBidItem().getEnchantLevel()));
html.replace("%itemprice%", bid.getCostItemCount() + " <font color=\"LEVEL\">" + priceName + "</font>");
if(bid.getTaxType() == MarketTaxType.BUYER)
{
double mtax = bid.getCostItemCount() * Market.MARKET_TAX;
html.replace("%markettax%", (int)mtax + " <font color=\"LEVEL\">" + priceName + "</font> (Full price: " + (bid.getCostItemCount() + (int)mtax) + " <font color\"LEVEL\">" + priceName + "</font>)");
}
else
{
html.replace("%markettax%", "Paid by the seller");
}
html.replace("%seller%", bid.getBidder().getName());
if(player.getObjectId() == bid.getBidder().getObjectId())
{
html.replace("%LINKS%", "<a action=\"bypass -h npc_%objectId%_marketdel " + player.getObjectId() + " " + bid.getBidId() + "\">Remove from the market</a>");
}
else
{
html.replace("%LINKS%", "<a action=\"bypass -h npc_%objectId%_marketbuy " + bid.getBidId() + "\">Purchase</a>");
}
return html;
}
 
private static NpcHtmlMessage genAddPage(L2PcInstance player)
{
       
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(ADD_PAGE);
html.replace("%values%", Market.getInstance().getPriceList());
html.replace("%charitems%", getAddItemsList(player));
html.replace("%taxprocent%", ""+((int)(Market.MARKET_TAX * 100)));
 
return html;
}
 
private static NpcHtmlMessage genCabPage(L2PcInstance player)
{
       
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile(CAB_PAGE);
html.replace("%charname%", player.getName());
 
StringBuilder tx = new StringBuilder();
ArrayList<Bid> bids = Market.getInstance().getLots().get(player.getObjectId());
if(bids != null)
{
for(Bid bid: bids)
{
tx.append(bid.getBidItem().getItemName() + " +" + bid.getBidItem().getEnchantLevel() + "&nbsp;<a action=\"bypass -h npc_%objectId%_marketpage info " + bid.getBidId() + "\">Info</a>&nbsp;<a action=\"bypass -h npc_%objectId%_marketdel " + player.getObjectId() + " " + bid.getBidId() + "\">Remove from the market</a><br>");
}
}
else
{
tx.append("You have no items on the market.");
}
html.replace("%charitems%", tx.toString());
return html;
}
 
private static String BidItem(Bid bid)
{
       
String info = "";
info += "<tr><td><a action=\"bypass -h npc_%objectId%_marketpage info " + bid.getBidId() + "\">" + bid.getBidItem().getName() + "</a>&nbsp;" + "(" + getItemGrade(bid.getBidItem().getItem()) + ")&nbsp;+" +  bid.getBidItem().getEnchantLevel() +  "</td></tr>";
info += "<tr><td><font color=\"808080\">Price: " + bid.getCostItemCount()  + " " + Market.getInstance().getShortItemName(bid.getCostItemId()) + "</font></td></tr>";
return info;
}
 
public int getMarketPagesCount()
{
int pages = 0;
for(int allbids = Market.getInstance().getBidsCount();allbids > 0;allbids -= Market.LOTS_PER_PAGE)
{
pages++;
}
return pages;
}
 
private void sendHtmlMessage(L2PcInstance player, NpcHtmlMessage html)
{
       
html.replace("%backlink%", "<a action=\"bypass -h npc_%objectId%_marketpage index\">Back</a>");
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcId%", String.valueOf(getNpcId()));
player.sendPacket(html);
}
 
private static boolean isAlreadyAdded(L2PcInstance player, L2ItemInstance item)
{
ArrayList<Bid> bids = Market.getInstance().getAllBids();
for(Bid bid: bids)
{
if(bid.getBidItem().getObjectId() == item.getObjectId())
return true;
}
return false;
}
private static String getItemType(L2Item item)
{
if(item instanceof L2Weapon)
return "Weapon";
else if(item instanceof L2Armor)
return "Armor";
else if(item instanceof L2EtcItem)
return "Other";
return "";
}
private static String getItemGrade(L2Item item)
{
String grade = "";
switch(item.getCrystalType())
{
case L2Item.CRYSTAL_NONE:
grade = "None";
break;
case L2Item.CRYSTAL_D:
grade = "D";
break;
case L2Item.CRYSTAL_C:
grade = "C";
break;
case L2Item.CRYSTAL_B:
grade = "B";
break;
case L2Item.CRYSTAL_A:
grade = "A";
break;
case L2Item.CRYSTAL_S:
grade = "S";
break;
}
return "<font color=\"LEVEL\">" + grade + "</font>";
}
 
}

Ahora crear nuevo paquete con el nombre de Mercado crear una nueva clase con el nombre de la subasta

package Market;
 
import net.sf.l2j.gameserver.model.L2ItemInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
 
public class Bid {
 
/**
* @author Elfocrash
*/
 
private final L2PcInstance bidder;
 
private final L2ItemInstance bidItem;
 
private final int costItemId;
 
private final int costItemCount;
 
private final int bidId;
 
private final MarketTaxType taxType;
 
public Bid(L2PcInstance bidder, int bidId, L2ItemInstance bidItem, int costItemId, int costItemCount, MarketTaxType taxType)
{
this.bidder = bidder;
this.bidId = bidId;
this.bidItem = bidItem;
this.costItemId = costItemId;
this.costItemCount = costItemCount;
this.taxType = taxType;
}
 
public L2PcInstance getBidder()
{
return bidder;
}
 
public int getBidId()
{
return bidId;
}
 
public L2ItemInstance getBidItem()
{
return bidItem;
}
 
public int getCostItemId()
{
return costItemId;
}
 
public int getCostItemCount()
{
return costItemCount;
}
 
public MarketTaxType getTaxType()
{
return taxType;
}
 
}

Crear una nueva clase con el nombre Market

package Market;
 
import net.sf.l2j.gameserver.model.L2ItemInstance;
import net.sf.l2j.gameserver.model.L2World;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
import net.sf.l2j.gameserver.templates.item.L2EtcItem;
 
import java.util.ArrayList;
import java.util.HashMap;
 
import java.util.Collection;
import java.util.Map;
 
 
/**
 *
 * @author Elfocrash
 *
 */
public class Market
{
public static final int MAX_LOTS = 50;
public static final int MAX_CHAR_LOTS = 12;
public static final int LOTS_PER_PAGE = 10;
 
public static final int[] DISALLOWED_ITEMS_FOR_BID = { 5588, 7694  };
public static final double MARKET_TAX = 0.1;
 
public static final boolean SEND_MESSAGE_AFTER_TRADE = true;
public static final boolean ALLOW_AUGMENTATED_ITEMS = true;
public static final boolean ALLOW_ETC_ITEMS_FOR_SELL = false;
public static final boolean ALLOW_ENCHATED_ITEMS = true;
public static final String TRADE_MESSAGE_FORSELLER = "Your item %item% was successfully sold.";
public static final String TRADE_MESSAGE_FORBUYER = "You have successfully bought %item%.";
 
private int lotsCount = 0;
 
private static Map<Integer, ArrayList<Bid>> lots;
private static Map<String, Integer> prices;
 
 
private Market()
{
lots = new HashMap<>();
prices = new HashMap<>();
prices.put("Adena", 57);
prices.put("CoL", 4037);
}
 
public void addLot(int playerid, int itemObjId, int costItemId, int costItemCount, String tax)
{
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/market/MarketReturnResult.htm");
L2PcInstance player = L2World.getInstance().getPlayer(playerid);
L2ItemInstance item = player.getInventory().getItemByObjectId(itemObjId);
MarketTaxType taxType = null;
if (tax.equalsIgnoreCase("Seller"))
taxType = MarketTaxType.SELLER;
else if (tax.equalsIgnoreCase("Buyer"))
taxType = MarketTaxType.BUYER;
if (!checkItemForMarket(item))
{
html.replace("%text%", "Sorry, that an item cannot be sold here.");
player.sendPacket(html);
return;
}
if (!prices.containsValue(costItemId))
{
html.replace("%text%", "Sorry, this currency is not supported by the market.");
player.sendPacket(html);
return;
}
if ((getBidsCount() +1) > MAX_LOTS)
{
html.replace("%text%", "Sorry, the auction is full.");
player.sendPacket(html);
return;
}
if (lots.get(player.getObjectId()) != null && (lots.get(player.getObjectId()).size() +1 > MAX_CHAR_LOTS))
{
html.replace("%text%", "Sorry, you exceeded the max quantity of goods.");
player.sendPacket(html);
return;
}
if (taxType == MarketTaxType.SELLER && (player.getInventory().getItemByItemId(costItemId) != null && player.getInventory().getItemByItemId(costItemId).getCount() < (costItemCount * MARKET_TAX)))
{
html.replace("%text%", "Sorry, you do not have enough money to pay the tax market.");
player.sendPacket(html);
return;
}
Bid biditem = new Bid(player, lotsCount++, item, costItemId, costItemCount, taxType);
if (biditem.getTaxType() == MarketTaxType.SELLER)
player.destroyItemByItemId("Market tax", costItemId, (int)(costItemCount * MARKET_TAX), null, false);
if (lots.get(player.getObjectId()) != null)
lots.get(player.getObjectId()).add(biditem);
else
{
ArrayList<Bid> charBidItems = new ArrayList<>();
charBidItems.add(biditem);
lots.put(player.getObjectId(), charBidItems);
}
html.replace("%text%", "This product was successfully added to the market.");
player.sendPacket(html);
}
 
public void deleteLot(int charObjId, int bidId)
{
L2PcInstance player = L2World.getInstance().getPlayer(charObjId);
Bid bid = getBidById(bidId);
if (bid.getBidder().getObjectId() != player.getObjectId())
return;
if (!(lots.get(player.getObjectId()).contains(bid)))
return;
lots.get(player.getObjectId()).remove(bid);
sendResultHtml(player, "Your item was successfully removed from the market.");
}
 
public void buyLot(int buyerId, int bidId)
{
Bid bid = getBidById(bidId);
L2PcInstance seller = L2World.getInstance().getPlayer(bid.getBidder().getObjectId());
L2PcInstance buyer = L2World.getInstance().getPlayer(buyerId);
if (seller == null || buyer == null || buyer.getObjectId() == bid.getBidder().getObjectId())
{
lots.get(bid.getBidder().getObjectId()).clear();
return;
}
if (seller.getInventory().getItemByItemId(bid.getBidItem().getItemId()) == null)
{
if(lots.get(seller.getObjectId()) != null)
lots.get(seller.getObjectId()).remove(bid);
return;
}
if (buyer.getInventory().getItemByItemId(bid.getCostItemId()) == null || (bid.getTaxType() == MarketTaxType.BUYER && (buyer.getInventory().getItemByItemId(bid.getCostItemId()).getCount() < (bid.getCostItemCount() + (bid.getCostItemCount() * MARKET_TAX)))) ||
(bid.getTaxType() == MarketTaxType.SELLER && (buyer.getInventory().getItemByItemId(bid.getCostItemId()).getCount() < bid.getCostItemCount())))
{
sendResultHtml(buyer, "Sorry, you do not have enough money to pay for goods.");
return;
}
L2ItemInstance item = seller.getInventory().getItemByObjectId(bid.getBidItem().getObjectId());
if (item == null)
return;
 
double itemcount = (bid.getTaxType() == MarketTaxType.BUYER ? (bid.getCostItemCount() + (bid.getCostItemCount() * MARKET_TAX)) : bid.getCostItemCount());
buyer.destroyItemByItemId("Market", bid.getCostItemId(), (int)itemcount, buyer, false);
seller.addItem("Market", bid.getCostItemId(), bid.getCostItemCount(), seller, false);
seller.transferItem("Market", item.getObjectId(), 1, buyer.getInventory(), seller);
if(SEND_MESSAGE_AFTER_TRADE)
{
seller.sendMessage((TRADE_MESSAGE_FORSELLER.replace("%item%", bid.getBidItem().getItemName() + " +" + bid.getBidItem().getEnchantLevel())));
buyer.sendMessage((TRADE_MESSAGE_FORBUYER.replace("%item%", bid.getBidItem().getItemName() + " +" + bid.getBidItem().getEnchantLevel())));
}
lots.get(bid.getBidder().getObjectId()).remove(bid);
}
 
public Bid getBidById(int bidId)
{
Collection<ArrayList<Bid>> collect = lots.values();
for (ArrayList<Bid> list: collect)
{
for (Bid bid: list)
{
if (bid.getBidId() == bidId)
return bid;
}
}
return null;
}
 
public ArrayList<Bid> getAllBids()
{
ArrayList<Bid> result = new ArrayList<>();
Collection<ArrayList<Bid>> collect = lots.values();
for (ArrayList<Bid> list: collect)
{
for (Bid bid: list)
{
result.add(bid);
}
}
return result;
}
 
public int getBidsCount()
{
int count = 0;
 
Collection<ArrayList<Bid>> collect = lots.values();
for (ArrayList<Bid> list: collect)
{
count += list.size();
}
return count;
}
 
public String getShortItemName(int id)
{
for (Map.Entry<String, Integer> entry: prices.entrySet())
{
if (entry.getValue() == id)
return entry.getKey();
}
return "";
}
 
public int getShortItemId(String name)
{
for (Map.Entry<String, Integer> entry: prices.entrySet())
{
if (entry.getKey().equalsIgnoreCase(name))
return entry.getValue();
}
return 0;
}
 
public String getPriceList()
{
String res = "";
Object[] str = Market.prices.keySet().toArray();
for (int i = 0;i < str.length;i++)
{
res += (String)str[i];
if (!(i == str.length-1))
{
res += ";";
}
}
return res;
}
 
public boolean isInArray(int[] arr, int item)
{
for (int i: arr)
{
if (i == item)
return true;
}
return false;
}
 
@SuppressWarnings("static-method")
private void sendResultHtml(L2PcInstance player, String text)
{
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setFile("data/html/market/MarketReturnResult.htm");
html.replace("%text%", text);
player.sendPacket(html);
}
 
public boolean checkItemForMarket(L2ItemInstance item)
{
if (isInArray(DISALLOWED_ITEMS_FOR_BID, item.getItemId()) || (item.isAugmented() && !ALLOW_AUGMENTATED_ITEMS) || item.isStackable()
|| ((item.getItem() instanceof L2EtcItem) && !ALLOW_ETC_ITEMS_FOR_SELL) || (item.getEnchantLevel() > 0 && !ALLOW_ENCHATED_ITEMS))
return false;
return true;
}
 
public Map<Integer, ArrayList<Bid>> getLots()
{
return lots;
}
 
private static Market _instance;
 
public static Market getInstance()
{
if (_instance == null)
_instance = new Market();
return _instance;
}
}

crear una nueva clase con el nombre MarketTaxType
package Market;
 
public enum MarketTaxType {
 
SELLER, BUYER
 
}

Añadir el npc en data/xml/NPCs

<npc id="5" idTemplate="30523" name="Market" title="L2>
<set name="level" val="70"/>
<set name="radius" val="8.0"/>
<set name="height" val="25.0"/>
<set name="rHand" val="0"/>
<set name="lHand" val="0"/>
<set name="type" val="L2MarketNpc"/>
<set name="exp" val="0"/>
<set name="sp" val="0"/>
<set name="hp" val="2444.46819"/>
<set name="mp" val="1345.8"/>
<set name="hpRegen" val="7.5"/>
<set name="mpRegen" val="2.7"/>
<set name="pAtk" val="688.86373"/>
<set name="pDef" val="700.91597"/>
<set name="mAtk" val="470.40463"/>
<set name="mDef" val="700.53847"/>
<set name="crit" val="4"/>
<set name="atkSpd" val="253"/>
<set name="str" val="22"/>
<set name="int" val="41"/>
<set name="dex" val="21"/>
<set name="wit" val="20"/>
<set name="con" val="27"/>
<set name="men" val="20"/>
<set name="corpseTime" val="7"/>
<set name="walkSpd" val="33"/>
<set name="runSpd" val="120"/>
<set name="dropHerbGroup" val="0"/>
<set name="attackRange" val="40"/>
<ai type="mage" ssCount="0" ssRate="0" spsCount="0" spsRate="0" aggro="0" clan="" clanRange="0" clanIgnore="" canMove="false" seedable="false"/>
</npc>

Creditos ElfoCrash