### Eclipse Workspace Patch 1.0
#P aCis_gameserver
Index: java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java
===================================================================
--- java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java (revision 5)
+++ java/net/sf/l2j/gameserver/handler/AdminCommandHandler.java (working copy)
@@ -63,6 +63,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
@@ -123,6 +124,7 @@
registerAdminCommandHandler(new AdminTarget());
registerAdminCommandHandler(new AdminTeleport());
registerAdminCommandHandler(new AdminZone());
+ registerAdminCommandHandler(new AdminVipStatus());
}
public void registerAdminCommandHandler(IAdminCommandHandler handler)
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.
+#
+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/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 .
+ */
+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.World;
+import net.sf.l2j.gameserver.model.actor.instance.Player;
+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, Player activeChar)
+ {
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+ String player = "";
+ int time = 1;
+ Player target = null;
+ if (st.hasMoreTokens())
+ {
+ player = st.nextToken();
+ target = World.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 Player)
+ target = (Player) activeChar.getTarget();
+
+ if (command.startsWith("admin_vipon"))
+ {
+ if (target == null && player.equals(""))
+ {
+ activeChar.sendMessage("Usage: //vipon [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 ");
+ 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(Player target, Player 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(Player 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: 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 .
+ */
+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.instance.Player;
+
+/**
+ * @author Baggos
+ */
+public class VipTimeTaskManager implements Runnable
+{
+ private final Map _players = new ConcurrentHashMap<>();
+
+ protected VipTimeTaskManager()
+ {
+ // Run task each 10 second.
+ ThreadPool.scheduleAtFixedRate(this, 10000, 10000);
+ }
+
+ public final void add(Player player)
+ {
+ _players.put(player, System.currentTimeMillis());
+ }
+
+ public final void remove(Player player)
+ {
+ _players.remove(player);
+ }
+
+ @Override
+ public final void run()
+ {
+ if (_players.isEmpty())
+ return;
+
+ for (Map.Entry entry : _players.entrySet())
+ {
+ final Player 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/Config.java
===================================================================
--- java/net/sf/l2j/Config.java (revision 5)
+++ java/net/sf/l2j/Config.java (working copy)
@@ -49,10 +49,26 @@
public static final String LOGIN_CONFIGURATION_FILE = "./config/loginserver.properties";
public static final String NPCS_FILE = "./config/npcs.properties";
public static final String PLAYERS_FILE = "./config/players.properties";
+ public static final String VIP_FILE = "./config/vip.properties";
public static final String SERVER_FILE = "./config/server.properties";
public static final String SIEGE_FILE = "./config/siege.properties";
public static final void loadGameServer()
{
_log.info("Loading gameserver configuration files.");
// clans settings
loadClans();
+ // Vip settings
+ loadVip();
// --------------------------------------------------
+ // 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;
+
+ // --------------------------------------------------
// Clans settings
// --------------------------------------------------
@@ -687,6 +703,22 @@
MAX_MONSTER_ANIMATION = npcs.getProperty("MaxMonsterAnimation", 40);
}
/**
* Loads player settings.
* Such as stats, inventory/warehouse, enchant, augmentation, karma, party, admin, petition, skill learn.
*/
+ private static final void loadVip()
+ {
+ // VIP settings
+ 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);
+
+
+ }
+
private static final void loadPlayers()
{
Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java (revision 5)
+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestEnchantItem.java (working copy)
@@ -111,7 +111,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/network/clientpackets/AbstractEnchantPacket.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/AbstractEnchantPacket.java (revision 5)
+++ 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.Player;
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 @@
*
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%).
*
* @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, Player 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/ItemHandler.java
===================================================================
--- java/net/sf/l2j/gameserver/handler/ItemHandler.java (revision 5)
+++ 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/Player.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/instance/Player.java (revision 5)
+++ java/net/sf/l2j/gameserver/model/actor/instance/Player.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;
@@ -586,6 +587,7 @@
private volatile int _clientHeading;
private int _mailPosition;
+ private boolean _isVipStatus;
private static final int FALLING_VALIDATION_DELAY = 10000;
private volatile long _fallingTimestamp = 0;
@@ -4084,7 +4086,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);
@@ -4395,6 +4397,8 @@
PvpFlagTaskManager.getInstance().remove(this);
GameTimeTaskManager.getInstance().remove(this);
ShadowItemTaskManager.getInstance().remove(this);
+ if (isVipStatus())
+ VipTimeTaskManager.getInstance().remove(this);
}
/**
@@ -6890,7 +6894,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:
@@ -8150,7 +8154,7 @@
else
for (L2Skill s : SkillTable.getNobleSkills())
super.removeSkill(s); // Just Remove skills without deleting from Sql
-
+
_noble = val;
sendSkillList();
@@ -8496,7 +8500,7 @@
for (L2Character character : getKnownList().getKnownType(L2Character.class))
if (character.getFusionSkill() != null && character.getFusionSkill().getTarget() == this)
character.abortCast();
-
+
store();
_reuseTimeStamps.clear();
@@ -8631,6 +8635,8 @@
// 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())
@@ -9113,7 +9119,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())
{
@@ -9170,7 +9176,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())
@@ -9285,13 +9291,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;
}
@@ -10198,6 +10204,16 @@
public final int getClientY()
{
return _clientY;
}
+ public boolean isVipStatus()
+ {
+ return _isVipStatus;
+ }
+
+ public void setVipStatus(boolean vip)
+ {
+ _isVipStatus = vip;
+ }
+
public final int getClientZ()
{
return _clientZ;
}
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 .
+ */
+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.Playable;
+import net.sf.l2j.gameserver.model.actor.instance.Player;
+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(Playable playable, ItemInstance item, boolean forceUse)
+ {
+ if (Config.ENABLE_VIP_ITEM)
+ {
+ if (!(playable instanceof Player))
+ return;
+
+ Player activeChar = (Player) 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/Attackable.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/Attackable.java (revision 5)
+++ java/net/sf/l2j/gameserver/model/actor/Attackable.java (working copy)
@@ -340,6 +340,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())
@@ -419,6 +425,12 @@
sp *= Config.CHAMPION_REWARDS;
}
+ if (attacker.isVipStatus())
+ {
+ exp *= Config.VIP_XP_SP_RATES;
+ sp *= Config.VIP_XP_SP_RATES;
+ }
+
exp *= partyMul;
sp *= partyMul;
@@ -793,11 +805,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;
@@ -832,7 +856,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);
@@ -851,7 +875,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"
@@ -882,7 +906,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
@@ -897,7 +921,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;
@@ -933,7 +962,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);
}
@@ -954,7 +983,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);
@@ -1515,7 +1544,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 5)
+++ java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java (working copy)
@@ -31,6 +31,7 @@
import net.sf.l2j.gameserver.model.L2Clan.SubPledge;
import net.sf.l2j.gameserver.model.World;
import net.sf.l2j.gameserver.model.actor.instance.Player;
+import net.sf.l2j.gameserver.model.actor.instance.L2VipInstance;
import net.sf.l2j.gameserver.model.base.Race;
import net.sf.l2j.gameserver.model.entity.ClanHall;
import net.sf.l2j.gameserver.model.entity.Couple;
@@ -203,6 +204,10 @@
activeChar.sendPacket(ExMailArrived.STATIC_PACKET);
}
+ // Vip Status onEnter
+ if (activeChar.getMemos().getLong("TimeOfVip", 0) > 0)
+ L2VipInstance.onEnterVipStatus(activeChar);
+
// Clan notice, if active.
if (Config.ENABLE_COMMUNITY_BOARD && clan != null && clan.isNoticeEnabled())
{
Index: java/net/sf/l2j/gameserver/model/actor/instance/L2VipInstance.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/instance/L2VipInstance.java (nonexistent)
+++ java/net/sf/l2j/gameserver/model/actor/instance/L2VipInstance.java (working copy)
@@ -0,0 +1,329 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+package net.sf.l2j.gameserver.model.actor.instance;
+
+import java.util.Calendar;
+import java.util.StringTokenizer;
+
+import net.sf.l2j.commons.concurrent.ThreadPool;
+import net.sf.l2j.gameserver.ai.CtrlIntention;
+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.World;
+import net.sf.l2j.gameserver.model.actor.instance.Folk;
+import net.sf.l2j.gameserver.model.base.Sex;
+import net.sf.l2j.gameserver.model.actor.template.NpcTemplate;
+import net.sf.l2j.gameserver.model.entity.Castle;
+import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
+import net.sf.l2j.gameserver.network.serverpackets.SiegeInfo;
+import net.sf.l2j.gameserver.network.serverpackets.SocialAction;
+
+/**
+ * @author Baggos
+ */
+public class L2VipInstance extends Folk
+{
+ public L2VipInstance(int objectId, NpcTemplate template)
+ {
+ super(objectId, template);
+ }
+
+ /** Type the count for clean pk */
+ private final static int PK_CLEAN_COUNT = 50;
+
+ @Override
+ public void onBypassFeedback(Player player, String command)
+ {
+ if (command.startsWith("vip"))
+ {
+ if (!player.isVipStatus())
+ {
+ player.sendMessage("Sorry! Only VIP player can do this action.");
+ return;
+ }
+ 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;
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ else if (command.startsWith("tp"))
+ {
+ if (!player.isVipStatus())
+ {
+ player.sendMessage("Sorry! Only VIP player can do this action.");
+ return;
+ }
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+
+ String val = "";
+ try
+ {
+ if (st.hasMoreTokens())
+ {
+ val = st.nextToken();
+ }
+ Player activeChar = World.getInstance().getPlayer(val);
+ teleportTo(val, player, activeChar);
+ }
+ catch (Exception e)
+ {
+ // Case if the player is not in the same party.
+ player.sendMessage("Incorrect target");
+ }
+ }
+
+ else if (command.startsWith("clantp"))
+ {
+ if (!player.isVipStatus())
+ {
+ player.sendMessage("Sorry! Only VIP player can do this action.");
+ return;
+ }
+ StringTokenizer st = new StringTokenizer(command);
+ st.nextToken();
+
+ String clan = "";
+ try
+ {
+ if (st.hasMoreTokens())
+ {
+ clan = st.nextToken();
+ }
+ Player activeChar = World.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("siege"))
+ {
+ if (!player.isVipStatus())
+ {
+ player.sendMessage("Sorry! Only VIP player can do this action.");
+ return;
+ }
+ 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)
+ {
+ }
+ }
+ }
+
+ public static void Nobless(Player player)
+ {
+ if (player.isNoble())
+ {
+ player.sendMessage("You Are Already A Noblesse!.");
+ return;
+ }
+ player.broadcastPacket(new SocialAction(player, 16));
+ player.setNoble(true, true);
+ player.sendMessage("You Are Now a Noble,You Are Granted With Noblesse Status , And Noblesse Skills.");
+ player.broadcastUserInfo();
+ }
+
+ public static void Sex(Player player)
+ {
+ player.getAppearance().setSex(player.getAppearance().getSex() == Sex.MALE ? Sex.FEMALE : Sex.MALE);
+ 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 static void CleanPk(Player player)
+ {
+ if (player.getPkKills() < 50)
+ {
+ player.sendMessage("You do not have enough Pk kills for clean.");
+ return;
+ }
+ player.setPkKills(player.getPkKills() - PK_CLEAN_COUNT);
+ player.sendMessage("You have successfully clean " + PK_CLEAN_COUNT + " pks!");
+ player.broadcastUserInfo();
+ }
+
+ public static void Rec(Player player)
+ {
+ if (player.getRecomHave() == 255)
+ {
+ player.sendMessage("You already have full recommends.");
+ return;
+ }
+ player.setRecomHave(255);
+ player.sendMessage("Added 255 recommends.");
+ player.getLastRecomUpdate();
+ player.broadcastUserInfo();
+ }
+
+ public static void teleportTo(String val, Player activeChar, Player target)
+ {
+ if (target.getObjectId() == activeChar.getObjectId())
+ activeChar.sendPacket(SystemMessageId.CANNOT_USE_ON_YOURSELF);
+
+ // Check if the player is not in the same party
+ else if (!activeChar.getParty().getMembers().contains(target))
+ return;
+
+ // Simple checks to avoid exploits
+ else if (target.isInJail() || target.isInOlympiadMode() || target.isInDuel() || target.isFestivalParticipant() || (target.isInParty() && target.getParty().isInDimensionalRift()) || target.isInObserverMode())
+ {
+ activeChar.sendMessage("Due to the current friend's status, the teleportation failed.");
+ return;
+ }
+
+ else 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;
+ }
+ else 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 3 Seconds!", 3000, 2, true));
+ ThreadPool.schedule(() -> activeChar.teleToLocation(x, y, z, 0), 3000);
+ activeChar.sendMessage("You have teleported to " + target.getName() + ".");
+ }
+
+ public static void teleportToClan(String clan, Player activeChar, Player target)
+ {
+ if (target.getObjectId() == activeChar.getObjectId())
+ activeChar.sendPacket(SystemMessageId.CANNOT_USE_ON_YOURSELF);
+
+ // Check if the player is not in the same clan.
+ else if (!activeChar.getClan().isMember(target.getObjectId()))
+ return;
+
+ // Simple checks to avoid exploits
+ else if (target.isInJail() || target.isInOlympiadMode() || target.isInDuel() || target.isFestivalParticipant() || (target.isInParty() && target.getParty().isInDimensionalRift()) || target.isInObserverMode())
+ {
+ activeChar.sendMessage("Due to the current clan member's status, the teleportation failed.");
+ return;
+ }
+
+ else 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;
+ }
+ else 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 3 Seconds!", 3000, 2, true));
+ ThreadPool.schedule(() -> activeChar.teleToLocation(x, y, z, 0), 3000);
+ activeChar.sendMessage("You have teleported to " + target.getName() + ".");
+ }
+
+ // Contains to EnterWorld.java for VIP onEnter.
+ public static void onEnterVipStatus(Player 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
+ public String getHtmlPath(int npcId, int val)
+ {
+ String filename = "";
+
+ if (val == 0)
+ filename = "" + npcId;
+ else
+ filename = npcId + "-" + val;
+
+ return "data/html/mods/vipNpc/" + filename + ".htm";
+ }
+}
\ No newline at end of file
#P aCis_datapack
Index: data/xml/npcs/50000-50999.xml
===================================================================
--- data/xml/npcs/50000-50999.xml (revision 5)
+++ data/xml/npcs/50000-50999.xml (working copy)
@@ -108,4 +108,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
Index: data/xml/admin_commands_rights.xml
===================================================================
--- data/xml/admin_commands_rights.xml (revision 5)
+++ data/xml/admin_commands_rights.xml (working copy)
@@ -12,6 +12,10 @@
+
+
+
+
Index: data/html/mods/vipNpc/50009.htm
===================================================================
Index: data/xml/items/3400-3499.xml
===================================================================
--- data/xml/items/3400-3499.xml (revision 5)
+++ data/xml/items/3400-3499.xml (working copy)
@@ -595,6 +595,7 @@
+
Index: data/html/mods/vipNpc/50009.htm
===================================================================
--- data/html/mods/vipNpc/50009.htm (nonexistent)
+++ data/html/mods/vipNpc/50009.htm (working copy)
@@ -0,0 +1,83 @@
+
+
+Donate Manager
+
+
+
+
+
+
+
+
+
+
+
+
+
Vip Settings:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Siege Services:
+
+
+
+
+
+
+
+
+Dear VIP player!
+From here you can go to your party member
+or you can also go to your clan member.
+Try it! It is easy only with one click.
+Conditions:
+ Olympiad, Duel, Events
+Jail, Observer Mode, Siege
+Flag for yourself, Karma for yourself.
+
+
+
+
+
+
+
+
+
+
Teleport to your party member:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Teleport to your clan member:
+
+
+
+
+
+
\ No newline at end of file
Index: data/xml/skills/2100-2199.xml
===================================================================
--- data/xml/skills/2100-2199.xml (revision 5)
+++ data/xml/skills/2100-2199.xml (working copy)
@@ -1,8 +1,8 @@
-
+
-
+