### Eclipse Workspace Patch 1.0
#P aCis_gameserverr
Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java (revision 6)
+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java (working copy)
@@ -112,7 +112,7 @@
synchronized (item)
{
- double chance = scrollTemplate.getChance(item);
+ double chance = scrollTemplate.getChance(item, activeChar);
// last validation check
if (item.getOwnerId() != activeChar.getObjectId() || !isEnchantable(item) || chance < 0)
Index: java/net/sf/l2j/gameserver/model/actor/instance/L2MultiShopInstance.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/instance/L2MultiShopInstance.java (nonexistent)
+++ java/net/sf/l2j/gameserver/model/actor/instance/L2MultiShopInstance.java (working copy)
@@ -0,0 +1,1248 @@
+/*
+ * 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 net.sf.l2j.gameserver.model.actor.instance;
+
+import java.security.MessageDigest;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Base64;
+import java.util.StringTokenizer;
+
+import net.sf.l2j.Config;
+import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.commons.concurrent.ThreadPool;
+import net.sf.l2j.gameserver.ai.CtrlIntention;
+import net.sf.l2j.gameserver.datatables.CharNameTable;
+import net.sf.l2j.gameserver.datatables.SkillTable;
+import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminVipStatus;
+import net.sf.l2j.gameserver.instancemanager.CastleManager;
+import net.sf.l2j.gameserver.model.L2Augmentation;
+import net.sf.l2j.gameserver.model.L2Skill;
+import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.model.actor.template.NpcTemplate;
+import net.sf.l2j.gameserver.model.base.Sex;
+import net.sf.l2j.gameserver.model.entity.Castle;
+import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
+import net.sf.l2j.gameserver.model.itemcontainer.Inventory;
+import net.sf.l2j.gameserver.model.olympiad.OlympiadManager;
+import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
+import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
+import net.sf.l2j.gameserver.network.serverpackets.ItemList;
+import net.sf.l2j.gameserver.network.serverpackets.MagicSkillUse;
+import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
+import net.sf.l2j.gameserver.network.serverpackets.SiegeInfo;
+import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
+
+/**
+ * @author Baggos
+ */
+public class L2MultiShopInstance extends L2NpcInstance
+{
+ public L2MultiShopInstance(int objectId, NpcTemplate template)
+ {
+ super(objectId, template);
+ }
+
+ @Override
+ public void onBypassFeedback(L2PcInstance player, String command)
+ {
+ if (player == null)
+ return;
+
+ if (command.startsWith("donate"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ try
+ {
+ String type = st.nextToken();
+ switch (type)
+ {
+ case "Noblesse":
+ Nobless(player);
+ break;
+ case "ChangeSex":
+ Sex(player);
+ break;
+ case "CleanPk":
+ CleanPk(player);
+ break;
+ case "FullRec":
+ Rec(player);
+ break;
+ case "ChangeClass":
+ final NpcHtmlMessage html = new NpcHtmlMessage(0);
+ html.setFile("data/html/mods/donateNpc/50091-2.htm");
+ player.sendPacket(html);
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ else if (command.startsWith("clan"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ try
+ {
+ String type = st.nextToken();
+ switch (type)
+ {
+ case "ClanLevel":
+ Clanlvl(player);
+ break;
+ case "ClanRep_20k":
+ ClanRep(player);
+ break;
+ case "ClanSkills":
+ ClanSkill(player);
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ else if (command.startsWith("siege"))
+ {
+
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ try
+ {
+ String type = st.nextToken();
+ int castleId = 0;
+
+ if (type.startsWith("Gludio"))
+ castleId = 1;
+ else if (type.startsWith("Dion"))
+ castleId = 2;
+ else if (type.startsWith("Giran"))
+ castleId = 3;
+ else if (type.startsWith("Oren"))
+ castleId = 4;
+ else if (type.startsWith("Aden"))
+ castleId = 5;
+ else if (type.startsWith("Innadril"))
+ castleId = 6;
+ else if (type.startsWith("Goddard"))
+ castleId = 7;
+ else if (type.startsWith("Rune"))
+ castleId = 8;
+ else if (type.startsWith("Schuttgart"))
+ castleId = 9;
+
+ Castle castle = CastleManager.getInstance().getCastleById(castleId);
+
+ if (castle != null && castleId != 0)
+ player.sendPacket(new SiegeInfo(castle));
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ else if (command.startsWith("color"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ try
+ {
+ String type = st.nextToken();
+ switch (type)
+ {
+ case "Green":
+ GreenColor(player);
+ break;
+ case "Blue":
+ BlueColor(player);
+ break;
+ case "Purple":
+ PurpleColor(player);
+ break;
+ case "Yellow":
+ YellowColor(player);
+ break;
+ case "Gold":
+ GoldColor(player);
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ else if (command.startsWith("vip"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ try
+ {
+ String type = st.nextToken();
+ switch (type)
+ {
+ case "Vip7Days":
+ Vip7(player);
+ break;
+ case "Vip15Days":
+ Vip15(player);
+ break;
+ case "Vip30Days":
+ Vip30(player);
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ else if (command.startsWith("active"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ try
+ {
+ String type = st.nextToken();
+ switch (type)
+ {
+ case "Might":
+ augments(player, 1062079106, 3132, 10);
+ break;
+ case "Empower":
+ augments(player, 1061423766, 3133, 10);
+ break;
+ case "DuelMight":
+ augments(player, 1062406807, 3134, 10);
+ break;
+ case "Shield":
+ augments(player, 968884225, 3135, 10);
+ break;
+ case "MagicBarrier":
+ augments(player, 956760065, 3136, 10);
+ break;
+ case "WildMagic":
+ augments(player, 1067850844, 3142, 10);
+ break;
+ case "Focus":
+ augments(player, 1067523168, 3141, 10);
+ break;
+ case "BattleRoad":
+ augments(player, 968228865, 3125, 10);
+ break;
+ case "BlessedBody":
+ augments(player, 991625216, 3124, 10);
+ break;
+ case "Agility":
+ augments(player, 1060444351, 3139, 10);
+ break;
+ case "Heal":
+ augments(player, 1061361888, 3123, 10);
+ break;
+ case "HydroBlast":
+ augments(player, 1063590051, 3167, 10);
+ break;
+ case "AuraFlare":
+ augments(player, 1063455338, 3172, 10);
+ break;
+ case "Hurricane":
+ augments(player, 1064108032, 3168, 10);
+ break;
+ case "ReflectDamage":
+ augments(player, 1067588698, 3204, 3);
+ break;
+ case "Celestial":
+ augments(player, 974454785, 3158, 1);
+ break;
+ case "Stone":
+ augments(player, 1060640984, 3169, 10);
+ break;
+ case "HealEmpower":
+ augments(player, 1061230760, 3138, 10);
+ break;
+ case "ShadowFlare":
+ augments(player, 1063520931, 3171, 10);
+ break;
+ case "Prominence":
+ augments(player, 1063327898, 3165, 10);
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ player.sendMessage("Usage : Bar>");
+ }
+ }
+ else if (command.startsWith("passive"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ try
+ {
+ String type = st.nextToken();
+ switch (type)
+ {
+ case "DuelMight":
+ augments(player, 1067260101, 3243, 10);
+ break;
+ case "Might":
+ augments(player, 1067125363, 3240, 10);
+ break;
+ case "Shield":
+ augments(player, 1067194549, 3244, 10);
+ break;
+ case "MagicBarrier":
+ augments(player, 962068481, 3245, 10);
+ break;
+ case "Empower":
+ augments(player, 1066994296, 3241, 10);
+ break;
+ case "Agility":
+ augments(player, 965279745, 3247, 10);
+ break;
+ case "Guidance":
+ augments(player, 1070537767, 3248, 10);
+ break;
+ case "Focus":
+ augments(player, 1070406728, 3249, 10);
+ break;
+ case "WildMagic":
+ augments(player, 1070599653, 3250, 10);
+ break;
+ case "ReflectDamage":
+ augments(player, 1070472227, 3259, 3);
+ break;
+ case "HealEmpower":
+ augments(player, 1066866909, 3246, 10);
+ break;
+ case "Prayer":
+ augments(player, 1066932422, 3238, 10);
+ break;
+
+ }
+ }
+ catch (Exception e)
+ {
+ player.sendMessage("Usage : Bar>");
+ }
+ }
+ else if (command.startsWith("name"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+
+ String newName = "";
+ try
+ {
+ if (st.hasMoreTokens())
+ {
+ newName = st.nextToken();
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ if (!conditionsname(newName, player))
+ return;
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.NAME_ITEM_COUNT, player, true);
+ player.setName(newName);
+ player.store();
+ player.sendMessage("Your new character name is " + newName);
+ player.broadcastUserInfo();
+ }
+ else if (command.startsWith("password"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+
+ String newPass = "";
+ String repeatNewPass = "";
+
+ try
+ {
+ if (st.hasMoreTokens())
+ {
+ newPass = st.nextToken();
+ repeatNewPass = st.nextToken();
+ }
+ }
+ catch (Exception e)
+ {
+ player.sendMessage("Please fill all the blanks before requesting for a password change.");
+ return;
+ }
+
+ if (!conditions(newPass, repeatNewPass, player))
+ return;
+ changePassword(newPass, repeatNewPass, player);
+ }
+ else if (command.startsWith("partytp"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+
+ String val = "";
+ try
+ {
+ if (st.hasMoreTokens())
+ {
+ val = st.nextToken();
+ }
+ L2PcInstance activeChar = L2World.getInstance().getPlayer(val);
+ teleportTo(val, player, activeChar);
+ }
+ catch (Exception e)
+ {
+ // Case of empty or missing coordinates
+ player.sendMessage("Incorrect target");
+ }
+ }
+ else if (command.startsWith("teleport"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+
+ String clan = "";
+ try
+ {
+ if (st.hasMoreTokens())
+ {
+ clan = st.nextToken();
+ }
+ L2PcInstance activeChar = L2World.getInstance().getPlayer(clan);
+ teleportToClan(clan, player, activeChar);
+ }
+ catch (Exception e)
+ {
+ // Case if the player is not in the same clan.
+ player.sendMessage("Incorrect target");
+ }
+ }
+ else if (command.startsWith("enchant"))
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ try
+ {
+ String type = st.nextToken();
+ switch (type)
+ {
+ case "Weapon":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_RHAND);
+ break;
+ case "Shield":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_LHAND);
+ break;
+ case "R-Earring":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_REAR);
+ break;
+ case "L-Earring":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_LEAR);
+ break;
+ case "R-Ring":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_RFINGER);
+ break;
+ case "L-Ring":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_LFINGER);
+ break;
+ case "Necklace":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_NECK);
+ break;
+ case "Helmet":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_HEAD);
+ break;
+ case "Boots":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_FEET);
+ break;
+ case "Gloves":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_GLOVES);
+ break;
+ case "Chest":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_CHEST);
+ break;
+ case "Legs":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_LEGS);
+ break;
+ case "Tattoo":
+ Enchant(player, Config.ENCHANT_MAX_VALUE, Inventory.PAPERDOLL_UNDER);
+ break;
+ }
+ }
+
+ catch (Exception e)
+ {
+ }
+ }
+ else if (command.startsWith("Chat"))
+ showChatWindow(player, command);
+ }
+
+ @Override
+ public void showChatWindow(L2PcInstance player, String command)
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ int page = Integer.parseInt(st.nextToken());
+ String filename = "data/html/mods/donateNpc/" + page + ".htm";
+ filename = "data/html/mods/donateNpc/50091-" + page + ".htm";
+
+ final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
+ html.setFile(filename);
+ html.replace("%objectId%", getObjectId());
+ html.replace("%npcname%", getName());
+ player.sendPacket(html);
+ }
+
+ public void Nobless(L2PcInstance player)
+ {
+ if (player.isNoble())
+ {
+ player.sendMessage("You Are Already A Noblesse!.");
+ return;
+ }
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.NOBL_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.NOBL_ITEM_COUNT, player, true);
+ player.setNoble(true, true);
+ player.sendMessage("You Are Now a Noble,You Are Granted With Noblesse Status , And Noblesse Skills.");
+ player.broadcastUserInfo();
+
+ }
+
+ public void Vip7(L2PcInstance player)
+ {
+ if (player.isVipStatus())
+ {
+ player.sendMessage("You are Already A Vip");
+ return;
+ }
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.VIP7_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.VIP7_ITEM_COUNT, player, true);
+ AdminVipStatus.AddVipStatus(player, player, 7);
+ player.sendMessage("You engage VIP Status for 7 Days.");
+
+ }
+
+ public void Vip15(L2PcInstance player)
+ {
+ if (player.isVipStatus())
+ {
+ player.sendMessage("You are Already A Vip");
+ return;
+ }
+
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.VIP15_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.VIP15_ITEM_COUNT, player, true);
+ AdminVipStatus.AddVipStatus(player, player, 15);
+ player.sendMessage("You engage VIP Status for 15 Days.");
+
+ }
+
+ public void Vip30(L2PcInstance player)
+ {
+ if (player.isVipStatus())
+ {
+ player.sendMessage("Your character has already Vip Status.");
+ return;
+ }
+
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.VIP30_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.VIP30_ITEM_COUNT, player, true);
+ AdminVipStatus.AddVipStatus(player, player, 30);
+ player.sendMessage("You engage VIP Status for 30 Days.");
+
+ }
+
+ public void GreenColor(L2PcInstance player)
+ {
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.COLOR_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.COLOR_ITEM_COUNT, player, true);
+ player.setColor(1);
+ player.getAppearance().setNameColor(0x009900);
+ player.broadcastUserInfo();
+ player.sendMessage("Your color name has changed!");
+ }
+
+ public void BlueColor(L2PcInstance player)
+ {
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.COLOR_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.COLOR_ITEM_COUNT, player, true);
+ player.setColor(2);
+ player.getAppearance().setNameColor(0xff7f00);
+ player.broadcastUserInfo();
+ player.sendMessage("Your color name has changed!");
+ }
+
+ public void PurpleColor(L2PcInstance player)
+ {
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.COLOR_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.COLOR_ITEM_COUNT, player, true);
+ player.setColor(3);
+ player.getAppearance().setNameColor(0xff00ff);
+ player.broadcastUserInfo();
+ player.sendMessage("Your color name has changed!");
+ }
+
+ public void YellowColor(L2PcInstance player)
+ {
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.COLOR_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.COLOR_ITEM_COUNT, player, true);
+ player.setColor(4);
+ player.getAppearance().setNameColor(0x00ffff);
+ player.broadcastUserInfo();
+ player.sendMessage("Your color name has changed!");
+ }
+
+ public void GoldColor(L2PcInstance player)
+ {
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.COLOR_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.COLOR_ITEM_COUNT, player, true);
+ player.setColor(5);
+ player.getAppearance().setNameColor(0x0099ff);
+ player.broadcastUserInfo();
+ player.sendMessage("Your color name has changed!");
+ }
+
+ public void Sex(L2PcInstance player)
+ {
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.SEX_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.getAppearance().setSex(player.getAppearance().getSex() == Sex.MALE ? Sex.FEMALE : Sex.MALE);
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.SEX_ITEM_COUNT, player, true);
+ player.sendMessage("Your gender has been changed,You will Be Disconected in 3 Seconds!");
+ player.broadcastUserInfo();
+ player.decayMe();
+ player.spawnMe();
+ ThreadPool.schedule(() -> player.logout(false), 3000);
+ }
+
+ public void Rec(L2PcInstance player)
+ {
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.REC_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ if (player.getRecomHave() == 255)
+ {
+ player.sendMessage("You already have full recommends.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.REC_ITEM_COUNT, player, true);
+ player.setRecomHave(255);
+ player.getLastRecomUpdate();
+ player.broadcastUserInfo();
+ }
+
+ public void CleanPk(L2PcInstance player)
+ {
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.PK_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ if (player.getPkKills() < 50)
+ {
+ player.sendMessage("You do not have enough Pk kills for clean.");
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.PK_ITEM_COUNT, player, true);
+ player.setPkKills(player.getPkKills() - Config.PK_CLEAN);
+ player.sendMessage("You have successfully clean " + Config.PK_CLEAN + " pks!");
+ player.broadcastUserInfo();
+ }
+
+ public void ClanRep(L2PcInstance player)
+ {
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.CLAN_REP_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ if (player.getClan() == null)
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_A_CLAN_MEMBER);
+ return;
+ }
+ if (!player.isClanLeader())
+ {
+ player.sendPacket(SystemMessageId.NOT_AUTHORIZED_TO_BESTOW_RIGHTS);
+ return;
+ }
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.CLAN_REP_ITEM_COUNT, player, true);
+ player.getClan().addReputationScore(Config.CLAN_REPS);
+ player.getClan().broadcastClanStatus();
+ player.sendMessage("Your clan reputation score has been increased.");
+ }
+
+ public void Clanlvl(L2PcInstance player)
+ {
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.CLAN_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ else if (player.getClan() == null)
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_A_CLAN_MEMBER);
+ return;
+ }
+ if (!player.isClanLeader())
+ {
+ player.sendPacket(SystemMessageId.NOT_AUTHORIZED_TO_BESTOW_RIGHTS);
+ return;
+ }
+ if (player.getClan().getLevel() == 8)
+ {
+ player.sendMessage("Your clan is already level 8.");
+ return;
+ }
+ player.getClan().changeLevel(player.getClan().getLevel() + 1);
+ player.getClan().broadcastClanStatus();
+ player.broadcastPacket(new MagicSkillUse(player, player, 5103, 1, 1000, 0));
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.CLAN_ITEM_COUNT, player, true);
+ }
+
+ public void augments(L2PcInstance player, int attributes, int idaugment, int levelaugment)
+ {
+ ItemInstance rhand = player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
+
+ if (rhand == null)
+ {
+ player.sendMessage(player.getName() + " have to equip a weapon.");
+ return;
+ }
+ else if (rhand.getItem().getCrystalType().getId() == 0 || rhand.getItem().getCrystalType().getId() == 1 || rhand.getItem().getCrystalType().getId() == 2)
+ {
+ player.sendMessage("You can't augment under " + rhand.getItem().getCrystalType() + " Grade Weapon!");
+ return;
+ }
+ else if (rhand.isHeroItem())
+ {
+ player.sendMessage("You Cannot be add Augment On " + rhand.getItemName() + " !");
+ return;
+ }
+ else if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.AUGM_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ if (!rhand.isAugmented())
+ {
+ player.sendMessage("Successfully To Add " + SkillTable.getInstance().getInfo(idaugment, levelaugment).getName() + ".");
+ augmentweapondatabase(player, attributes, idaugment, levelaugment);
+ }
+ else
+ {
+ player.sendMessage("You Have Augment on weapon!");
+ return;
+ }
+ }
+
+ public void augmentweapondatabase(L2PcInstance player, int attributes, int id, int level)
+ {
+ ItemInstance item = player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
+ L2Augmentation augmentation = new L2Augmentation(attributes, id, level);
+ augmentation.applyBonus(player);
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.AUGM_ITEM_COUNT, player, true);
+ item.setAugmentation(augmentation);
+ player.disarmWeapons();
+
+ try (Connection con = L2DatabaseFactory.getInstance().getConnection())
+ {
+ PreparedStatement statement = con.prepareStatement("REPLACE INTO augmentations VALUES(?,?,?,?)");
+ statement.setInt(1, item.getObjectId());
+ statement.setInt(2, attributes);
+ statement.setInt(3, id);
+ statement.setInt(4, level);
+ InventoryUpdate iu = new InventoryUpdate();
+ player.sendPacket(iu);
+ statement.execute();
+ statement.close();
+ }
+ catch (SQLException e)
+ {
+ System.out.println(e);
+ }
+ }
+
+ /**
+ * @param player
+ */
+ public void removeAugmentation(L2PcInstance player)
+ {
+ ItemInstance item = player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
+
+ if (item == null)
+ {
+ player.sendMessage("Equipped first a weapon!");
+ return;
+ }
+
+ if (!item.isAugmented())
+ {
+ player.sendMessage("The weapon is not augmented.");
+ return;
+ }
+
+ item.getAugmentation().removeBonus(player);
+ item.removeAugmentation();
+ {
+ player.sendMessage("Your augmented has been removed!");
+ // Unequip the weapon
+ player.disarmWeapons();
+ }
+ }
+
+ public void ClanSkill(L2PcInstance player)
+ {
+
+ if (!player.isClanLeader())
+ {
+ player.sendMessage("Only a clan leader can add clan skills.!");
+ return;
+ }
+ if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.CLAN_SKILL_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(370, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(371, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(372, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(373, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(374, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(375, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(376, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(377, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(378, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(379, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(380, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(381, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(382, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(383, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(384, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(385, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(386, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(387, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(388, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(389, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(390, 3));
+ player.getClan().addNewSkill(SkillTable.getInstance().getInfo(391, 1));
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.CLAN_SKILL_ITEM_COUNT, player, true);
+ }
+
+ public void Enchant(L2PcInstance player, int enchant, int type)
+ {
+ ItemInstance item = player.getInventory().getPaperdollItem(type);
+
+ if (item == null)
+ {
+ player.sendMessage("That item doesn't exist in your inventory.");
+ return;
+ }
+ else if (item.getEnchantLevel() == Config.ENCHANT_MAX_VALUE || item.getEnchantLevel() == Config.ENCHANT_MAX_VALUE)
+ {
+ player.sendMessage("Your " + item.getItemName() + " is already on maximun enchant!");
+ return;
+ }
+ else if (item.getItem().getCrystalType().getId() == 0)
+ {
+ player.sendMessage("You can't Enchant under " + item.getItem().getCrystalType() + " Grade Weapon!");
+ return;
+ }
+ else if (item.isHeroItem())
+ {
+ player.sendMessage("You Cannot be Enchant On " + item.getItemName() + " !");
+ return;
+ }
+ else if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.ENCHANT_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return;
+ }
+ if (item.isEquipped())
+ {
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.ENCHANT_ITEM_COUNT, player, true);
+ item.setEnchantLevel(enchant);
+ item.updateDatabase();
+ player.sendPacket(new ItemList(player, false));
+ player.broadcastUserInfo();
+ player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_S2_SUCCESSFULLY_ENCHANTED).addNumber(item.getEnchantLevel()).addItemName(item.getItemId()));
+ }
+ }
+
+ public static boolean conditionsclass(L2PcInstance player)
+ {
+ if (player.isSubClassActive())
+ {
+ player.sendMessage("You cannot change your Main Class while you're with Sub Class.");
+ return false;
+ }
+ else if (OlympiadManager.getInstance().isRegisteredInComp(player))
+ {
+ player.sendMessage("You cannot change your Main Class while you have been registered for olympiad match.");
+ return false;
+ }
+ else if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.CLASS_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean conditionsname(String newName, L2PcInstance player)
+ {
+ if (!newName.matches("^[a-zA-Z0-9]+$"))
+ {
+ player.sendMessage("Incorrect name. Please try again.");
+ return false;
+ }
+ else if (newName.equals(player.getName()))
+ {
+ player.sendMessage("Please, choose a different name.");
+ return false;
+ }
+ else if (CharNameTable.getInstance().getPlayerObjectId(newName) > 0)
+ {
+ player.sendMessage("The name " + newName + " already exists.");
+ return false;
+ }
+ else if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.NAME_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean conditions(String newPass, String repeatNewPass, L2PcInstance player)
+ {
+ if (newPass.length() < 3)
+ {
+ player.sendMessage("The new password is too short!");
+ return false;
+ }
+ else if (newPass.length() > 45)
+ {
+ player.sendMessage("The new password is too long!");
+ return false;
+ }
+ else if (!newPass.equals(repeatNewPass))
+ {
+ player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.PASSWORD_ENTERED_INCORRECT2));
+ return false;
+ }
+ else if (player.getInventory().getInventoryItemCount(Config.DONATE_ITEM, -1) < Config.PASSWORD_ITEM_COUNT)
+ {
+ player.sendMessage("You do not have enough Donate Coins.");
+ return false;
+ }
+ return true;
+ }
+
+ public void changePassword(String newPass, String repeatNewPass, L2PcInstance activeChar)
+ {
+ try (Connection con = L2DatabaseFactory.getInstance().getConnection(); PreparedStatement ps = con.prepareStatement("UPDATE accounts SET password=? WHERE login=?"))
+ {
+ byte[] newPassword = MessageDigest.getInstance("SHA").digest(newPass.getBytes("UTF-8"));
+
+ ps.setString(1, Base64.getEncoder().encodeToString(newPassword));
+ ps.setString(2, activeChar.getAccountName());
+ ps.executeUpdate();
+
+ activeChar.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.PASSWORD_ITEM_COUNT, activeChar, true);
+ activeChar.sendMessage("Congratulations! Your password has been changed. You will now be disconnected for security reasons. Please login again.");
+ ThreadPool.schedule(() -> activeChar.logout(false), 3000);
+ }
+ catch (Exception e)
+ {
+
+ }
+ }
+
+ public void teleportTo(String val, L2PcInstance activeChar, L2PcInstance target)
+ {
+ if (target.getObjectId() == activeChar.getObjectId())
+ activeChar.sendPacket(SystemMessageId.CANNOT_USE_ON_YOURSELF);
+
+ // Check if the attacker is not in the same party
+ if (!activeChar.getParty().getPartyMembers().contains(target))
+ {
+ activeChar.sendMessage("Your target Isn't in your party.");
+ return;
+ }
+ // Simple checks to avoid exploits
+ if (target.isInJail() || target.isInOlympiadMode() || target.isInDuel() || target.isFestivalParticipant() || (target.isInParty() && target.getParty().isInDimensionalRift()) || target.inObserverMode())
+ {
+ activeChar.sendMessage("Due to the current friend's status, the teleportation failed.");
+ return;
+ }
+ if (target.getClan() != null && CastleManager.getInstance().getCastleByOwner(target.getClan()) != null && CastleManager.getInstance().getCastleByOwner(target.getClan()).getSiege().isInProgress())
+ {
+ activeChar.sendMessage("As your friend is in siege, you can't go to him/her.");
+ return;
+ }
+ if (activeChar.getPvpFlag() > 0 || activeChar.getKarma() > 0)
+ {
+ activeChar.sendMessage("Go away! Flag or Pk player can not be teleported.");
+ return;
+ }
+ int x = target.getX();
+ int y = target.getY();
+ int z = target.getZ();
+
+ activeChar.getAI().setIntention(CtrlIntention.IDLE);
+ activeChar.doCast(SkillTable.getInstance().getInfo(2100, 1));
+ activeChar.sendPacket(new ExShowScreenMessage("You will be teleported to " + target.getName() + " in 5 Seconds!", 5000, 2, true));
+ ThreadPool.schedule(() -> activeChar.teleToLocation(x, y, z, 0), 5000);
+ activeChar.sendMessage("You have teleported to " + target.getName() + ".");
+ }
+
+ public void teleportToClan(String clan, L2PcInstance activeChar, L2PcInstance target)
+ {
+ if (target.getObjectId() == activeChar.getObjectId())
+ activeChar.sendPacket(SystemMessageId.CANNOT_USE_ON_YOURSELF);
+
+ // Check if the player is not in the same clan.
+ if (!activeChar.getClan().isMember(target.getObjectId()))
+ return;
+
+ // Simple checks to avoid exploits
+ if (target.isInJail() || target.isInOlympiadMode() || target.isInDuel() || target.isFestivalParticipant() || (target.isInParty() && target.getParty().isInDimensionalRift()) || target.inObserverMode())
+ {
+ activeChar.sendMessage("Due to the current clan member's status, the teleportation failed.");
+ return;
+ }
+ if (target.getClan() != null && CastleManager.getInstance().getCastleByOwner(target.getClan()) != null && CastleManager.getInstance().getCastleByOwner(target.getClan()).getSiege().isInProgress())
+ {
+ activeChar.sendMessage("As your clan member is in siege, you can't go to him/her.");
+ return;
+ }
+ if (activeChar.getPvpFlag() > 0 || activeChar.getKarma() > 0)
+ {
+ activeChar.sendMessage("Go away! Flag or Pk player can not be teleported.");
+ return;
+ }
+ int x = target.getX();
+ int y = target.getY();
+ int z = target.getZ();
+
+ activeChar.getAI().setIntention(CtrlIntention.IDLE);
+ activeChar.doCast(SkillTable.getInstance().getInfo(2100, 1));
+ activeChar.sendPacket(new ExShowScreenMessage("You will be teleported to " + target.getName() + " in 5 Seconds!", 5000, 2, true));
+ ThreadPool.schedule(() -> activeChar.teleToLocation(x, y, z, 0), 5000);
+ activeChar.sendMessage("You have teleported to " + target.getName() + ".");
+ }
+
+ public static void Classes(String command, final L2PcInstance player)
+ {
+ if (!conditionsclass(player))
+ return;
+
+ player.destroyItemByItemId("Consume", Config.DONATE_ITEM, Config.CLASS_ITEM_COUNT, player, true);
+ for (final L2Skill skill : player.getSkills().values())
+ player.removeSkill(skill);
+
+ String classes = command.substring(command.indexOf("_") + 1);
+ switch (classes)
+ {
+ case "duelist":
+ player.setClassId(88);
+ player.setBaseClass(88);
+ break;
+ case "dreadnought":
+ player.setClassId(89);
+ player.setBaseClass(89);
+ break;
+ case "phoenix":
+ player.setClassId(90);
+ player.setBaseClass(90);
+ break;
+ case "hell":
+ player.setClassId(91);
+ player.setBaseClass(91);
+ break;
+ case "sagittarius":
+ player.setClassId(92);
+ player.setBaseClass(92);
+ break;
+ case "adventurer":
+ player.setClassId(93);
+ player.setBaseClass(93);
+ break;
+ case "archmage":
+ player.setClassId(94);
+ player.setBaseClass(94);
+ break;
+ case "soultaker":
+ player.setClassId(95);
+ player.setBaseClass(95);
+ break;
+ case "arcana":
+ player.setClassId(96);
+ player.setBaseClass(96);
+ break;
+ case "cardinal":
+ player.setClassId(97);
+ player.setBaseClass(97);
+ break;
+ case "hierophant":
+ player.setClassId(98);
+ player.setBaseClass(98);
+ break;
+ case "evas":
+ player.setClassId(99);
+ player.setBaseClass(99);
+ break;
+ case "muse":
+ player.setClassId(100);
+ player.setBaseClass(100);
+ break;
+ case "windrider":
+ player.setClassId(101);
+ player.setBaseClass(101);
+ break;
+ case "sentinel":
+ player.setClassId(102);
+ player.setBaseClass(102);
+ break;
+ case "mystic":
+ player.setClassId(103);
+ player.setBaseClass(103);
+ break;
+ case "elemental":
+ player.setClassId(104);
+ player.setBaseClass(104);
+ break;
+ case "saint":
+ player.setClassId(105);
+ player.setBaseClass(105);
+ break;
+ case "templar":
+ player.setClassId(106);
+ player.setBaseClass(106);
+ break;
+ case "dancer":
+ player.setClassId(107);
+ player.setBaseClass(107);
+ break;
+ case "hunter":
+ player.setClassId(108);
+ player.setBaseClass(108);
+ break;
+ case "gsentinel":
+ player.setClassId(109);
+ player.setBaseClass(109);
+ break;
+ case "screamer":
+ player.setClassId(110);
+ player.setBaseClass(110);
+ break;
+ case "master":
+ player.setClassId(111);
+ player.setBaseClass(111);
+ break;
+ case "ssaint":
+ player.setClassId(112);
+ player.setBaseClass(112);
+ break;
+ case "titan":
+ player.setClassId(113);
+ player.setBaseClass(113);
+ break;
+ case "khavatari":
+ player.setClassId(114);
+ player.setBaseClass(114);
+ break;
+ case "domi":
+ player.setClassId(115);
+ player.setBaseClass(115);
+ break;
+ case "doom":
+ player.setClassId(116);
+ player.setBaseClass(116);
+ break;
+ case "fortune":
+ player.setClassId(117);
+ player.setBaseClass(117);
+ break;
+ case "maestro":
+ player.setClassId(118);
+ player.setBaseClass(118);
+ break;
+ }
+ player.store();
+ player.broadcastUserInfo();
+ player.sendSkillList();
+ player.giveAvailableSkills();
+ player.sendMessage("Your base class has been changed! You will Be Disconected in 5 Seconds!");
+ ThreadPool.schedule(() -> player.logout(false), 5000);
+ }
+
+ @Override
+ public String getHtmlPath(int npcId, int val)
+ {
+ String filename = "";
+
+ if (val == 0)
+ filename = "" + npcId;
+ else
+ filename = npcId + "-" + val;
+
+ return "data/html/mods/donateNpc/" + filename + ".htm";
+ }
+}
Index: java/net/sf/l2j/gameserver/network/clientpackets/AbstractEnchantPacket.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/AbstractEnchantPacket.java (revision 6)
+++ java/net/sf/l2j/gameserver/network/clientpackets/AbstractEnchantPacket.java (working copy)
@@ -18,6 +18,7 @@
import java.util.Map;
import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
import net.sf.l2j.gameserver.model.item.kind.Item;
import net.sf.l2j.gameserver.model.item.kind.Weapon;
@@ -59,7 +60,6 @@
if (!_isWeapon || (Config.ENCHANT_MAX_WEAPON > 0 && enchantItem.getEnchantLevel() >= Config.ENCHANT_MAX_WEAPON))
return false;
break;
-
case Item.TYPE2_SHIELD_ARMOR:
case Item.TYPE2_ACCESSORY:
if (_isWeapon || (Config.ENCHANT_MAX_ARMOR > 0 && enchantItem.getEnchantLevel() >= Config.ENCHANT_MAX_ARMOR))
@@ -107,9 +107,10 @@
* <li>full body armors has a chance of 1/1 for +4, 2/3 for +5, 1/3 for +6, ..., 1/17 for +20. If you've made a +20 armor, chance to make it +21 will be equal to zero (0%).</li>
* </ul>
* @param enchantItem : The item to enchant.
+ * @param player
* @return the enchant chance under double format (0.7 / 0.35 / 0.44324...).
*/
- public final double getChance(ItemInstance enchantItem)
+ public final double getChance(ItemInstance enchantItem, L2PcInstance player)
{
if (!isValid(enchantItem))
return -1;
@@ -122,16 +123,20 @@
// Armor formula : 0.66^(current-2), chance is lower and lower for each enchant.
if (enchantItem.isArmor())
- chance = Math.pow(Config.ENCHANT_CHANCE_ARMOR, (enchantItem.getEnchantLevel() - 2));
+ if (player.isVipStatus())
+ chance = Math.pow(Config.VIP_ENCHANT_CHANCE_ARMOR, (enchantItem.getEnchantLevel() - 2));
+ else
+ chance = Math.pow(Config.ENCHANT_CHANCE_ARMOR, (enchantItem.getEnchantLevel() - 2));
// Weapon formula is 70% for fighter weapon, 40% for mage weapon. Special rates after +14.
else if (enchantItem.isWeapon())
{
+ if (player.isVipStatus())
+ chance = (enchantItem.getEnchantLevel() > 14) ? Config.VIP_ENCHANT_CHANCE_WEAPON_15PLUS : Config.VIP_ENCHANT_CHANCE_WEAPON;
if (((Weapon) enchantItem.getItem()).isMagical())
chance = (enchantItem.getEnchantLevel() > 14) ? Config.ENCHANT_CHANCE_WEAPON_MAGIC_15PLUS : Config.ENCHANT_CHANCE_WEAPON_MAGIC;
else
chance = (enchantItem.getEnchantLevel() > 14) ? Config.ENCHANT_CHANCE_WEAPON_NONMAGIC_15PLUS : Config.ENCHANT_CHANCE_WEAPON_NONMAGIC;
}
-
return chance;
}
}
Index: java/net/sf/l2j/gameserver/handler/itemhandlers/VipStatusItem.java
===================================================================
--- java/net/sf/l2j/gameserver/handler/itemhandlers/VipStatusItem.java (nonexistent)
+++ java/net/sf/l2j/gameserver/handler/itemhandlers/VipStatusItem.java (working copy)
@@ -0,0 +1,57 @@
+/*
+ * 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 net.sf.l2j.gameserver.handler.itemhandlers;
+
+import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.handler.IItemHandler;
+import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminVipStatus;
+import net.sf.l2j.gameserver.model.actor.L2Playable;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
+import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.serverpackets.SocialAction;
+
+/**
+ * @author Baggos
+ */
+public class VipStatusItem implements IItemHandler
+{
+ @Override
+ public void useItem(L2Playable playable, ItemInstance item, boolean forceUse)
+ {
+ if (Config.ENABLE_VIP_ITEM)
+ {
+ if (!(playable instanceof L2PcInstance))
+ return;
+
+ L2PcInstance activeChar = (L2PcInstance) playable;
+ if (activeChar.isVipStatus())
+ activeChar.sendMessage("Your character has already VIP Status!");
+ else if (activeChar.isInOlympiadMode())
+ activeChar.sendPacket(SystemMessageId.YOU_ARE_NOT_AUTHORIZED_TO_DO_THAT);
+ else
+ {
+ AdminVipStatus.AddVipStatus(activeChar, activeChar, Config.VIP_DAYS);
+ activeChar.broadcastPacket(new SocialAction(activeChar, 16));
+ playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
+ }
+ }
+ }
+
+ public int getItemIds()
+ {
+ return Config.VIP_ITEM_ID;
+ }
+}
Index: java/net/sf/l2j/gameserver/model/actor/L2Attackable.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/L2Attackable.java (revision 6)
+++ java/net/sf/l2j/gameserver/model/actor/L2Attackable.java (working copy)
@@ -326,6 +326,12 @@
sp *= Config.CHAMPION_REWARDS;
}
+ if (attacker.isVipStatus())
+ {
+ exp *= Config.VIP_XP_SP_RATES;
+ sp *= Config.VIP_XP_SP_RATES;
+ }
+
exp *= 1 - penalty;
if (isOverhit() && _overhitAttacker != null && _overhitAttacker.getActingPlayer() != null && attacker == _overhitAttacker.getActingPlayer())
@@ -405,6 +411,12 @@
sp *= Config.CHAMPION_REWARDS;
}
+ if (attacker.isVipStatus())
+ {
+ exp *= Config.VIP_XP_SP_RATES;
+ sp *= Config.VIP_XP_SP_RATES;
+ }
+
exp *= partyMul;
sp *= partyMul;
@@ -766,11 +778,23 @@
// Applies Drop rates
if (drop.getItemId() == 57)
- dropChance *= Config.RATE_DROP_ADENA;
+ if (lastAttacker.isVipStatus())
+ dropChance *= Config.VIP_ADENA_RATES;
+ else
+ dropChance *= Config.RATE_DROP_ADENA;
else if (isSweep)
- dropChance *= Config.RATE_DROP_SPOIL;
+ if (lastAttacker.isVipStatus())
+ dropChance *= Config.VIP_SPOIL_RATES;
+ else
+ dropChance *= Config.RATE_DROP_SPOIL;
else
- dropChance *= isRaid() && !isRaidMinion() ? Config.RATE_DROP_ITEMS_BY_RAID : Config.RATE_DROP_ITEMS;
+ {
+ if (lastAttacker.isVipStatus())
+ dropChance *= isRaid() && !isRaidMinion() ? Config.VIP_RATE_DROP_ITEMS_BY_RAID : Config.VIP_DROP_RATES;
+ else
+ dropChance *= isRaid() && !isRaidMinion() ? Config.RATE_DROP_ITEMS_BY_RAID : Config.RATE_DROP_ITEMS;
+
+ }
if (isChampion())
dropChance *= Config.CHAMPION_REWARDS;
@@ -805,7 +829,7 @@
if (isChampion())
if (drop.getItemId() == 57 || (drop.getItemId() >= 6360 && drop.getItemId() <= 6362))
itemCount *= Config.CHAMPION_ADENAS_REWARDS;
-
+
if (itemCount > 0)
return new IntIntHolder(drop.getItemId(), itemCount);
@@ -824,7 +848,7 @@
{
if (categoryDrops == null)
return null;
-
+
// Get default drop chance for the category (that's the sum of chances for all items in the category)
// keep track of the base category chance as it'll be used later, if an item is drop from the category.
// for everything else, use the total "categoryDropChance"
@@ -855,7 +879,7 @@
DropData drop = categoryDrops.dropOne(isRaid() && !isRaidMinion());
if (drop == null)
return null;
-
+
// Now decide the quantity to drop based on the rates and penalties. To get this value
// simply divide the modified categoryDropChance by the base category chance. This
// results in a chance that will dictate the drops amounts: for each amount over 100
@@ -870,7 +894,12 @@
double dropChance = drop.getChance();
if (drop.getItemId() == 57)
- dropChance *= Config.RATE_DROP_ADENA;
+ if (lastAttacker.isVipStatus())
+ dropChance *= Config.VIP_ADENA_RATES;
+ else
+ dropChance *= Config.RATE_DROP_ADENA;
+ else if (lastAttacker.isVipStatus())
+ dropChance *= isRaid() && !isRaidMinion() ? Config.VIP_RATE_DROP_ITEMS_BY_RAID : Config.VIP_DROP_RATES;
else
dropChance *= isRaid() && !isRaidMinion() ? Config.RATE_DROP_ITEMS_BY_RAID : Config.RATE_DROP_ITEMS;
@@ -906,7 +935,7 @@
if (isChampion())
if (drop.getItemId() == 57 || (drop.getItemId() >= 6360 && drop.getItemId() <= 6362))
itemCount *= Config.CHAMPION_ADENAS_REWARDS;
-
+
if (itemCount > 0)
return new IntIntHolder(drop.getItemId(), itemCount);
}
@@ -927,7 +956,7 @@
for (L2Character atkChar : _attackByList)
if (atkChar.getLevel() > highestLevel)
highestLevel = atkChar.getLevel();
-
+
// According to official data (Prima), deep blue mobs are 9 or more levels below players
if (highestLevel - 9 >= getLevel())
return ((highestLevel - (getLevel() + 8)) * 9);
@@ -1456,7 +1485,7 @@
// Over-hit damage percentages are limited to 25% max
if (overhitPercentage > 25)
overhitPercentage = 25;
-
+
// Get the overhit exp bonus according to the above over-hit damage percentage
// (1/1 basis - 13% of over-hit damage, 13% of extra exp is given, and so on...)
double overhitExp = ((overhitPercentage / 100) * normalExp);
Index: java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java (revision 6)
+++ java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java (working copy)
@@ -17,6 +17,7 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.util.Calendar;
import java.util.logging.Level;
import net.sf.l2j.Config;
@@ -27,6 +28,7 @@
import net.sf.l2j.gameserver.datatables.GmListTable;
import net.sf.l2j.gameserver.datatables.MapRegionTable.TeleportWhereType;
import net.sf.l2j.gameserver.datatables.SkillTable.FrequentSkill;
+import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminVipStatus;
import net.sf.l2j.gameserver.instancemanager.ClanHallManager;
import net.sf.l2j.gameserver.instancemanager.CoupleManager;
import net.sf.l2j.gameserver.instancemanager.DimensionalRiftManager;
@@ -88,6 +90,36 @@
return;
}
+ int color = activeChar.isColor();
+ switch (color)
+ {
+ case 1:
+ activeChar.setColor(1);
+ activeChar.getAppearance().setNameColor(0x009900);
+ activeChar.broadcastUserInfo();
+ break;
+ case 2:
+ activeChar.setColor(2);
+ activeChar.getAppearance().setNameColor(0xff7f00);
+ activeChar.broadcastUserInfo();
+ break;
+ case 3:
+ activeChar.setColor(3);
+ activeChar.getAppearance().setNameColor(0xff00ff);
+ activeChar.broadcastUserInfo();
+ break;
+ case 4:
+ activeChar.setColor(4);
+ activeChar.getAppearance().setNameColor(0x00ffff);
+ activeChar.broadcastUserInfo();
+ break;
+ case 5:
+ activeChar.setColor(5);
+ activeChar.getAppearance().setNameColor(0x0099ff);
+ activeChar.broadcastUserInfo();
+ break;
+ }
+
final int objectId = activeChar.getObjectId();
if (activeChar.isGM())
@@ -231,6 +263,9 @@
activeChar.sendPacket(new EtcStatusUpdate(activeChar));
activeChar.sendSkillList();
+ if (activeChar.getMemos().getLong("TimeOfVip", 0) > 0)
+ onEnterVip(activeChar);
+
// Load quests.
try (Connection con = L2DatabaseFactory.getInstance().getConnection())
{
@@ -334,6 +369,19 @@
activeChar.sendPacket(ActionFailed.STATIC_PACKET);
}
+ private static void onEnterVip(L2PcInstance activeChar)
+ {
+ long now = Calendar.getInstance().getTimeInMillis();
+ long endDay = activeChar.getMemos().getLong("TimeOfVip");
+ if (now > endDay)
+ AdminVipStatus.RemoveVipStatus(activeChar);
+ else
+ {
+ activeChar.setVipStatus(true);
+ activeChar.broadcastUserInfo();
+ }
+ }
+
@Override
protected boolean triggersOnActionRequest()
{
Index: config/vip.properties
===================================================================
--- config/vip.properties (nonexistent)
+++ config/vip.properties (working copy)
@@ -0,0 +1,25 @@
+# ================================================
+# VIP System
+# ================================================
+# If True, player can got VIP Status by item.
+VipItemEnabled = True
+
+# Id of VIP Item.
+# Do not forget to add the item handler on xml/items 3481.
+# <set name="handler" val="VipStatusItem" />
+VipItemId = 3481
+
+# Days of VIP.
+VipDays = 10
+
+# Set Exp/Sp/Drop.
+VipExp/SpRates = 50
+VipAdenaDrop = 50
+VipSpoilRates = 50
+VipRaidDrop = 1
+VipDrop = 1
+
+# Set Enchant Chance.
+VipEnchantChanceArmor = 0.77
+VipEnchantChanceWeapon15Plus = 0.77
+VipEnchantChanceWeapon = 0.77
\ No newline at end of file
Index: java/net/sf/l2j/gameserver/handler/ItemHandler.java
===================================================================
--- java/net/sf/l2j/gameserver/handler/ItemHandler.java (revision 6)
+++ java/net/sf/l2j/gameserver/handler/ItemHandler.java (working copy)
@@ -43,6 +43,7 @@
import net.sf.l2j.gameserver.handler.itemhandlers.SpecialXMas;
import net.sf.l2j.gameserver.handler.itemhandlers.SpiritShot;
import net.sf.l2j.gameserver.handler.itemhandlers.SummonItems;
+import net.sf.l2j.gameserver.handler.itemhandlers.VipStatusItem;
import net.sf.l2j.gameserver.model.item.kind.EtcItem;
public class ItemHandler
@@ -82,6 +83,7 @@
registerItemHandler(new SoulCrystals());
registerItemHandler(new SpiritShot());
registerItemHandler(new SummonItems());
+ registerItemHandler(new VipStatusItem());
}
public void registerItemHandler(IItemHandler handler)
Index: java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java (revision 6)
+++ java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java (working copy)
@@ -239,6 +239,7 @@
import net.sf.l2j.gameserver.taskmanager.ItemsOnGroundTaskManager;
import net.sf.l2j.gameserver.taskmanager.PvpFlagTaskManager;
import net.sf.l2j.gameserver.taskmanager.ShadowItemTaskManager;
+import net.sf.l2j.gameserver.taskmanager.VipTimeTaskManager;
import net.sf.l2j.gameserver.taskmanager.WaterTaskManager;
import net.sf.l2j.gameserver.templates.skills.L2EffectFlag;
import net.sf.l2j.gameserver.templates.skills.L2EffectType;
@@ -314,8 +315,8 @@
private static final String DELETE_SKILL_SAVE = "DELETE FROM character_skills_save WHERE char_obj_id=? AND class_index=?";
private static final String INSERT_CHARACTER = "INSERT INTO characters (account_name,obj_Id,char_name,level,maxHp,curHp,maxCp,curCp,maxMp,curMp,face,hairStyle,hairColor,sex,exp,sp,karma,pvpkills,pkkills,clanid,race,classid,deletetime,cancraft,title,accesslevel,online,isin7sdungeon,clan_privs,wantspeace,base_class,nobless,power_grade,last_recom_date) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
- private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,face=?,hairStyle=?,hairColor=?,sex=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,pvpkills=?,pkkills=?,rec_have=?,rec_left=?,clanid=?,race=?,classid=?,deletetime=?,title=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,punish_level=?,punish_timer=?,nobless=?,power_grade=?,subpledge=?,last_recom_date=?,lvl_joined_academy=?,apprentice=?,sponsor=?,varka_ketra_ally=?,clan_join_expiry_time=?,clan_create_expiry_time=?,char_name=?,death_penalty_level=? WHERE obj_id=?";
- private static final String RESTORE_CHARACTER = "SELECT account_name, obj_Id, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, face, hairStyle, hairColor, sex, heading, x, y, z, exp, expBeforeDeath, sp, karma, pvpkills, pkkills, clanid, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, base_class, onlinetime, isin7sdungeon, punish_level, punish_timer, nobless, power_grade, subpledge, last_recom_date, lvl_joined_academy, apprentice, sponsor, varka_ketra_ally,clan_join_expiry_time,clan_create_expiry_time,death_penalty_level FROM characters WHERE obj_id=?";
+ private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,face=?,hairStyle=?,hairColor=?,sex=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,pvpkills=?,pkkills=?,rec_have=?,rec_left=?,clanid=?,race=?,classid=?,deletetime=?,title=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,punish_level=?,punish_timer=?,nobless=?,power_grade=?,subpledge=?,last_recom_date=?,lvl_joined_academy=?,apprentice=?,sponsor=?,varka_ketra_ally=?,clan_join_expiry_time=?,clan_create_expiry_time=?,char_name=?,death_penalty_level=?,color=? WHERE obj_id=?";
+ private static final String RESTORE_CHARACTER = "SELECT account_name, obj_Id, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, face, hairStyle, hairColor, sex, heading, x, y, z, exp, expBeforeDeath, sp, karma, pvpkills, pkkills, clanid, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, base_class, onlinetime, isin7sdungeon, punish_level, punish_timer, nobless, power_grade, subpledge, last_recom_date, lvl_joined_academy, apprentice, sponsor, varka_ketra_ally,clan_join_expiry_time,clan_create_expiry_time,death_penalty_level,color FROM characters WHERE obj_id=?";
private static final String RESTORE_CHAR_SUBCLASSES = "SELECT class_id,exp,sp,level,class_index FROM character_subclasses WHERE char_obj_id=? ORDER BY class_index ASC";
private static final String ADD_CHAR_SUBCLASS = "INSERT INTO character_subclasses (char_obj_id,class_id,exp,sp,level,class_index) VALUES (?,?,?,?,?,?)";
@@ -507,6 +508,9 @@
private int _deathPenaltyBuffLevel;
+ private int _isColor;
+ private boolean _isVipStatus;
+
private final AtomicInteger _charges = new AtomicInteger();
private ScheduledFuture<?> _chargeTask;
@@ -3969,7 +3973,7 @@
for (L2Character character : getKnownList().getKnownType(L2Character.class))
if (character.getFusionSkill() != null && character.getFusionSkill().getTarget() == this)
character.abortCast();
-
+
if (isInParty() && getParty().isInDimensionalRift())
getParty().getDimensionalRift().getDeadMemberList().add(this);
@@ -4283,6 +4287,8 @@
PvpFlagTaskManager.getInstance().remove(this);
GameTimeTaskManager.getInstance().remove(this);
ShadowItemTaskManager.getInstance().remove(this);
+ if (isVipStatus())
+ VipTimeTaskManager.getInstance().remove(this);
}
/**
@@ -5401,6 +5407,8 @@
player.setDeathPenaltyBuffLevel(rset.getInt("death_penalty_level"));
+ player.setColor(rset.getInt("color"));
+
// Set the x,y,z position of the L2PcInstance and make it invisible
player.setXYZInvisible(rset.getInt("x"), rset.getInt("y"), rset.getInt("z"));
@@ -5733,7 +5741,8 @@
statement.setLong(47, getClanCreateExpiryTime());
statement.setString(48, getName());
statement.setLong(49, getDeathPenaltyBuffLevel());
- statement.setInt(50, getObjectId());
+ statement.setInt(50, isColor());
+ statement.setInt(51, getObjectId());
statement.execute();
statement.close();
@@ -6700,7 +6709,7 @@
switch (sklTargetType)
{
- // Target the player if skill type is AURA, PARTY, CLAN or SELF
+ // Target the player if skill type is AURA, PARTY, CLAN or SELF
case TARGET_AURA:
case TARGET_FRONT_AURA:
case TARGET_BEHIND_AURA:
@@ -7964,7 +7973,7 @@
else
for (L2Skill s : SkillTable.getNobleSkills())
super.removeSkill(s); // Just Remove skills without deleting from Sql
-
+
_isNoble = val;
sendSkillList();
@@ -8296,7 +8305,7 @@
for (L2Character character : getKnownList().getKnownType(L2Character.class))
if (character.getFusionSkill() != null && character.getFusionSkill().getTarget() == this)
character.abortCast();
-
+
store();
_reuseTimeStamps.clear();
@@ -8440,6 +8449,9 @@
// Add to the GameTimeTask to keep inform about activity time.
GameTimeTaskManager.getInstance().add(this);
+ if (isVipStatus())
+ VipTimeTaskManager.getInstance().add(this);
+
// Teleport player if the Seven Signs period isn't the good one, or if the player isn't in a cabal.
if (isIn7sDungeon() && !isGM())
{
@@ -8917,7 +8929,7 @@
for (L2Character character : getKnownList().getKnownType(L2Character.class))
if (character.getFusionSkill() != null && character.getFusionSkill().getTarget() == this)
character.abortCast();
-
+
// Stop signets & toggles effects.
for (L2Effect effect : getAllEffects())
{
@@ -8969,7 +8981,7 @@
// If the L2PcInstance is a GM, remove it from the GM List
if (isGM())
GmListTable.getInstance().deleteGm(this);
-
+
// Check if the L2PcInstance is in observer mode to set its position to its position
// before entering in observer mode
if (inObserverMode())
@@ -9083,13 +9095,13 @@
case 7809: // yellow for beginners
case 8486: // prize-winning for beginners
return 0;
-
+
case 8485: // prize-winning luminous
case 8506: // green luminous
case 8509: // purple luminous
case 8512: // yellow luminous
return 2;
-
+
default:
return 1;
}
@@ -10410,6 +10422,26 @@
return _selectedBlocksList;
}
+ public int isColor()
+ {
+ return _isColor;
+ }
+
+ public int setColor(int colors)
+ {
+ return _isColor = colors;
+ }
+
+ public boolean isVipStatus()
+ {
+ return _isVipStatus;
+ }
+
+ public void setVipStatus(boolean vip)
+ {
+ _isVipStatus = vip;
+ }
+
@Override
public void broadcastRelationsChanges()
{
Index: java/net/sf/l2j/Config.java
===================================================================
--- java/net/sf/l2j/Config.java (revision 6)
+++ java/net/sf/l2j/Config.java (working copy)
@@ -51,6 +51,8 @@
public static final String PLAYERS_FILE = "./config/players.properties";
public static final String SERVER_FILE = "./config/server.properties";
public static final String SIEGE_FILE = "./config/siege.properties";
+ public static final String MULTI_FILE = "./config/multishop.properties";
+ public static final String VIP_FILE = "./config/vip.properties";
// --------------------------------------------------
// Clans settings
@@ -282,6 +284,28 @@
// NPCs / Monsters
// --------------------------------------------------
+ /** Multi Shop Manager */
+ public static int DONATE_ITEM;
+ public static int NOBL_ITEM_COUNT;
+ public static int SEX_ITEM_COUNT;
+ public static int PK_ITEM_COUNT;
+ public static int PK_CLEAN;
+ public static int CLAN_ITEM_COUNT;
+ public static int CLAN_REP_ITEM_COUNT;
+ public static int CLAN_REPS;
+ public static int AUGM_ITEM_COUNT;
+ public static int CLAN_SKILL_ITEM_COUNT;
+ public static int REC_ITEM_COUNT;
+ public static int PASSWORD_ITEM_COUNT;
+ public static int COLOR_ITEM_COUNT;
+ public static int NAME_ITEM_COUNT;
+ public static int ENCHANT_ITEM_COUNT;
+ public static int ENCHANT_MAX_VALUE;
+ public static int CLASS_ITEM_COUNT;
+ public static int VIP7_ITEM_COUNT;
+ public static int VIP15_ITEM_COUNT;
+ public static int VIP30_ITEM_COUNT;
+
/** Champion Mod */
public static int CHAMPION_FREQUENCY;
public static int CHAMP_MIN_LVL;
@@ -495,6 +519,19 @@
public static boolean STORE_SKILL_COOLTIME;
public static int BUFFS_MAX_AMOUNT;
+ /** Vip Settings */
+ public static boolean ENABLE_VIP_ITEM;
+ public static int VIP_ITEM_ID;
+ public static int VIP_DAYS;
+ public static int VIP_XP_SP_RATES;
+ public static int VIP_ADENA_RATES;
+ public static int VIP_SPOIL_RATES;
+ public static int VIP_RATE_DROP_ITEMS_BY_RAID;
+ public static int VIP_DROP_RATES;
+ public static double VIP_ENCHANT_CHANCE_ARMOR;
+ public static double VIP_ENCHANT_CHANCE_WEAPON_15PLUS;
+ public static double VIP_ENCHANT_CHANCE_WEAPON;
+
// --------------------------------------------------
// Server
// --------------------------------------------------
@@ -860,7 +897,7 @@
ALT_GAME_CASTLE_DUSK = events.getProperty("AltCastleForDusk", true);
ALT_FESTIVAL_MIN_PLAYER = events.getProperty("AltFestivalMinPlayer", 5);
ALT_MAXIMUM_PLAYER_CONTRIB = events.getProperty("AltMaxPlayerContrib", 1000000);
- ALT_FESTIVAL_MANAGER_START = events.getProperty("AltFestivalManagerStart", 120000);
+ ALT_FESTIVAL_MANAGER_START = events.getProperty("AltFestivalmultitart", 120000);
ALT_FESTIVAL_LENGTH = events.getProperty("AltFestivalLength", 1080000);
ALT_FESTIVAL_CYCLE_LENGTH = events.getProperty("AltFestivalCycleLength", 2280000);
ALT_FESTIVAL_FIRST_SPAWN = events.getProperty("AltFestivalFirstSpawn", 120000);
@@ -1082,6 +1119,55 @@
}
/**
+ * Load Multishop settings.
+ */
+ private static final void loadMultiShop()
+ {
+ final ExProperties multi = initProperties(MULTI_FILE);
+ DONATE_ITEM = multi.getProperty("DonateItemId", 57);
+ NOBL_ITEM_COUNT = multi.getProperty("NoblesseItemCount", 100);
+ SEX_ITEM_COUNT = multi.getProperty("SexItemCount", 100);
+ PK_ITEM_COUNT = multi.getProperty("PkItemCount", 100);
+ PK_CLEAN = multi.getProperty("PkCleanValue", 50);
+ CLAN_ITEM_COUNT = multi.getProperty("ClanItemCount", 100);
+ CLAN_REP_ITEM_COUNT = multi.getProperty("ClanRepsCount", 100);
+ CLAN_REPS = multi.getProperty("ClanReps", 20000);
+ AUGM_ITEM_COUNT = multi.getProperty("AugmentionItemCount", 100);
+ NOBL_ITEM_COUNT = multi.getProperty("ClanSkillsItemCount", 100);
+ REC_ITEM_COUNT = multi.getProperty("RecItemCount", 100);
+ PASSWORD_ITEM_COUNT = multi.getProperty("PasswordItemCount", 100);
+ COLOR_ITEM_COUNT = multi.getProperty("ColorItemCount", 100);
+ NAME_ITEM_COUNT = multi.getProperty("NameItemCount", 100);
+ ENCHANT_ITEM_COUNT = multi.getProperty("EnchantItemCount", 100);
+ ENCHANT_MAX_VALUE = multi.getProperty("MaxEnchantValue", 15);
+ CLASS_ITEM_COUNT = multi.getProperty("ClassItemCount", 100);
+ VIP7_ITEM_COUNT = multi.getProperty("Vip7DaysItemCount", 100);
+ VIP15_ITEM_COUNT = multi.getProperty("Vip15DaysItemCount", 100);
+ VIP30_ITEM_COUNT = multi.getProperty("Vip30DaysItemCount", 100);
+ }
+
+ /**
+ * Load Vip player settings.
+ */
+ private static final void loadVip()
+ {
+ final ExProperties vip = initProperties(VIP_FILE);
+ ENABLE_VIP_ITEM = vip.getProperty("VipItemEnabled", true);
+ VIP_ITEM_ID = vip.getProperty("VipItemId", 3481);
+ VIP_DAYS = vip.getProperty("VipDays", 5);
+
+ VIP_XP_SP_RATES = vip.getProperty("VipExp/SpRates", 1000);
+ VIP_ADENA_RATES = vip.getProperty("VipAdenaDrop", 1000);
+ VIP_SPOIL_RATES = vip.getProperty("VipSpoilRates", 1000);
+ VIP_RATE_DROP_ITEMS_BY_RAID = vip.getProperty("VipRaidDrop", 1);
+ VIP_DROP_RATES = vip.getProperty("VipDrop", 1);
+
+ VIP_ENCHANT_CHANCE_ARMOR = vip.getProperty("VipEnchantChanceArmor", 0.77);
+ VIP_ENCHANT_CHANCE_WEAPON_15PLUS = vip.getProperty("VipEnchantChanceWeapon15Plus", 0.77);
+ VIP_ENCHANT_CHANCE_WEAPON = vip.getProperty("VipEnchantChanceWeapon", 0.77);
+ }
+
+ /**
* Loads player settings.<br>
* Such as stats, inventory/warehouse, enchant, augmentation, karma, party, admin, petition, skill learn.
*/
@@ -1422,6 +1508,12 @@
// NPCs/monsters settings
loadNpcs();
+ // Mulishop settings
+ loadMultiShop();
+
+ // Vip settings
+ loadVip();
+
// players settings
loadPlayers();
Index: java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminVipStatus.java
===================================================================
--- java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminVipStatus.java (nonexistent)
+++ java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminVipStatus.java (working copy)
@@ -0,0 +1,134 @@
+/*
+ * 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 net.sf.l2j.gameserver.handler.admincommandhandlers;
+
+import java.util.StringTokenizer;
+import java.util.concurrent.TimeUnit;
+
+import net.sf.l2j.gameserver.handler.IAdminCommandHandler;
+import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.network.clientpackets.Say2;
+import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
+import net.sf.l2j.gameserver.network.serverpackets.SocialAction;
+import net.sf.l2j.gameserver.taskmanager.VipTimeTaskManager;
+
+/**
+ * @author Baggos
+ */
+public class AdminVipStatus implements IAdminCommandHandler
+{
+ private static String[] _adminCommands = new String[]
+ {
+ "admin_vipon",
+ "admin_vipoff"
+ };
+
+ @Override
+ public boolean useAdminCommand(String command, L2PcInstance activeChar)
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ String player = "";
+ int time = 1;
+ L2PcInstance target = null;
+ if (st.hasMoreTokens())
+ {
+ player = st.nextToken();
+ target = L2World.getInstance().getPlayer(player);
+ if (st.hasMoreTokens())
+ {
+ try
+ {
+ time = Integer.parseInt(st.nextToken());
+ }
+ catch (NumberFormatException nfe)
+ {
+ activeChar.sendMessage("Invalid number format used: " + nfe);
+ return false;
+ }
+ }
+ }
+ else if (activeChar.getTarget() != null && activeChar.getTarget() instanceof L2PcInstance)
+ target = (L2PcInstance) activeChar.getTarget();
+
+ if (command.startsWith("admin_vipon"))
+ {
+ if (target == null && player.equals(""))
+ {
+ activeChar.sendMessage("Usage: //vipon <char_name> [days]");
+ return false;
+ }
+ if (target != null)
+ {
+ AdminVipStatus.AddVipStatus(target, activeChar, time);
+ activeChar.sendMessage(target.getName() + " got VIP Status for " + time + " day(s).");
+ }
+ }
+ else if (command.startsWith("admin_vipoff"))
+ {
+ if (target == null && player.equals(""))
+ {
+ activeChar.sendMessage("Usage: //removevip <char_name>");
+ return false;
+ }
+ if (target != null)
+ {
+ if (target.isVipStatus())
+ {
+ AdminVipStatus.RemoveVipStatus(target);
+ activeChar.sendMessage(target.getName() + "'s VIP Status has been removed.");
+ }
+ else
+ activeChar.sendMessage("Player " +target.getName() + " is not an VIP.");
+ }
+ }
+ return true;
+ }
+
+ public static void AddVipStatus(L2PcInstance target, L2PcInstance player, int time)
+ {
+ target.broadcastPacket(new SocialAction(target, 16));
+ target.setVipStatus(true);
+ VipTimeTaskManager.getInstance().add(target);
+ long remainingTime = target.getMemos().getLong("TimeOfVip", 0);
+ if (remainingTime > 0)
+ {
+ target.getMemos().set("TimeOfVip", remainingTime + TimeUnit.DAYS.toMillis(time));
+ target.sendPacket(new CreatureSay(0, Say2.HERO_VOICE, "VIP Manager", "Dear " + player.getName() + ", your VIP status has been extended by " + time + " day(s)."));
+ }
+ else
+ {
+ target.getMemos().set("TimeOfVip", System.currentTimeMillis() + TimeUnit.DAYS.toMillis(time));
+ target.sendPacket(new CreatureSay(0, Say2.HERO_VOICE, "VIP Manager", "Dear " + player.getName() + ", you got VIP Status for " + time + " day(s)."));
+ target.broadcastUserInfo();
+ }
+ }
+
+ public static void RemoveVipStatus(L2PcInstance target)
+ {
+ VipTimeTaskManager.getInstance().remove(target);
+ target.getMemos().set("TimeOfVip", 0);
+ target.setVipStatus(false);
+ target.broadcastPacket(new SocialAction(target, 13));
+ target.broadcastUserInfo();
+ }
+
+ @Override
+ public String[] getAdminCommandList()
+ {
+ return _adminCommands;
+ }
+}
Index: config/multishop.properties
===================================================================
--- config/multishop.properties (nonexistent)
+++ config/multishop.properties (working copy)
@@ -0,0 +1,41 @@
+#=============================================================
+# Multi Shop Npc Manager ID 50008
+#=============================================================
+# Add the Item ID for Donate Coin
+DonateItemId = 57
+
+# Bellow you can add the price of Donate Coins
+# Make your character Noblesse
+NoblesseItemCount = 100
+# Change the Gender of the player
+SexItemCount = 100
+# Clean Characters PKs.
+PkItemCount = 100
+# How much Pk for clean?
+PkCleanValue = 50
+# Level up the player clan
+ClanItemCount = 100
+# Give clan reps to the clan
+ClanRepsCount = 100
+ClanReps = 20000
+# Add augment skills
+AugmentionItemCount = 100
+# Add Full clan skills
+ClanSkillsItemCount = 100
+# Give full recs to players
+RecItemCount = 100
+# Change the password
+PasswordItemCount = 100
+# Change the name color
+ColorItemCount = 100
+# Change the player name
+NameItemCount = 100
+# Full enchant Items
+EnchantItemCount = 100
+MaxEnchantValue = 15
+# Change the Main class of the players
+ClassItemCount = 100
+# Set price for Vip Days
+Vip7DaysItemCount = 100
+Vip15DaysItemCount = 100
+Vip30DaysItemCount = 100
\ No newline at end of file
Index: java/net/sf/l2j/gameserver/taskmanager/VipTimeTaskManager.java
===================================================================
--- java/net/sf/l2j/gameserver/taskmanager/VipTimeTaskManager.java (nonexistent)
+++ java/net/sf/l2j/gameserver/taskmanager/VipTimeTaskManager.java (working copy)
@@ -0,0 +1,75 @@
+/*
+ * 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 net.sf.l2j.gameserver.taskmanager;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import net.sf.l2j.commons.concurrent.ThreadPool;
+import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminVipStatus;
+import net.sf.l2j.gameserver.model.actor.L2Character;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author Baggos
+ */
+public class VipTimeTaskManager implements Runnable
+{
+ private final Map<L2PcInstance, Long> _players = new ConcurrentHashMap<>();
+
+ protected VipTimeTaskManager()
+ {
+ // Run task each 10 second.
+ ThreadPool.scheduleAtFixedRate(this, 10000, 10000);
+ }
+
+ public final void add(L2PcInstance player)
+ {
+ _players.put(player, System.currentTimeMillis());
+ }
+
+ public final void remove(L2Character player)
+ {
+ _players.remove(player);
+ }
+
+ @Override
+ public final void run()
+ {
+ if (_players.isEmpty())
+ return;
+
+ for (Map.Entry<L2PcInstance, Long> entry : _players.entrySet())
+ {
+ final L2PcInstance player = entry.getKey();
+
+ if (player.getMemos().getLong("TimeOfVip") < System.currentTimeMillis())
+ {
+ AdminVipStatus.RemoveVipStatus(player);
+ remove(player);
+ }
+ }
+ }
+
+ public static final VipTimeTaskManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final VipTimeTaskManager _instance = new VipTimeTaskManager();
+ }
+}
Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java (revision 6)
+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java (working copy)
@@ -25,6 +25,7 @@
import net.sf.l2j.gameserver.model.L2Object;
import net.sf.l2j.gameserver.model.L2World;
import net.sf.l2j.gameserver.model.actor.L2Npc;
+import net.sf.l2j.gameserver.model.actor.instance.L2MultiShopInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2OlympiadManagerInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.entity.Hero;
@@ -162,6 +163,8 @@
if (heroid > 0)
Hero.getInstance().showHeroDiary(activeChar, heroclass, heroid, heropage);
}
+ else if (_command.startsWith("base"))
+ L2MultiShopInstance.Classes(_command, activeChar);
else if (_command.startsWith("arenachange")) // change
{
final boolean isManager = activeChar.getCurrentFolkNPC() instanceof L2OlympiadManagerInstance;
Index: java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java
===================================================================
--- java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java (revision 6)
+++ java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java (working copy)
@@ -62,6 +62,7 @@
import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminSpawn;
import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminTarget;
import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminTeleport;
+import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminVipStatus;
import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminZone;
public class AdminCommandHandler
@@ -121,6 +122,7 @@
registerAdminCommandHandler(new AdminTarget());
registerAdminCommandHandler(new AdminTeleport());
registerAdminCommandHandler(new AdminZone());
+ registerAdminCommandHandler(new AdminVipStatus());
}
public void registerAdminCommandHandler(IAdminCommandHandler handler)
#P aCis_datapackk
Index: data/xml/skills/2100-2199.xml
===================================================================
--- data/xml/skills/2100-2199.xml (revision 6)
+++ data/xml/skills/2100-2199.xml (working copy)
@@ -1,8 +1,8 @@
<?xml version='1.0' encoding='utf-8'?>
<list>
- <skill id="2100" levels="1" name="Escape: 1 second">
+ <skill id="2100" levels="1" name="Escape: 5 second">
<set name="target" val="TARGET_SELF" />
- <set name="hitTime" val="1000" />
+ <set name="hitTime" val="5000" />
<set name="staticHitTime" val="true" />
<set name="skillType" val="RECALL" />
<set name="operateType" val="OP_ACTIVE" />
Index: data/xml/npcs/MultiShop.xml
===================================================================
--- data/xml/npcs/MultiShop.xml (nonexistent)
+++ data/xml/npcs/MultiShop.xml (working copy)
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<list>
+ <npc id="50091" idTemplate="30540" name="MULTI SHOP" title="L2jNetwork.com">
+ <set name="level" val="70"/>
+ <set name="radius" val="8"/>
+ <set name="height" val="20.5"/>
+ <set name="rHand" val="0"/>
+ <set name="lHand" val="0"/>
+ <set name="type" val="L2MultiShop"/>
+ <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="295.91597"/>
+ <set name="mAtk" val="470.40463"/>
+ <set name="mDef" val="216.53847"/>
+ <set name="crit" val="4"/>
+ <set name="atkSpd" val="253"/>
+ <set name="str" val="40"/>
+ <set name="int" val="21"/>
+ <set name="dex" val="30"/>
+ <set name="wit" val="20"/>
+ <set name="con" val="43"/>
+ <set name="men" val="20"/>
+ <set name="corpseTime" val="7"/>
+ <set name="walkSpd" val="50"/>
+ <set name="runSpd" val="120"/>
+ <set name="dropHerbGroup" val="0"/>
+ <set name="attackRange" val="40"/>
+ <ai type="DEFAULT" ssCount="0" ssRate="0" spsCount="0" spsRate="0" aggro="0" canMove="true" seedable="false"/>
+ <skills>
+ <skill id="4045" level="1"/>
+ <skill id="4416" level="14"/>
+ </skills>
+ </npc>
+</list>
\ No newline at end of file
Index: data/html/mods/donateNpc/50091-2.htm
===================================================================
--- data/html/mods/donateNpc/50091-2.htm (nonexistent)
+++ data/html/mods/donateNpc/50091-2.htm (working copy)
@@ -0,0 +1,77 @@
+<html>
+<body>
+<title>Main Class Changer</title>
+<center>
+
+<table border="1" width="296" height="65" bgcolor="000000">
+<tr>
+<td width=99 align=center>Change the main class of your character!<br1>
+You cannot change your class while:<br1>
+You're with sub class or olympiad register.</td>
+</tr>
+</table>
+<br>
+
+<center><button value="Duelist" action="bypass -h base_duelist" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Dreadnought" action="bypass -h base_dreadnought" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Phoenix Knight" action="bypass -h base_phoenix" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Hell Knight" action="bypass -h base_hell" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Sagittarius" action="bypass -h base_sagittarius" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Adventurer" action="bypass -h base_adventurer" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Archmage" action="bypass -h base_archmage" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Soultaker" action="bypass -h base_soultaker" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Arcana Lord" action="bypass -h base_arcana" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Cardinal" action="bypass -h base_cardinal" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Hierophant" action="bypass -h base_hierophant" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Evas Templar" action="bypass -h base_evas" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Sword Muse" action="bypass -h base_muse" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Wind Rider" action="bypass -h base_windrider" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Moonlight Sentinel" action="bypass -h base_sentinel" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Mystic Muse" action="bypass -h base_mystic" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Elemental Master" action="bypass -h base_elemental" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Evas Saint" action="bypass -h base_saint" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Shillien Templar" action="bypass -h base_templar" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Spectral Dancer" action="bypass -h base_dancer" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Ghost Hunter" action="bypass -h base_hunter" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Ghost Sentinel" action="bypass -h base_gsentinel" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Storm Screamer" action="bypass -h base_screamer" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Spectral Master" action="bypass -h base_master" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Shillien Saint" action="bypass -h base_ssaint" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Titan" action="bypass -h base_titan" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Grand Khavatari" action="bypass -h base_khavatari" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Dominator" action="bypass -h base_domi" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Doomcryer" action="bypass -h base_doom" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Fortune Seeker" action="bypass -h base_fortune" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Maestro" action="bypass -h base_maestro" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+
+</body></html>
\ No newline at end of file
Index: data/html/mods/donateNpc/50091.htm
===================================================================
--- data/html/mods/donateNpc/50091.htm (nonexistent)
+++ data/html/mods/donateNpc/50091.htm (working copy)
@@ -0,0 +1,150 @@
+<html>
+<title>
+Donate Manager
+</title>
+<body>
+<br>
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+ <center><button value="" action="bypass -h npc_%objectId%_donate $dona" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill0434">
+
+</td>
+<td fixwidth=250>
+<center><font color=F2F5A9>Character Services:</font>
+ <center><combobox width=120 height=17 var="dona" list=Noblesse;ChangeSex;CleanPk;FullRec;ChangeClass;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42><br>
+ <center><button value="" action="bypass -h npc_%objectId%_clan $clan" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill0391">
+
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Clan Services:</font>
+ <center><combobox width=120 height=17 var="clan" list=ClanLevel;ClanRep_20k;ClanSkills
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+ <center><button value="" action="bypass -h npc_%objectId%_siege $siege" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill0216">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Siege Services:</font>
+ <center><combobox width=120 height=17 var="siege" list=Gludio;Dion;Giran;Oren;Aden;Innadril;Goddard;Rune;Schuttgart;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+ <center><button value="" action="bypass -h npc_%objectId%_active $active" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill3123">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Augment Services [Active]:</font>
+ <center><combobox width=120 height=17 var="active" list=Might;Empower;DuelMight;Shield;MagicBarrier;WildMagic;Focus;BattleRoad;SolarFlare;Guidance;BlessedBody;Agility;Heal;HydroBlast;AuraFlare;Hurricane;ReflectDamage;Prominence;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+ <center><button value="" action="bypass -h npc_%objectId%_passive $passive" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill3238">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Augment Services [Passive]:</font>
+ <center><combobox width=120 height=17 var="passive" list=Empower;DuelMight;Might;Shield;MagicBarrier;Agility;Guidance;Focus;WildMagic;ReflectDamage;Prayer;Clarity;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<center><button action="bypass -h npc_%objectId%_color $color" value="" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill0106">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Change Color:</font>
+ <center><combobox width=120 height=17 var="color" list=Green;Blue;Purple;Yellow;Gold;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<center><button value="" action="bypass -h npc_%objectId%_vip $vip" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill0212">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Vip Services:</font>
+ <center><combobox width=120 height=17 var="vip" list=Vip7Days;Vip15Days;Vip30Days;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+</td>
+<td fixwidth=250>
+<br>
+<center><a action="bypass -h npc_%objectId%_Chat 1">Page 2</a></center>
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=22 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=300 height=10>
+</td>
+</tr>
+</table>
+</body></html>
\ No newline at end of file
Index: data/html/mods/donateNpc/50091-1.htm
===================================================================
--- data/html/mods/donateNpc/50091-1.htm (nonexistent)
+++ data/html/mods/donateNpc/50091-1.htm (working copy)
@@ -0,0 +1,115 @@
+<html>
+<title>
+Donate Manager
+</title>
+<body>
+<br>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<button action="bypass -h npc_%objectId%_partytp $val" value="" value="" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill1429">
+</td>
+<td fixwidth=250>
+<center><font color=F2F5A9>Teleport to your party member:</font>
+<center><edit var="val" width=120></td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<button action="bypass -h npc_%objectId%_teleport $clan" value="" value="" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill1429">
+</td>
+<td fixwidth=250>
+<center><font color=F2F5A9>Teleport to your Clan member:</font>
+<center><edit var="clan" width=120></td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<button action="bypass -h npc_%objectId%_name $newName" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill1430">
+</td>
+<td fixwidth=250>
+<center><font color=F2F5A9>Change your character name:</font>
+<center><edit var="newName" width=120></td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<button action="bypass -h npc_%objectId%_enchant $ench" value="" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill1400">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Enchant Services [Max]:</font>
+ <center><combobox width=120 height=17 var="ench" list=Tattoo;Weapon;Helmet;Boots;Gloves;Chest;Legs;Shield;Necklace;R-Ring;L-Ring;R-Earring;L-Earring;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<button action="bypass -h npc_%objectId%_password $newPass $repeatNewPass" value="" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill1409">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Change Password:</font>
+<center><edit var="newPass" width=120>
+<center><edit var="repeatNewPass" width=120></td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=20 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=300 height=30>
+</td>
+</tr>
+</table>
+
+<table width=300 height=20 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=300 height=30>
+</td>
+</tr>
+</table>
+
+<table width=300 height=20 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=300 height=45>
+</td>
+</tr>
+</table>
+
+</body></html>
\ No newline at end of file
Index: data/html/mods/donateNpc/50091-2.htm
===================================================================
--- data/html/mods/donateNpc/50091-2.htm (nonexistent)
+++ data/html/mods/donateNpc/50091-2.htm (working copy)
@@ -0,0 +1,77 @@
+<html>
+<body>
+<title>Main Class Changer</title>
+<center>
+
+<table border="1" width="296" height="65" bgcolor="000000">
+<tr>
+<td width=99 align=center>Change the main class of your character!<br1>
+You cannot change your class while:<br1>
+You're with sub class or olympiad register.</td>
+</tr>
+</table>
+<br>
+
+<center><button value="Duelist" action="bypass -h base_duelist" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Dreadnought" action="bypass -h base_dreadnought" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Phoenix Knight" action="bypass -h base_phoenix" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Hell Knight" action="bypass -h base_hell" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Sagittarius" action="bypass -h base_sagittarius" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Adventurer" action="bypass -h base_adventurer" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Archmage" action="bypass -h base_archmage" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Soultaker" action="bypass -h base_soultaker" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Arcana Lord" action="bypass -h base_arcana" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Cardinal" action="bypass -h base_cardinal" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Hierophant" action="bypass -h base_hierophant" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Evas Templar" action="bypass -h base_evas" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Sword Muse" action="bypass -h base_muse" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Wind Rider" action="bypass -h base_windrider" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Moonlight Sentinel" action="bypass -h base_sentinel" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Mystic Muse" action="bypass -h base_mystic" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Elemental Master" action="bypass -h base_elemental" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Evas Saint" action="bypass -h base_saint" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Shillien Templar" action="bypass -h base_templar" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Spectral Dancer" action="bypass -h base_dancer" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Ghost Hunter" action="bypass -h base_hunter" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Ghost Sentinel" action="bypass -h base_gsentinel" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Storm Screamer" action="bypass -h base_screamer" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Spectral Master" action="bypass -h base_master" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Shillien Saint" action="bypass -h base_ssaint" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Titan" action="bypass -h base_titan" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Grand Khavatari" action="bypass -h base_khavatari" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Dominator" action="bypass -h base_domi" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Doomcryer" action="bypass -h base_doom" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Fortune Seeker" action="bypass -h base_fortune" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+<br>
+<center><button value="Maestro" action="bypass -h base_maestro" width=134 height=21 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3">
+
+</body></html>
\ No newline at end of file
Index: data/html/mods/donateNpc/50091.htm
===================================================================
--- data/html/mods/donateNpc/50091.htm (nonexistent)
+++ data/html/mods/donateNpc/50091.htm (working copy)
@@ -0,0 +1,150 @@
+<html>
+<title>
+Donate Manager
+</title>
+<body>
+<br>
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+ <center><button value="" action="bypass -h npc_%objectId%_donate $dona" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill0434">
+
+</td>
+<td fixwidth=250>
+<center><font color=F2F5A9>Character Services:</font>
+ <center><combobox width=120 height=17 var="dona" list=Noblesse;ChangeSex;CleanPk;FullRec;ChangeClass;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42><br>
+ <center><button value="" action="bypass -h npc_%objectId%_clan $clan" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill0391">
+
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Clan Services:</font>
+ <center><combobox width=120 height=17 var="clan" list=ClanLevel;ClanRep_20k;ClanSkills
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+ <center><button value="" action="bypass -h npc_%objectId%_siege $siege" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill0216">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Siege Services:</font>
+ <center><combobox width=120 height=17 var="siege" list=Gludio;Dion;Giran;Oren;Aden;Innadril;Goddard;Rune;Schuttgart;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+ <center><button value="" action="bypass -h npc_%objectId%_active $active" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill3123">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Augment Services [Active]:</font>
+ <center><combobox width=120 height=17 var="active" list=Might;Empower;DuelMight;Shield;MagicBarrier;WildMagic;Focus;BattleRoad;SolarFlare;Guidance;BlessedBody;Agility;Heal;HydroBlast;AuraFlare;Hurricane;ReflectDamage;Prominence;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+ <center><button value="" action="bypass -h npc_%objectId%_passive $passive" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill3238">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Augment Services [Passive]:</font>
+ <center><combobox width=120 height=17 var="passive" list=Empower;DuelMight;Might;Shield;MagicBarrier;Agility;Guidance;Focus;WildMagic;ReflectDamage;Prayer;Clarity;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<center><button action="bypass -h npc_%objectId%_color $color" value="" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill0106">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Change Color:</font>
+ <center><combobox width=120 height=17 var="color" list=Green;Blue;Purple;Yellow;Gold;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<center><button value="" action="bypass -h npc_%objectId%_vip $vip" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill0212">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Vip Services:</font>
+ <center><combobox width=120 height=17 var="vip" list=Vip7Days;Vip15Days;Vip30Days;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+</td>
+<td fixwidth=250>
+<br>
+<center><a action="bypass -h npc_%objectId%_Chat 1">Page 2</a></center>
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=22 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=300 height=10>
+</td>
+</tr>
+</table>
+</body></html>
\ No newline at end of file
Index: sql/characters.sql
===================================================================
--- sql/characters.sql (revision 6)
+++ sql/characters.sql (working copy)
@@ -54,6 +54,7 @@
`clan_join_expiry_time` BIGINT UNSIGNED NOT NULL DEFAULT 0,
`clan_create_expiry_time` BIGINT UNSIGNED NOT NULL DEFAULT 0,
`death_penalty_level` SMALLINT UNSIGNED NOT NULL DEFAULT 0,
+ `color` SMALLINT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (obj_Id),
KEY `clanid` (`clanid`)
);
\ No newline at end of file
Index: data/html/mods/donateNpc/50091-1.htm
===================================================================
--- data/html/mods/donateNpc/50091-1.htm (nonexistent)
+++ data/html/mods/donateNpc/50091-1.htm (working copy)
@@ -0,0 +1,115 @@
+<html>
+<title>
+Donate Manager
+</title>
+<body>
+<br>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<button action="bypass -h npc_%objectId%_partytp $val" value="" value="" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill1429">
+</td>
+<td fixwidth=250>
+<center><font color=F2F5A9>Teleport to your party member:</font>
+<center><edit var="val" width=120></td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<button action="bypass -h npc_%objectId%_teleport $clan" value="" value="" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill1429">
+</td>
+<td fixwidth=250>
+<center><font color=F2F5A9>Teleport to your Clan member:</font>
+<center><edit var="clan" width=120></td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<button action="bypass -h npc_%objectId%_name $newName" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill1430">
+</td>
+<td fixwidth=250>
+<center><font color=F2F5A9>Change your character name:</font>
+<center><edit var="newName" width=120></td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<button action="bypass -h npc_%objectId%_enchant $ench" value="" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill1400">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Enchant Services [Max]:</font>
+ <center><combobox width=120 height=17 var="ench" list=Tattoo;Weapon;Helmet;Boots;Gloves;Chest;Legs;Shield;Necklace;R-Ring;L-Ring;R-Earring;L-Earring;
+</td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+
+<table width=300 height=32 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=32 height=42>
+<button action="bypass -h npc_%objectId%_password $newPass $repeatNewPass" value="" width=32 height=32 back="L2UI_CH3.Minimap.mapbutton_zoomin1" fore="icon.skill1409">
+</td>
+<td fixwidth=250>
+<br>
+<center><font color=F2F5A9>Change Password:</font>
+<center><edit var="newPass" width=120>
+<center><edit var="repeatNewPass" width=120></td>
+<td fixwidth=50>
+</td>
+</tr>
+</table>
+
+<table width=300 height=20 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=300 height=30>
+</td>
+</tr>
+</table>
+
+<table width=300 height=20 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=300 height=30>
+</td>
+</tr>
+</table>
+
+<table width=300 height=20 bgcolor=000000>
+<tr>
+<td fixwidth=5>
+</td>
+<td fixwidth=300 height=45>
+</td>
+</tr>
+</table>
+
+</body></html>
\ No newline at end of file