+
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/mods/SellBuffs/BuffChoice.html b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/mods/SellBuffs/BuffChoice.html
new file mode 100644
index 0000000000..5b7ff4ae14
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/mods/SellBuffs/BuffChoice.html
@@ -0,0 +1,10 @@
+
+
+
+
+ %list%
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/mods/SellBuffs/BuffMenu.html b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/mods/SellBuffs/BuffMenu.html
new file mode 100644
index 0000000000..b6a2e12c49
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/mods/SellBuffs/BuffMenu.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Title:
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/mods/SellBuffs/BuffMenu_already.html b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/mods/SellBuffs/BuffMenu_already.html
new file mode 100644
index 0000000000..8b4b5ed697
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/html/mods/SellBuffs/BuffMenu_already.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/SellBuff/SellBuff.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/SellBuff/SellBuff.java
new file mode 100644
index 0000000000..73d3b30ab3
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/custom/SellBuff/SellBuff.java
@@ -0,0 +1,448 @@
+/*
+ * 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 .
+ */
+package custom.SellBuff;
+
+import java.util.StringTokenizer;
+
+import com.l2jmobius.Config;
+import com.l2jmobius.gameserver.datatables.ItemTable;
+import com.l2jmobius.gameserver.handler.BypassHandler;
+import com.l2jmobius.gameserver.handler.IBypassHandler;
+import com.l2jmobius.gameserver.handler.IVoicedCommandHandler;
+import com.l2jmobius.gameserver.handler.VoicedCommandHandler;
+import com.l2jmobius.gameserver.instancemanager.SellBuffsManager;
+import com.l2jmobius.gameserver.model.L2World;
+import com.l2jmobius.gameserver.model.actor.L2Character;
+import com.l2jmobius.gameserver.model.actor.L2Npc;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.events.AbstractScript;
+import com.l2jmobius.gameserver.model.holders.SellBuffHolder;
+import com.l2jmobius.gameserver.model.items.L2Item;
+import com.l2jmobius.gameserver.model.skills.Skill;
+import com.l2jmobius.gameserver.util.Util;
+
+/**
+ * Sell Buffs voice command
+ * @author St3eT
+ */
+public class SellBuff implements IVoicedCommandHandler, IBypassHandler
+{
+ private static final String[] VOICED_COMMANDS =
+ {
+ "sellbuff",
+ "sellbuffs",
+ };
+
+ private static final String[] BYPASS_COMMANDS =
+ {
+ "sellbuffadd",
+ "sellbuffaddskill",
+ "sellbuffedit",
+ "sellbuffchangeprice",
+ "sellbuffremove",
+ "sellbuffbuymenu",
+ "sellbuffbuyskill",
+ "sellbuffstart",
+ "sellbuffstop",
+ };
+
+ private SellBuff()
+ {
+ if (Config.SELLBUFF_ENABLED)
+ {
+ BypassHandler.getInstance().registerHandler(this);
+ VoicedCommandHandler.getInstance().registerHandler(this);
+ }
+ }
+
+ @Override
+ public boolean useBypass(String command, L2PcInstance activeChar, L2Character target)
+ {
+ String cmd = "";
+ String params = "";
+ final StringTokenizer st = new StringTokenizer(command, " ");
+
+ if (st.hasMoreTokens())
+ {
+ cmd = st.nextToken();
+ }
+
+ while (st.hasMoreTokens())
+ {
+ params += st.nextToken() + (st.hasMoreTokens() ? " " : "");
+ }
+
+ if (cmd.isEmpty())
+ {
+ return false;
+ }
+ return useBypass(cmd, activeChar, params);
+ }
+
+ @Override
+ public boolean useVoicedCommand(String command, L2PcInstance activeChar, String params)
+ {
+ switch (command)
+ {
+ case "sellbuff":
+ case "sellbuffs":
+ {
+ SellBuffsManager.getInstance().sendSellMenu(activeChar);
+ break;
+ }
+ }
+ return true;
+ }
+
+ public boolean useBypass(String command, L2PcInstance activeChar, String params)
+ {
+ if (!Config.SELLBUFF_ENABLED)
+ {
+ return false;
+ }
+
+ switch (command)
+ {
+ case "sellbuffstart":
+ {
+ if (activeChar.isSellingBuffs() || (params == null) || params.isEmpty())
+ {
+ return false;
+ }
+ else if (activeChar.getSellingBuffs().isEmpty())
+ {
+ activeChar.sendMessage("Your list of buffs is empty, please add some buffs first!");
+ return false;
+ }
+ else
+ {
+ String title = "BUFF SELL: ";
+ final StringTokenizer st = new StringTokenizer(params, " ");
+ while (st.hasMoreTokens())
+ {
+ title += st.nextToken() + " ";
+ }
+
+ if (title.length() > 40)
+ {
+ activeChar.sendMessage("Your title cannot exceed 29 characters in length. Please try again.");
+ return false;
+ }
+
+ SellBuffsManager.getInstance().startSellBuffs(activeChar, title);
+ }
+ break;
+ }
+ case "sellbuffstop":
+ {
+ if (activeChar.isSellingBuffs())
+ {
+ SellBuffsManager.getInstance().stopSellBuffs(activeChar);
+ }
+ break;
+ }
+ case "sellbuffadd":
+ {
+ if (!activeChar.isSellingBuffs())
+ {
+ int index = 0;
+ if ((params != null) && !params.isEmpty() && Util.isDigit(params))
+ {
+ index = Integer.parseInt(params);
+ }
+
+ SellBuffsManager.getInstance().sendBuffChoiceMenu(activeChar, index);
+ }
+ break;
+ }
+ case "sellbuffedit":
+ {
+ if (!activeChar.isSellingBuffs())
+ {
+ SellBuffsManager.getInstance().sendBuffEditMenu(activeChar);
+ }
+ break;
+ }
+ case "sellbuffchangeprice":
+ {
+ if (!activeChar.isSellingBuffs() && (params != null) && !params.isEmpty())
+ {
+ final StringTokenizer st = new StringTokenizer(params, " ");
+
+ int skillId = -1;
+ int price = -1;
+
+ if (st.hasMoreTokens())
+ {
+ skillId = Integer.parseInt(st.nextToken());
+ }
+
+ if (st.hasMoreTokens())
+ {
+ try
+ {
+ price = Integer.parseInt(st.nextToken());
+ }
+ catch (NumberFormatException e)
+ {
+ activeChar.sendMessage("Too big price! Maximal price is " + Config.SELLBUFF_MAX_PRICE);
+ SellBuffsManager.getInstance().sendBuffEditMenu(activeChar);
+ }
+ }
+
+ if ((skillId == -1) || (price == -1))
+ {
+ return false;
+ }
+
+ final Skill skillToChange = activeChar.getKnownSkill(skillId);
+ if (skillToChange == null)
+ {
+ return false;
+ }
+
+ final SellBuffHolder holder = activeChar.getSellingBuffs().stream().filter(h -> (h.getSkillId() == skillToChange.getId())).findFirst().orElse(null);
+ if ((holder != null))
+ {
+ activeChar.sendMessage("Price of " + activeChar.getKnownSkill(holder.getSkillId()).getName() + " has been changed to " + price + "!");
+ holder.setPrice(price);
+ SellBuffsManager.getInstance().sendBuffEditMenu(activeChar);
+ }
+ }
+ break;
+ }
+ case "sellbuffremove":
+ {
+ if (!activeChar.isSellingBuffs() && (params != null) && !params.isEmpty())
+ {
+ final StringTokenizer st = new StringTokenizer(params, " ");
+
+ int skillId = -1;
+
+ if (st.hasMoreTokens())
+ {
+ skillId = Integer.parseInt(st.nextToken());
+ }
+
+ if ((skillId == -1))
+ {
+ return false;
+ }
+
+ final Skill skillToRemove = activeChar.getKnownSkill(skillId);
+ if (skillToRemove == null)
+ {
+ return false;
+ }
+
+ final SellBuffHolder holder = activeChar.getSellingBuffs().stream().filter(h -> (h.getSkillId() == skillToRemove.getId())).findFirst().orElse(null);
+ if ((holder != null) && activeChar.getSellingBuffs().remove(holder))
+ {
+ activeChar.sendMessage("Skill " + activeChar.getKnownSkill(holder.getSkillId()).getName() + " has been removed!");
+ SellBuffsManager.getInstance().sendBuffEditMenu(activeChar);
+ }
+ }
+ break;
+ }
+ case "sellbuffaddskill":
+ {
+ if (!activeChar.isSellingBuffs() && (params != null) && !params.isEmpty())
+ {
+ final StringTokenizer st = new StringTokenizer(params, " ");
+
+ int skillId = -1;
+ long price = -1;
+
+ if (st.hasMoreTokens())
+ {
+ skillId = Integer.parseInt(st.nextToken());
+ }
+
+ if (st.hasMoreTokens())
+ {
+ try
+ {
+ price = Integer.parseInt(st.nextToken());
+ }
+ catch (NumberFormatException e)
+ {
+ activeChar.sendMessage("Too big price! Maximal price is " + Config.SELLBUFF_MIN_PRICE);
+ SellBuffsManager.getInstance().sendBuffEditMenu(activeChar);
+ }
+ }
+
+ if ((skillId == -1) || (price == -1))
+ {
+ return false;
+ }
+
+ final Skill skillToAdd = activeChar.getKnownSkill(skillId);
+ if (skillToAdd == null)
+ {
+ return false;
+ }
+ else if (price < Config.SELLBUFF_MIN_PRICE)
+ {
+ activeChar.sendMessage("Too small price! Minimal price is " + Config.SELLBUFF_MIN_PRICE);
+ return false;
+ }
+ else if (price > Config.SELLBUFF_MAX_PRICE)
+ {
+ activeChar.sendMessage("Too big price! Maximal price is " + Config.SELLBUFF_MAX_PRICE);
+ return false;
+ }
+ else if (activeChar.getSellingBuffs().size() >= Config.SELLBUFF_MAX_BUFFS)
+ {
+ activeChar.sendMessage("You already reached max count of buffs! Max buffs is: " + Config.SELLBUFF_MAX_BUFFS);
+ return false;
+ }
+ else if (!SellBuffsManager.getInstance().isInSellList(activeChar, skillToAdd))
+ {
+ activeChar.getSellingBuffs().add(new SellBuffHolder(skillToAdd.getId(), price));
+ activeChar.sendMessage(skillToAdd.getName() + " has been added!");
+ SellBuffsManager.getInstance().sendBuffChoiceMenu(activeChar, 0);
+ }
+ }
+ break;
+ }
+ case "sellbuffbuymenu":
+ {
+ if ((params != null) && !params.isEmpty())
+ {
+ final StringTokenizer st = new StringTokenizer(params, " ");
+
+ int objId = -1;
+ int index = 0;
+ if (st.hasMoreTokens())
+ {
+ objId = Integer.parseInt(st.nextToken());
+ }
+
+ if (st.hasMoreTokens())
+ {
+ index = Integer.parseInt(st.nextToken());
+ }
+
+ final L2PcInstance seller = L2World.getInstance().getPlayer(objId);
+ if (seller != null)
+ {
+ if (!seller.isSellingBuffs() || !activeChar.isInsideRadius(seller, L2Npc.INTERACTION_DISTANCE, true, true))
+ {
+ return false;
+ }
+
+ SellBuffsManager.getInstance().sendBuffMenu(activeChar, seller, index);
+ }
+ }
+ break;
+ }
+ case "sellbuffbuyskill":
+ {
+ if ((params != null) && !params.isEmpty())
+ {
+ final StringTokenizer st = new StringTokenizer(params, " ");
+ int objId = -1;
+ int skillId = -1;
+ int index = 0;
+
+ if (st.hasMoreTokens())
+ {
+ objId = Integer.parseInt(st.nextToken());
+ }
+
+ if (st.hasMoreTokens())
+ {
+ skillId = Integer.parseInt(st.nextToken());
+ }
+
+ if (st.hasMoreTokens())
+ {
+ index = Integer.parseInt(st.nextToken());
+ }
+
+ if ((skillId == -1) || (objId == -1))
+ {
+ return false;
+ }
+
+ final L2PcInstance seller = L2World.getInstance().getPlayer(objId);
+ if (seller == null)
+ {
+ return false;
+ }
+
+ final Skill skillToBuy = seller.getKnownSkill(skillId);
+ if (!seller.isSellingBuffs() || !Util.checkIfInRange(L2Npc.INTERACTION_DISTANCE, activeChar, seller, true) || (skillToBuy == null))
+ {
+ return false;
+ }
+
+ if (seller.getCurrentMp() < (skillToBuy.getMpConsume() * Config.SELLBUFF_MP_MULTIPLER))
+ {
+ activeChar.sendMessage(seller.getName() + " has no enough mana for " + skillToBuy.getName() + "!");
+ SellBuffsManager.getInstance().sendBuffMenu(activeChar, seller, index);
+ return false;
+ }
+
+ final SellBuffHolder holder = seller.getSellingBuffs().stream().filter(h -> (h.getSkillId() == skillToBuy.getId())).findFirst().orElse(null);
+ if (holder != null)
+ {
+ if (AbstractScript.getQuestItemsCount(activeChar, Config.SELLBUFF_PAYMENT_ID) >= holder.getPrice())
+ {
+ AbstractScript.takeItems(activeChar, Config.SELLBUFF_PAYMENT_ID, holder.getPrice());
+ AbstractScript.giveItems(seller, Config.SELLBUFF_PAYMENT_ID, holder.getPrice());
+ seller.reduceCurrentMp(skillToBuy.getMpConsume() * Config.SELLBUFF_MP_MULTIPLER);
+ skillToBuy.activateSkill(seller, activeChar);
+ }
+ else
+ {
+ final L2Item item = ItemTable.getInstance().getTemplate(Config.SELLBUFF_PAYMENT_ID);
+ if (item != null)
+ {
+ activeChar.sendMessage("Not enough " + item.getName() + "!");
+ }
+ else
+ {
+ activeChar.sendMessage("Not enough items!");
+ }
+ }
+ }
+ SellBuffsManager.getInstance().sendBuffMenu(activeChar, seller, index);
+ }
+ break;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String[] getVoicedCommandList()
+ {
+ return VOICED_COMMANDS;
+ }
+
+ @Override
+ public String[] getBypassList()
+ {
+ return BYPASS_COMMANDS;
+ }
+
+ public static void main(String[] args)
+ {
+ new SellBuff();
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/SellBuffData.xsd b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/SellBuffData.xsd
new file mode 100644
index 0000000000..c64e08cd7e
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/xsd/SellBuffData.xsd
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/Config.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/Config.java
index dcfe5609ee..2f06f4e729 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/Config.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/Config.java
@@ -121,6 +121,7 @@ public final class Config
public static final String CUSTOM_PVP_ANNOUNCE_CONFIG_FILE = "./Config/Custom/PvpAnnounce.ini";
public static final String CUSTOM_RANDOM_SPAWNS_CONFIG_FILE = "./Config/Custom/RandomSpawns.ini";
public static final String CUSTOM_SCREEN_WELCOME_MESSAGE_CONFIG_FILE = "./Config/Custom/ScreenWelcomeMessage.ini";
+ public static final String CUSTOM_SELL_BUFFS_CONFIG_FILE = "./config/Custom/SellBuffs.ini";
public static final String CUSTOM_SERVER_TIME_CONFIG_FILE = "./Config/Custom/ServerTime.ini";
public static final String CUSTOM_STARTING_LOCATION_CONFIG_FILE = "./Config/Custom/StartingLocation.ini";
public static final String CUSTOM_TVT_CONFIG_FILE = "./Config/Custom/TeamVersusTeam.ini";
@@ -1197,6 +1198,7 @@ public final class Config
public static int COMMUNITY_PREMIUM_PRICE_PER_DAY;
public static List COMMUNITY_AVAILABLE_BUFFS;
public static Map COMMUNITY_AVAILABLE_TELEPORTS;
+ public static boolean ENABLE_FIND_PVP;
public static boolean PREMIUM_SYSTEM_ENABLED;
public static float PREMIUM_RATE_XP;
public static float PREMIUM_RATE_SP;
@@ -1207,7 +1209,12 @@ public final class Config
public static float PREMIUM_RATE_SPOIL_AMOUNT;
public static Map PREMIUM_RATE_DROP_CHANCE_BY_ID;
public static Map PREMIUM_RATE_DROP_AMOUNT_BY_ID;
- public static boolean ENABLE_FIND_PVP;
+ public static boolean SELLBUFF_ENABLED;
+ public static int SELLBUFF_MP_MULTIPLER;
+ public static int SELLBUFF_PAYMENT_ID;
+ public static long SELLBUFF_MIN_PRICE;
+ public static long SELLBUFF_MAX_PRICE;
+ public static int SELLBUFF_MAX_BUFFS;
/**
* This class initializes all global variables for configuration.
@@ -2727,6 +2734,16 @@ public final class Config
WELCOME_MESSAGE_TEXT = ScreenWelcomeMessage.getString("ScreenWelcomeMessageText", "Welcome to our server!");
WELCOME_MESSAGE_TIME = ScreenWelcomeMessage.getInt("ScreenWelcomeMessageTime", 10) * 1000;
+ // Load SellBuffs config file (if exists)
+ final PropertiesParser SellBuffs = new PropertiesParser(CUSTOM_SELL_BUFFS_CONFIG_FILE);
+
+ SELLBUFF_ENABLED = SellBuffs.getBoolean("SellBuffEnable", false);
+ SELLBUFF_MP_MULTIPLER = SellBuffs.getInt("MpCostMultipler", 1);
+ SELLBUFF_PAYMENT_ID = SellBuffs.getInt("PaymentID", 57);
+ SELLBUFF_MIN_PRICE = SellBuffs.getLong("MinimalPrice", 100000);
+ SELLBUFF_MAX_PRICE = SellBuffs.getLong("MaximalPrice", 100000000);
+ SELLBUFF_MAX_BUFFS = SellBuffs.getInt("MaxBuffs", 15);
+
// Load ServerTime config file (if exists)
final PropertiesParser ServerTime = new PropertiesParser(CUSTOM_SERVER_TIME_CONFIG_FILE);
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/GameServer.java
index b6a3c23044..c0c8050afc 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/GameServer.java
@@ -59,7 +59,6 @@ import com.l2jmobius.gameserver.data.xml.impl.HennaData;
import com.l2jmobius.gameserver.data.xml.impl.HitConditionBonusData;
import com.l2jmobius.gameserver.data.xml.impl.InitialEquipmentData;
import com.l2jmobius.gameserver.data.xml.impl.InitialShortcutData;
-import com.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import com.l2jmobius.gameserver.data.xml.impl.KarmaData;
import com.l2jmobius.gameserver.data.xml.impl.MultisellData;
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
@@ -68,6 +67,7 @@ import com.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import com.l2jmobius.gameserver.data.xml.impl.PetSkillData;
import com.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
import com.l2jmobius.gameserver.data.xml.impl.PlayerXpPercentLostData;
+import com.l2jmobius.gameserver.data.xml.impl.PrimeShopData;
import com.l2jmobius.gameserver.data.xml.impl.RecipeData;
import com.l2jmobius.gameserver.data.xml.impl.SecondaryAuthData;
import com.l2jmobius.gameserver.data.xml.impl.SiegeScheduleData;
@@ -116,6 +116,7 @@ import com.l2jmobius.gameserver.instancemanager.PunishmentManager;
import com.l2jmobius.gameserver.instancemanager.QuestManager;
import com.l2jmobius.gameserver.instancemanager.RaidBossPointsManager;
import com.l2jmobius.gameserver.instancemanager.RaidBossSpawnManager;
+import com.l2jmobius.gameserver.instancemanager.SellBuffsManager;
import com.l2jmobius.gameserver.instancemanager.ServerRestartManager;
import com.l2jmobius.gameserver.instancemanager.SiegeManager;
import com.l2jmobius.gameserver.instancemanager.SoDManager;
@@ -281,6 +282,10 @@ public final class GameServer
CursedWeaponsManager.getInstance();
TransformData.getInstance();
BotReportTable.getInstance();
+ if (Config.SELLBUFF_ENABLED)
+ {
+ SellBuffsManager.getInstance();
+ }
printSection("Scripts");
QuestManager.getInstance();
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/data/sql/impl/OfflineTradersTable.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/data/sql/impl/OfflineTradersTable.java
index e496cf34f5..efe55bcf4e 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/data/sql/impl/OfflineTradersTable.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/data/sql/impl/OfflineTradersTable.java
@@ -32,6 +32,7 @@ import com.l2jmobius.gameserver.model.L2ManufactureItem;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.TradeItem;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.holders.SellBuffHolder;
import com.l2jmobius.gameserver.network.Disconnection;
import com.l2jmobius.gameserver.network.L2GameClient;
@@ -73,7 +74,7 @@ public class OfflineTradersTable
{
stm3.setInt(1, pc.getObjectId()); // Char Id
stm3.setLong(2, pc.getOfflineStartTime());
- stm3.setInt(3, pc.getPrivateStoreType().getId()); // store type
+ stm3.setInt(3, pc.isSellingBuffs() ? PrivateStoreType.SELL_BUFFS.getId() : pc.getPrivateStoreType().getId()); // store type
String title = null;
switch (pc.getPrivateStoreType())
@@ -104,14 +105,29 @@ public class OfflineTradersTable
continue;
}
title = pc.getSellList().getTitle();
- for (TradeItem i : pc.getSellList().getItems())
+ if (pc.isSellingBuffs())
{
- stm_items.setInt(1, pc.getObjectId());
- stm_items.setInt(2, i.getObjectId());
- stm_items.setLong(3, i.getCount());
- stm_items.setLong(4, i.getPrice());
- stm_items.executeUpdate();
- stm_items.clearParameters();
+ for (SellBuffHolder holder : pc.getSellingBuffs())
+ {
+ stm_items.setInt(1, pc.getObjectId());
+ stm_items.setInt(2, holder.getSkillId());
+ stm_items.setLong(3, 0);
+ stm_items.setLong(4, holder.getPrice());
+ stm_items.executeUpdate();
+ stm_items.clearParameters();
+ }
+ }
+ else
+ {
+ for (TradeItem i : pc.getSellList().getItems())
+ {
+ stm_items.setInt(1, pc.getObjectId());
+ stm_items.setInt(2, i.getObjectId());
+ stm_items.setLong(3, i.getCount());
+ stm_items.setLong(4, i.getPrice());
+ stm_items.executeUpdate();
+ stm_items.clearParameters();
+ }
}
break;
}
@@ -175,7 +191,16 @@ public class OfflineTradersTable
}
}
- final PrivateStoreType type = PrivateStoreType.findById(rs.getInt("type"));
+ final int typeId = rs.getInt("type");
+ boolean isSellBuff = false;
+
+ if (typeId == PrivateStoreType.SELL_BUFFS.getId())
+ {
+ isSellBuff = true;
+ }
+
+ final PrivateStoreType type = isSellBuff ? PrivateStoreType.PACKAGE_SELL : PrivateStoreType.findById(typeId);
+
if (type == null)
{
LOGGER.warning(getClass().getSimpleName() + ": PrivateStoreType with id " + rs.getInt("type") + " could not be found.");
@@ -199,6 +224,12 @@ public class OfflineTradersTable
client.setAccountName(player.getAccountNamePlayer());
player.setClient(client);
player.setOfflineStartTime(time);
+
+ if (isSellBuff)
+ {
+ player.setIsSellingBuffs(true);
+ }
+
player.spawnMe(player.getX(), player.getY(), player.getZ());
LoginServerThread.getInstance().addGameServerLogin(player.getAccountName(), client);
try (PreparedStatement stm_items = con.prepareStatement(LOAD_OFFLINE_ITEMS))
@@ -224,12 +255,22 @@ public class OfflineTradersTable
case SELL:
case PACKAGE_SELL:
{
- while (items.next())
+ if (player.isSellingBuffs())
{
- if (player.getSellList().addItem(items.getInt(2), items.getLong(3), items.getLong(4)) == null)
+ while (items.next())
{
- continue;
- // throw new NullPointerException();
+ player.getSellingBuffs().add(new SellBuffHolder(items.getInt("item"), items.getLong("price")));
+ }
+ }
+ else
+ {
+ while (items.next())
+ {
+ if (player.getSellList().addItem(items.getInt(2), items.getLong(3), items.getLong(4)) == null)
+ {
+ continue;
+ // throw new NullPointerException();
+ }
}
}
player.getSellList().setTitle(rs.getString("title"));
@@ -339,14 +380,29 @@ public class OfflineTradersTable
{
title = trader.getSellList().getTitle();
}
- for (TradeItem i : trader.getSellList().getItems())
+ if (trader.isSellingBuffs())
{
- stm3.setInt(1, trader.getObjectId());
- stm3.setInt(2, i.getObjectId());
- stm3.setLong(3, i.getCount());
- stm3.setLong(4, i.getPrice());
- stm3.executeUpdate();
- stm3.clearParameters();
+ for (SellBuffHolder holder : trader.getSellingBuffs())
+ {
+ stm3.setInt(1, trader.getObjectId());
+ stm3.setInt(2, holder.getSkillId());
+ stm3.setLong(3, 0);
+ stm3.setLong(4, holder.getPrice());
+ stm3.executeUpdate();
+ stm3.clearParameters();
+ }
+ }
+ else
+ {
+ for (TradeItem i : trader.getSellList().getItems())
+ {
+ stm3.setInt(1, trader.getObjectId());
+ stm3.setInt(2, i.getObjectId());
+ stm3.setLong(3, i.getCount());
+ stm3.setLong(4, i.getPrice());
+ stm3.executeUpdate();
+ stm3.clearParameters();
+ }
}
break;
}
@@ -373,7 +429,7 @@ public class OfflineTradersTable
{
stm4.setInt(1, trader.getObjectId()); // Char Id
stm4.setLong(2, trader.getOfflineStartTime());
- stm4.setInt(3, trader.getPrivateStoreType().getId()); // store type
+ stm4.setInt(3, trader.isSellingBuffs() ? PrivateStoreType.SELL_BUFFS.getId() : trader.getPrivateStoreType().getId()); // store type
stm4.setString(4, title);
stm4.executeUpdate();
stm4.clearParameters();
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/enums/PrivateStoreType.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/enums/PrivateStoreType.java
index 0d03c4cc5a..23e82469a0 100644
--- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/enums/PrivateStoreType.java
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/enums/PrivateStoreType.java
@@ -27,7 +27,8 @@ public enum PrivateStoreType
BUY(3),
BUY_MANAGE(4),
MANUFACTURE(5),
- PACKAGE_SELL(8);
+ PACKAGE_SELL(8),
+ SELL_BUFFS(9);
private int _id;
diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/SellBuffsManager.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/SellBuffsManager.java
new file mode 100644
index 0000000000..2b1c54fa5b
--- /dev/null
+++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/instancemanager/SellBuffsManager.java
@@ -0,0 +1,454 @@
+/*
+ * 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 .
+ */
+package com.l2jmobius.gameserver.instancemanager;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import com.l2jmobius.Config;
+import com.l2jmobius.commons.util.IGameXmlReader;
+import com.l2jmobius.gameserver.cache.HtmCache;
+import com.l2jmobius.gameserver.datatables.ItemTable;
+import com.l2jmobius.gameserver.datatables.SkillData;
+import com.l2jmobius.gameserver.enums.PrivateStoreType;
+import com.l2jmobius.gameserver.handler.CommunityBoardHandler;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.holders.SellBuffHolder;
+import com.l2jmobius.gameserver.model.items.L2Item;
+import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
+import com.l2jmobius.gameserver.model.skills.Skill;
+import com.l2jmobius.gameserver.model.zone.ZoneId;
+import com.l2jmobius.gameserver.network.serverpackets.ExPrivateStoreSetWholeMsg;
+import com.l2jmobius.gameserver.util.HtmlUtil;
+import com.l2jmobius.gameserver.util.Util;
+
+/**
+ * Sell Buffs Manager
+ * @author St3eT
+ */
+public final class SellBuffsManager implements IGameXmlReader
+{
+ private static final Logger LOGGER = Logger.getLogger(SellBuffsManager.class.getName());
+ private static final List ALLOWED_BUFFS = new ArrayList<>();
+ private static final String htmlFolder = "data/html/mods/SellBuffs/";
+
+ protected SellBuffsManager()
+ {
+ load();
+ }
+
+ @Override
+ public void load()
+ {
+ if (Config.SELLBUFF_ENABLED)
+ {
+ ALLOWED_BUFFS.clear();
+ parseDatapackFile("data/SellBuffData.xml");
+ LOGGER.info(getClass().getSimpleName() + ": Loaded " + ALLOWED_BUFFS.size() + " allowed buffs.");
+ }
+ }
+
+ @Override
+ public void parseDocument(Document doc, File f)
+ {
+ final NodeList node = doc.getDocumentElement().getElementsByTagName("skill");
+ for (int i = 0; i < node.getLength(); ++i)
+ {
+ final Element elem = (Element) node.item(i);
+ final int skillId = Integer.parseInt(elem.getAttribute("id"));
+
+ if (!ALLOWED_BUFFS.contains(skillId))
+ {
+ ALLOWED_BUFFS.add(skillId);
+ }
+ }
+ }
+
+ public void sendSellMenu(L2PcInstance player)
+ {
+ final String html = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), htmlFolder + (player.isSellingBuffs() ? "BuffMenu_already.html" : "BuffMenu.html"));
+ CommunityBoardHandler.separateAndSend(html, player);
+ }
+
+ public void sendBuffChoiceMenu(L2PcInstance player, int index)
+ {
+ String html = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), htmlFolder + "BuffChoice.html");
+ html = html.replace("%list%", buildSkillMenu(player, index));
+ CommunityBoardHandler.separateAndSend(html, player);
+ }
+
+ public void sendBuffEditMenu(L2PcInstance player)
+ {
+ String html = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), htmlFolder + "BuffChoice.html");
+ html = html.replace("%list%", buildEditMenu(player));
+ CommunityBoardHandler.separateAndSend(html, player);
+ }
+
+ public void sendBuffMenu(L2PcInstance player, L2PcInstance seller, int index)
+ {
+ if (!seller.isSellingBuffs() || seller.getSellingBuffs().isEmpty())
+ {
+ return;
+ }
+
+ String html = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), htmlFolder + "BuffBuyMenu.html");
+ html = html.replace("%list%", buildBuffMenu(player, seller, index));
+ CommunityBoardHandler.separateAndSend(html, player);
+ }
+
+ public void startSellBuffs(L2PcInstance player, String title)
+ {
+ player.sitDown();
+ player.setIsSellingBuffs(true);
+ player.setPrivateStoreType(PrivateStoreType.PACKAGE_SELL);
+ player.getSellList().setTitle(title);
+ player.getSellList().setPackaged(true);
+ player.broadcastUserInfo();
+ player.broadcastPacket(new ExPrivateStoreSetWholeMsg(player));
+ sendSellMenu(player);
+ }
+
+ public void stopSellBuffs(L2PcInstance player)
+ {
+ player.setIsSellingBuffs(false);
+ player.setPrivateStoreType(PrivateStoreType.NONE);
+ player.standUp();
+ player.broadcastUserInfo();
+ sendSellMenu(player);
+ }
+
+ private String buildBuffMenu(L2PcInstance player, L2PcInstance seller, int index)
+ {
+ final int ceiling = index + 10;
+ int nextIndex = -1;
+ int previousIndex = -1;
+ int emptyFields = 0;
+ final StringBuilder sb = new StringBuilder();
+ final List sellList = new ArrayList<>();
+
+ int count = 0;
+ for (SellBuffHolder holder : seller.getSellingBuffs())
+ {
+ count++;
+ if ((count > index) && (count <= ceiling))
+ {
+ sellList.add(holder);
+ }
+ }
+
+ if (count > 10)
+ {
+ if (count > (index + 10))
+ {
+ nextIndex = index + 10;
+ }
+ }
+
+ if (index >= 10)
+ {
+ previousIndex = index - 10;
+ }
+
+ emptyFields = ceiling - sellList.size();
+
+ sb.append(" ");
+ sb.append(HtmlUtil.getMpGauge(250, (long) seller.getCurrentMp(), seller.getMaxMp(), false));
+ sb.append(" ");
+
+ sb.append("
");
+ sb.append("
");
+ sb.append("
");
+ sb.append("
");
+ sb.append("
"); // Icon
+ sb.append("
"); // Name
+ sb.append("
"); // Leve
+ sb.append("
"); // Price
+ sb.append("
"); // Price
+ sb.append("
"); // Action
+ sb.append("
");
+ sb.append("
");
+
+ for (SellBuffHolder holder : sellList)
+ {
+ final Skill skill = seller.getKnownSkill(holder.getSkillId());
+ if (skill == null)
+ {
+ emptyFields++;
+ continue;
+ }
+
+ final L2Item item = ItemTable.getInstance().getTemplate(Config.SELLBUFF_PAYMENT_ID);
+
+ sb.append("