Support for premium henna slot.

This commit is contained in:
MobiusDev 2017-10-18 03:44:06 +00:00
parent bd34bdcd19
commit a08b596b1b
34 changed files with 260 additions and 95 deletions

View File

@ -27,6 +27,10 @@ PremiumRateSpoilChance = 1
# Spoil amount for premium players.
PremiumRateSpoilAmount = 2
# Enable premium henna slot.
# Default: True
EnablePremiumHennaSlot = True
# Caution: Raid bosses and herbs are not affected by premium rates, but specific items can be affected by rates bellow.
# List of items affected by custom drop rate by id, used now for Adena rate too.
# Usage: itemId1,multiplier1;itemId2,multiplier2;...

View File

@ -1111,6 +1111,7 @@ public final class Config
public static float PREMIUM_RATE_DROP_AMOUNT;
public static float PREMIUM_RATE_SPOIL_CHANCE;
public static float PREMIUM_RATE_SPOIL_AMOUNT;
public static boolean PREMIUM_HENNA_SLOT_ENABLED;
public static Map<Integer, Float> PREMIUM_RATE_DROP_CHANCE_BY_ID;
public static Map<Integer, Float> PREMIUM_RATE_DROP_AMOUNT_BY_ID;
public static boolean PC_CAFE_ENABLED;
@ -2546,6 +2547,7 @@ public final class Config
PREMIUM_RATE_DROP_AMOUNT = PremiumSystem.getFloat("PremiumRateDropAmount", 1);
PREMIUM_RATE_SPOIL_CHANCE = PremiumSystem.getFloat("PremiumRateSpoilChance", 2);
PREMIUM_RATE_SPOIL_AMOUNT = PremiumSystem.getFloat("PremiumRateSpoilAmount", 1);
PREMIUM_HENNA_SLOT_ENABLED = PremiumSystem.getBoolean("EnablePremiumHennaSlot", true);
final String[] premiumDropChanceMultiplier = PremiumSystem.getString("PremiumRateDropChanceByItemId", "").split(";");
PREMIUM_RATE_DROP_CHANCE_BY_ID = new HashMap<>(premiumDropChanceMultiplier.length);
if (!premiumDropChanceMultiplier[0].isEmpty())

View File

@ -50,6 +50,7 @@ public class PremiumManager
private static final String LOAD_SQL = "SELECT account_name,enddate FROM account_premium";
private static final String UPDATE_SQL = "UPDATE account_premium SET enddate = ? WHERE account_name = ?";
private static final String ADD_SQL = "INSERT INTO account_premium (enddate,account_name) VALUE (?,?)";
private static final String DELETE_SQL = "DELETE FROM account_premium WHERE account_name = ?";
class PremiumExpireTask implements Runnable
{
@ -65,6 +66,10 @@ public class PremiumManager
{
player.setPremiumStatus(false);
player.sendPacket(new ExBrPremiumState(player));
if (player.getHenna(4) != null)
{
player.removeHenna(4);
}
}
}
@ -90,6 +95,10 @@ public class PremiumManager
{
startExpireTask(player, premiumExpiration - now);
}
else if (player.getHenna(4) != null)
{
player.removeHenna(4);
}
};
private final Consumer<OnPlayerLogout> playerLogoutEvent = (event) ->
@ -202,6 +211,10 @@ public class PremiumManager
playerOnline.setPremiumStatus(false);
playerOnline.sendPacket(new ExBrPremiumState(playerOnline));
stopExpireTask(playerOnline);
if (playerOnline.getHenna(4) != null)
{
playerOnline.removeHenna(4);
}
}
// UPDATE CACHE
@ -209,10 +222,9 @@ public class PremiumManager
// UPDATE DATABASE
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement stmt = con.prepareStatement(UPDATE_SQL))
PreparedStatement stmt = con.prepareStatement(DELETE_SQL))
{
stmt.setLong(1, 0L);
stmt.setString(2, accountName);
stmt.setString(1, accountName);
stmt.execute();
}
catch (SQLException e)

View File

@ -597,9 +597,9 @@ public final class L2PcInstance extends L2Playable
private final Set<L2PcInstance> _snoopedPlayer = ConcurrentHashMap.newKeySet();
/** Hennas */
private final L2Henna[] _henna = new L2Henna[3];
private final L2Henna[] _henna = new L2Henna[4];
private final Map<BaseStats, Integer> _hennaBaseStats = new ConcurrentHashMap<>();
private final Map<Integer, ScheduledFuture<?>> _hennaRemoveSchedules = new ConcurrentHashMap<>(3);
private final Map<Integer, ScheduledFuture<?>> _hennaRemoveSchedules = new ConcurrentHashMap<>(4);
/** The Pet of the L2PcInstance */
private L2PetInstance _pet = null;
@ -7754,7 +7754,7 @@ public final class L2PcInstance extends L2Playable
*/
private void restoreHenna()
{
for (int i = 1; i < 4; i++)
for (int i = 1; i < 5; i++)
{
_henna[i - 1] = null;
}
@ -7771,7 +7771,7 @@ public final class L2PcInstance extends L2Playable
while (rset.next())
{
slot = rset.getInt("slot");
if ((slot < 1) || (slot > 3))
if ((slot < 1) || (slot > 4))
{
continue;
}
@ -7825,7 +7825,7 @@ public final class L2PcInstance extends L2Playable
{
totalSlots = 2;
}
else
else if (getClassId().level() > 1)
{
totalSlots = 3;
}
@ -7853,7 +7853,7 @@ public final class L2PcInstance extends L2Playable
*/
public boolean removeHenna(int slot)
{
if ((slot < 1) || (slot > 3))
if ((slot < 1) || (slot > 4))
{
return false;
}
@ -7894,7 +7894,7 @@ public final class L2PcInstance extends L2Playable
if ((henna.getDuration() < 0) || (remainingTime > 0))
{
// Add the recovered dyes to the player's inventory and notify them.
if (henna.getCancelFee() > 0)
if ((henna.getCancelFee() > 0) && (hasPremiumStatus() || (slot != 4)))
{
reduceAdena("Henna", henna.getCancelFee(), this, false);
}
@ -7938,7 +7938,7 @@ public final class L2PcInstance extends L2Playable
*/
public boolean addHenna(L2Henna henna)
{
for (int i = 1; i < 4; i++)
for (int i = 1; i < 5; i++)
{
if (_henna[i - 1] == null)
{
@ -8016,7 +8016,7 @@ public final class L2PcInstance extends L2Playable
*/
public L2Henna getHenna(int slot)
{
if ((slot < 1) || (slot > 3))
if ((slot < 1) || (slot > 4))
{
return null;
}

View File

@ -358,7 +358,14 @@ public class EnterWorld implements IClientIncomingPacket
// activeChar.queryGameGuard();
// Send Dye Information
activeChar.sendPacket(new HennaInfo(activeChar));
if (!Config.PREMIUM_SYSTEM_ENABLED && (activeChar.getHenna(4) != null))
{
activeChar.removeHenna(4);
}
else
{
activeChar.sendPacket(new HennaInfo(activeChar));
}
// Send Skill list
activeChar.sendSkillList();

View File

@ -57,7 +57,12 @@ public final class RequestHennaEquip implements IClientIncomingPacket
return;
}
if (activeChar.getHennaEmptySlots() == 0)
int totalHennaSlots = activeChar.getHennaEmptySlots();
if (activeChar.hasPremiumStatus() && Config.PREMIUM_HENNA_SLOT_ENABLED && (activeChar.getClassId().level() > 1) && (activeChar.getHenna(4) == null))
{
totalHennaSlots++;
}
if (totalHennaSlots == 0)
{
activeChar.sendPacket(SystemMessageId.NO_SLOT_EXISTS_TO_DRAW_THE_SYMBOL);
client.sendPacket(ActionFailed.STATIC_PACKET);

View File

@ -54,7 +54,7 @@ public final class RequestHennaRemove implements IClientIncomingPacket
L2Henna henna;
boolean found = false;
for (int i = 1; i <= 3; i++)
for (int i = 1; i <= 4; i++)
{
henna = activeChar.getHenna(i);
if ((henna != null) && (henna.getDyeId() == _symbolId))

View File

@ -37,11 +37,11 @@ public final class GMHennaInfo implements IClientOutgoingPacket
public GMHennaInfo(L2PcInstance player)
{
_activeChar = player;
for (L2Henna henna : _activeChar.getHennaList())
for (int i = 1; i < 4; i++)
{
if (henna != null)
if (player.getHenna(i) != null)
{
_hennas.add(henna);
_hennas.add(player.getHenna(i));
}
}
}
@ -66,9 +66,18 @@ public final class GMHennaInfo implements IClientOutgoingPacket
packet.writeD(henna.getDyeId());
packet.writeD(0x01);
}
packet.writeD(0x00);
packet.writeD(0x00);
packet.writeD(0x00);
if (_activeChar.getHenna(4) != null)
{
packet.writeD(_activeChar.getHenna(4).getDyeId());
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(_activeChar.getHenna(4).isAllowedClass(_activeChar.getClassId()) ? 0x01 : 0x00);
}
else
{
packet.writeD(0x00); // Premium Slot Dye ID
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(0x00); // Premium Slot Dye ID isValid
}
return true;
}
}

View File

@ -37,11 +37,11 @@ public final class HennaInfo implements IClientOutgoingPacket
public HennaInfo(L2PcInstance player)
{
_activeChar = player;
for (L2Henna henna : _activeChar.getHennaList())
for (int i = 1; i < 4; i++)
{
if (henna != null)
if (player.getHenna(i) != null)
{
_hennas.add(henna);
_hennas.add(player.getHenna(i));
}
}
}
@ -66,9 +66,18 @@ public final class HennaInfo implements IClientOutgoingPacket
packet.writeD(henna.getDyeId());
packet.writeD(henna.isAllowedClass(_activeChar.getClassId()) ? 0x01 : 0x00);
}
packet.writeD(0x00); // Premium Slot Dye ID
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(0x00); // Premium Slot Dye ID isValid
if (_activeChar.getHenna(4) != null)
{
packet.writeD(_activeChar.getHenna(4).getDyeId());
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(_activeChar.getHenna(4).isAllowedClass(_activeChar.getClassId()) ? 0x01 : 0x00);
}
else
{
packet.writeD(0x00); // Premium Slot Dye ID
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(0x00); // Premium Slot Dye ID isValid
}
return true;
}
}

View File

@ -16,6 +16,7 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.items.L2Henna;
@ -39,8 +40,14 @@ public class HennaRemoveList implements IClientOutgoingPacket
OutgoingPackets.HENNA_UNEQUIP_LIST.writeId(packet);
packet.writeQ(_player.getAdena());
packet.writeD(0x03); // seems to be max size
packet.writeD(3 - _player.getHennaEmptySlots());
boolean premiumSlotEnabled = false;
if (_player.hasPremiumStatus() && Config.PREMIUM_HENNA_SLOT_ENABLED && (_player.getClassId().level() > 1) && (_player.getHenna(4) != null))
{
premiumSlotEnabled = true;
}
packet.writeD(premiumSlotEnabled ? 0x04 : 0x03); // seems to be max size
packet.writeD((premiumSlotEnabled ? 4 : 3) - _player.getHennaEmptySlots()); // slots used
for (L2Henna henna : _player.getHennaList())
{

View File

@ -27,6 +27,10 @@ PremiumRateSpoilChance = 1
# Spoil amount for premium players.
PremiumRateSpoilAmount = 2
# Enable premium henna slot.
# Default: True
EnablePremiumHennaSlot = True
# Caution: Raid bosses and herbs are not affected by premium rates, but specific items can be affected by rates bellow.
# List of items affected by custom drop rate by id, used now for Adena rate too.
# Usage: itemId1,multiplier1;itemId2,multiplier2;...

View File

@ -1112,6 +1112,7 @@ public final class Config
public static float PREMIUM_RATE_DROP_AMOUNT;
public static float PREMIUM_RATE_SPOIL_CHANCE;
public static float PREMIUM_RATE_SPOIL_AMOUNT;
public static boolean PREMIUM_HENNA_SLOT_ENABLED;
public static Map<Integer, Float> PREMIUM_RATE_DROP_CHANCE_BY_ID;
public static Map<Integer, Float> PREMIUM_RATE_DROP_AMOUNT_BY_ID;
public static boolean PC_CAFE_ENABLED;
@ -2548,6 +2549,7 @@ public final class Config
PREMIUM_RATE_DROP_AMOUNT = PremiumSystem.getFloat("PremiumRateDropAmount", 1);
PREMIUM_RATE_SPOIL_CHANCE = PremiumSystem.getFloat("PremiumRateSpoilChance", 2);
PREMIUM_RATE_SPOIL_AMOUNT = PremiumSystem.getFloat("PremiumRateSpoilAmount", 1);
PREMIUM_HENNA_SLOT_ENABLED = PremiumSystem.getBoolean("EnablePremiumHennaSlot", true);
final String[] premiumDropChanceMultiplier = PremiumSystem.getString("PremiumRateDropChanceByItemId", "").split(";");
PREMIUM_RATE_DROP_CHANCE_BY_ID = new HashMap<>(premiumDropChanceMultiplier.length);
if (!premiumDropChanceMultiplier[0].isEmpty())

View File

@ -50,6 +50,7 @@ public class PremiumManager
private static final String LOAD_SQL = "SELECT account_name,enddate FROM account_premium";
private static final String UPDATE_SQL = "UPDATE account_premium SET enddate = ? WHERE account_name = ?";
private static final String ADD_SQL = "INSERT INTO account_premium (enddate,account_name) VALUE (?,?)";
private static final String DELETE_SQL = "DELETE FROM account_premium WHERE account_name = ?";
class PremiumExpireTask implements Runnable
{
@ -65,6 +66,10 @@ public class PremiumManager
{
player.setPremiumStatus(false);
player.sendPacket(new ExBrPremiumState(player));
if (player.getHenna(4) != null)
{
player.removeHenna(4);
}
}
}
@ -90,6 +95,10 @@ public class PremiumManager
{
startExpireTask(player, premiumExpiration - now);
}
else if (player.getHenna(4) != null)
{
player.removeHenna(4);
}
};
private final Consumer<OnPlayerLogout> playerLogoutEvent = (event) ->
@ -202,6 +211,10 @@ public class PremiumManager
playerOnline.setPremiumStatus(false);
playerOnline.sendPacket(new ExBrPremiumState(playerOnline));
stopExpireTask(playerOnline);
if (playerOnline.getHenna(4) != null)
{
playerOnline.removeHenna(4);
}
}
// UPDATE CACHE
@ -209,10 +222,9 @@ public class PremiumManager
// UPDATE DATABASE
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement stmt = con.prepareStatement(UPDATE_SQL))
PreparedStatement stmt = con.prepareStatement(DELETE_SQL))
{
stmt.setLong(1, 0L);
stmt.setString(2, accountName);
stmt.setString(1, accountName);
stmt.execute();
}
catch (SQLException e)

View File

@ -596,9 +596,9 @@ public final class L2PcInstance extends L2Playable
private final Set<L2PcInstance> _snoopedPlayer = ConcurrentHashMap.newKeySet();
/** Hennas */
private final L2Henna[] _henna = new L2Henna[3];
private final L2Henna[] _henna = new L2Henna[4];
private final Map<BaseStats, Integer> _hennaBaseStats = new ConcurrentHashMap<>();
private final Map<Integer, ScheduledFuture<?>> _hennaRemoveSchedules = new ConcurrentHashMap<>(3);
private final Map<Integer, ScheduledFuture<?>> _hennaRemoveSchedules = new ConcurrentHashMap<>(4);
/** The Pet of the L2PcInstance */
private L2PetInstance _pet = null;
@ -7754,7 +7754,7 @@ public final class L2PcInstance extends L2Playable
*/
private void restoreHenna()
{
for (int i = 1; i < 4; i++)
for (int i = 1; i < 5; i++)
{
_henna[i - 1] = null;
}
@ -7771,7 +7771,7 @@ public final class L2PcInstance extends L2Playable
while (rset.next())
{
slot = rset.getInt("slot");
if ((slot < 1) || (slot > 3))
if ((slot < 1) || (slot > 4))
{
continue;
}
@ -7825,7 +7825,7 @@ public final class L2PcInstance extends L2Playable
{
totalSlots = 2;
}
else
else if (getClassId().level() > 1)
{
totalSlots = 3;
}
@ -7853,7 +7853,7 @@ public final class L2PcInstance extends L2Playable
*/
public boolean removeHenna(int slot)
{
if ((slot < 1) || (slot > 3))
if ((slot < 1) || (slot > 4))
{
return false;
}
@ -7894,7 +7894,7 @@ public final class L2PcInstance extends L2Playable
if ((henna.getDuration() < 0) || (remainingTime > 0))
{
// Add the recovered dyes to the player's inventory and notify them.
if (henna.getCancelFee() > 0)
if ((henna.getCancelFee() > 0) && (hasPremiumStatus() || (slot != 4)))
{
reduceAdena("Henna", henna.getCancelFee(), this, false);
}
@ -7938,7 +7938,7 @@ public final class L2PcInstance extends L2Playable
*/
public boolean addHenna(L2Henna henna)
{
for (int i = 1; i < 4; i++)
for (int i = 1; i < 5; i++)
{
if (_henna[i - 1] == null)
{
@ -8016,7 +8016,7 @@ public final class L2PcInstance extends L2Playable
*/
public L2Henna getHenna(int slot)
{
if ((slot < 1) || (slot > 3))
if ((slot < 1) || (slot > 4))
{
return null;
}

View File

@ -361,7 +361,14 @@ public class EnterWorld implements IClientIncomingPacket
// activeChar.queryGameGuard();
// Send Dye Information
activeChar.sendPacket(new HennaInfo(activeChar));
if (!Config.PREMIUM_SYSTEM_ENABLED && (activeChar.getHenna(4) != null))
{
activeChar.removeHenna(4);
}
else
{
activeChar.sendPacket(new HennaInfo(activeChar));
}
// Send Skill list
activeChar.sendSkillList();

View File

@ -57,7 +57,12 @@ public final class RequestHennaEquip implements IClientIncomingPacket
return;
}
if (activeChar.getHennaEmptySlots() == 0)
int totalHennaSlots = activeChar.getHennaEmptySlots();
if (activeChar.hasPremiumStatus() && Config.PREMIUM_HENNA_SLOT_ENABLED && (activeChar.getClassId().level() > 1) && (activeChar.getHenna(4) == null))
{
totalHennaSlots++;
}
if (totalHennaSlots == 0)
{
activeChar.sendPacket(SystemMessageId.NO_SLOT_EXISTS_TO_DRAW_THE_SYMBOL);
client.sendPacket(ActionFailed.STATIC_PACKET);

View File

@ -54,7 +54,7 @@ public final class RequestHennaRemove implements IClientIncomingPacket
L2Henna henna;
boolean found = false;
for (int i = 1; i <= 3; i++)
for (int i = 1; i <= 4; i++)
{
henna = activeChar.getHenna(i);
if ((henna != null) && (henna.getDyeId() == _symbolId))

View File

@ -37,11 +37,11 @@ public final class GMHennaInfo implements IClientOutgoingPacket
public GMHennaInfo(L2PcInstance player)
{
_activeChar = player;
for (L2Henna henna : _activeChar.getHennaList())
for (int i = 1; i < 4; i++)
{
if (henna != null)
if (player.getHenna(i) != null)
{
_hennas.add(henna);
_hennas.add(player.getHenna(i));
}
}
}
@ -66,9 +66,18 @@ public final class GMHennaInfo implements IClientOutgoingPacket
packet.writeD(henna.getDyeId());
packet.writeD(0x01);
}
packet.writeD(0x00);
packet.writeD(0x00);
packet.writeD(0x00);
if (_activeChar.getHenna(4) != null)
{
packet.writeD(_activeChar.getHenna(4).getDyeId());
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(_activeChar.getHenna(4).isAllowedClass(_activeChar.getClassId()) ? 0x01 : 0x00);
}
else
{
packet.writeD(0x00); // Premium Slot Dye ID
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(0x00); // Premium Slot Dye ID isValid
}
return true;
}
}

View File

@ -37,11 +37,11 @@ public final class HennaInfo implements IClientOutgoingPacket
public HennaInfo(L2PcInstance player)
{
_activeChar = player;
for (L2Henna henna : _activeChar.getHennaList())
for (int i = 1; i < 4; i++)
{
if (henna != null)
if (player.getHenna(i) != null)
{
_hennas.add(henna);
_hennas.add(player.getHenna(i));
}
}
}
@ -66,9 +66,18 @@ public final class HennaInfo implements IClientOutgoingPacket
packet.writeD(henna.getDyeId());
packet.writeD(henna.isAllowedClass(_activeChar.getClassId()) ? 0x01 : 0x00);
}
packet.writeD(0x00); // Premium Slot Dye ID
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(0x00); // Premium Slot Dye ID isValid
if (_activeChar.getHenna(4) != null)
{
packet.writeD(_activeChar.getHenna(4).getDyeId());
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(_activeChar.getHenna(4).isAllowedClass(_activeChar.getClassId()) ? 0x01 : 0x00);
}
else
{
packet.writeD(0x00); // Premium Slot Dye ID
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(0x00); // Premium Slot Dye ID isValid
}
return true;
}
}

View File

@ -16,6 +16,7 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.items.L2Henna;
@ -39,8 +40,14 @@ public class HennaRemoveList implements IClientOutgoingPacket
OutgoingPackets.HENNA_UNEQUIP_LIST.writeId(packet);
packet.writeQ(_player.getAdena());
packet.writeD(0x03); // seems to be max size
packet.writeD(3 - _player.getHennaEmptySlots());
boolean premiumSlotEnabled = false;
if (_player.hasPremiumStatus() && Config.PREMIUM_HENNA_SLOT_ENABLED && (_player.getClassId().level() > 1) && (_player.getHenna(4) != null))
{
premiumSlotEnabled = true;
}
packet.writeD(premiumSlotEnabled ? 0x04 : 0x03); // seems to be max size
packet.writeD((premiumSlotEnabled ? 4 : 3) - _player.getHennaEmptySlots()); // slots used
for (L2Henna henna : _player.getHennaList())
{

View File

@ -27,6 +27,10 @@ PremiumRateSpoilChance = 1
# Spoil amount for premium players.
PremiumRateSpoilAmount = 2
# Enable premium henna slot.
# Default: True
EnablePremiumHennaSlot = True
# Caution: Raid bosses and herbs are not affected by premium rates, but specific items can be affected by rates bellow.
# List of items affected by custom drop rate by id, used now for Adena rate too.
# Usage: itemId1,multiplier1;itemId2,multiplier2;...

View File

@ -1120,6 +1120,7 @@ public final class Config
public static float PREMIUM_RATE_DROP_AMOUNT;
public static float PREMIUM_RATE_SPOIL_CHANCE;
public static float PREMIUM_RATE_SPOIL_AMOUNT;
public static boolean PREMIUM_HENNA_SLOT_ENABLED;
public static Map<Integer, Float> PREMIUM_RATE_DROP_CHANCE_BY_ID;
public static Map<Integer, Float> PREMIUM_RATE_DROP_AMOUNT_BY_ID;
public static boolean PC_CAFE_ENABLED;
@ -2565,6 +2566,7 @@ public final class Config
PREMIUM_RATE_DROP_AMOUNT = PremiumSystem.getFloat("PremiumRateDropAmount", 1);
PREMIUM_RATE_SPOIL_CHANCE = PremiumSystem.getFloat("PremiumRateSpoilChance", 2);
PREMIUM_RATE_SPOIL_AMOUNT = PremiumSystem.getFloat("PremiumRateSpoilAmount", 1);
PREMIUM_HENNA_SLOT_ENABLED = PremiumSystem.getBoolean("EnablePremiumHennaSlot", true);
final String[] premiumDropChanceMultiplier = PremiumSystem.getString("PremiumRateDropChanceByItemId", "").split(";");
PREMIUM_RATE_DROP_CHANCE_BY_ID = new HashMap<>(premiumDropChanceMultiplier.length);
if (!premiumDropChanceMultiplier[0].isEmpty())

View File

@ -50,6 +50,7 @@ public class PremiumManager
private static final String LOAD_SQL = "SELECT account_name,enddate FROM account_premium";
private static final String UPDATE_SQL = "UPDATE account_premium SET enddate = ? WHERE account_name = ?";
private static final String ADD_SQL = "INSERT INTO account_premium (enddate,account_name) VALUE (?,?)";
private static final String DELETE_SQL = "DELETE FROM account_premium WHERE account_name = ?";
class PremiumExpireTask implements Runnable
{
@ -65,6 +66,10 @@ public class PremiumManager
{
player.setPremiumStatus(false);
player.sendPacket(new ExBrPremiumState(player));
if (player.getHenna(4) != null)
{
player.removeHenna(4);
}
}
}
@ -90,6 +95,10 @@ public class PremiumManager
{
startExpireTask(player, premiumExpiration - now);
}
else if (player.getHenna(4) != null)
{
player.removeHenna(4);
}
};
private final Consumer<OnPlayerLogout> playerLogoutEvent = (event) ->
@ -202,6 +211,10 @@ public class PremiumManager
playerOnline.setPremiumStatus(false);
playerOnline.sendPacket(new ExBrPremiumState(playerOnline));
stopExpireTask(playerOnline);
if (playerOnline.getHenna(4) != null)
{
playerOnline.removeHenna(4);
}
}
// UPDATE CACHE
@ -209,10 +222,9 @@ public class PremiumManager
// UPDATE DATABASE
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement stmt = con.prepareStatement(UPDATE_SQL))
PreparedStatement stmt = con.prepareStatement(DELETE_SQL))
{
stmt.setLong(1, 0L);
stmt.setString(2, accountName);
stmt.setString(1, accountName);
stmt.execute();
}
catch (SQLException e)

View File

@ -598,9 +598,9 @@ public final class L2PcInstance extends L2Playable
private final Set<L2PcInstance> _snoopedPlayer = ConcurrentHashMap.newKeySet();
/** Hennas */
private final L2Henna[] _henna = new L2Henna[3];
private final L2Henna[] _henna = new L2Henna[4];
private final Map<BaseStats, Integer> _hennaBaseStats = new ConcurrentHashMap<>();
private final Map<Integer, ScheduledFuture<?>> _hennaRemoveSchedules = new ConcurrentHashMap<>(3);
private final Map<Integer, ScheduledFuture<?>> _hennaRemoveSchedules = new ConcurrentHashMap<>(4);
/** The Pet of the L2PcInstance */
private L2PetInstance _pet = null;
@ -7756,7 +7756,7 @@ public final class L2PcInstance extends L2Playable
*/
private void restoreHenna()
{
for (int i = 1; i < 4; i++)
for (int i = 1; i < 5; i++)
{
_henna[i - 1] = null;
}
@ -7773,7 +7773,7 @@ public final class L2PcInstance extends L2Playable
while (rset.next())
{
slot = rset.getInt("slot");
if ((slot < 1) || (slot > 3))
if ((slot < 1) || (slot > 4))
{
continue;
}
@ -7827,7 +7827,7 @@ public final class L2PcInstance extends L2Playable
{
totalSlots = 2;
}
else
else if (getClassId().level() > 1)
{
totalSlots = 3;
}
@ -7855,7 +7855,7 @@ public final class L2PcInstance extends L2Playable
*/
public boolean removeHenna(int slot)
{
if ((slot < 1) || (slot > 3))
if ((slot < 1) || (slot > 4))
{
return false;
}
@ -7896,7 +7896,7 @@ public final class L2PcInstance extends L2Playable
if ((henna.getDuration() < 0) || (remainingTime > 0))
{
// Add the recovered dyes to the player's inventory and notify them.
if (henna.getCancelFee() > 0)
if ((henna.getCancelFee() > 0) && (hasPremiumStatus() || (slot != 4)))
{
reduceAdena("Henna", henna.getCancelFee(), this, false);
}
@ -7940,7 +7940,7 @@ public final class L2PcInstance extends L2Playable
*/
public boolean addHenna(L2Henna henna)
{
for (int i = 1; i < 4; i++)
for (int i = 1; i < 5; i++)
{
if (_henna[i - 1] == null)
{
@ -8018,7 +8018,7 @@ public final class L2PcInstance extends L2Playable
*/
public L2Henna getHenna(int slot)
{
if ((slot < 1) || (slot > 3))
if ((slot < 1) || (slot > 4))
{
return null;
}

View File

@ -361,7 +361,14 @@ public class EnterWorld implements IClientIncomingPacket
// activeChar.queryGameGuard();
// Send Dye Information
activeChar.sendPacket(new HennaInfo(activeChar));
if (!Config.PREMIUM_SYSTEM_ENABLED && (activeChar.getHenna(4) != null))
{
activeChar.removeHenna(4);
}
else
{
activeChar.sendPacket(new HennaInfo(activeChar));
}
// Send Skill list
activeChar.sendSkillList();

View File

@ -57,7 +57,12 @@ public final class RequestHennaEquip implements IClientIncomingPacket
return;
}
if (activeChar.getHennaEmptySlots() == 0)
int totalHennaSlots = activeChar.getHennaEmptySlots();
if (activeChar.hasPremiumStatus() && Config.PREMIUM_HENNA_SLOT_ENABLED && (activeChar.getClassId().level() > 1) && (activeChar.getHenna(4) == null))
{
totalHennaSlots++;
}
if (totalHennaSlots == 0)
{
activeChar.sendPacket(SystemMessageId.NO_SLOT_EXISTS_TO_DRAW_THE_SYMBOL);
client.sendPacket(ActionFailed.STATIC_PACKET);

View File

@ -54,7 +54,7 @@ public final class RequestHennaRemove implements IClientIncomingPacket
L2Henna henna;
boolean found = false;
for (int i = 1; i <= 3; i++)
for (int i = 1; i <= 4; i++)
{
henna = activeChar.getHenna(i);
if ((henna != null) && (henna.getDyeId() == _symbolId))

View File

@ -37,11 +37,11 @@ public final class GMHennaInfo implements IClientOutgoingPacket
public GMHennaInfo(L2PcInstance player)
{
_activeChar = player;
for (L2Henna henna : _activeChar.getHennaList())
for (int i = 1; i < 4; i++)
{
if (henna != null)
if (player.getHenna(i) != null)
{
_hennas.add(henna);
_hennas.add(player.getHenna(i));
}
}
}
@ -66,9 +66,18 @@ public final class GMHennaInfo implements IClientOutgoingPacket
packet.writeD(henna.getDyeId());
packet.writeD(0x01);
}
packet.writeD(0x00);
packet.writeD(0x00);
packet.writeD(0x00);
if (_activeChar.getHenna(4) != null)
{
packet.writeD(_activeChar.getHenna(4).getDyeId());
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(_activeChar.getHenna(4).isAllowedClass(_activeChar.getClassId()) ? 0x01 : 0x00);
}
else
{
packet.writeD(0x00); // Premium Slot Dye ID
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(0x00); // Premium Slot Dye ID isValid
}
return true;
}
}

View File

@ -37,11 +37,11 @@ public final class HennaInfo implements IClientOutgoingPacket
public HennaInfo(L2PcInstance player)
{
_activeChar = player;
for (L2Henna henna : _activeChar.getHennaList())
for (int i = 1; i < 4; i++)
{
if (henna != null)
if (player.getHenna(i) != null)
{
_hennas.add(henna);
_hennas.add(player.getHenna(i));
}
}
}
@ -66,9 +66,18 @@ public final class HennaInfo implements IClientOutgoingPacket
packet.writeD(henna.getDyeId());
packet.writeD(henna.isAllowedClass(_activeChar.getClassId()) ? 0x01 : 0x00);
}
packet.writeD(0x00); // Premium Slot Dye ID
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(0x00); // Premium Slot Dye ID isValid
if (_activeChar.getHenna(4) != null)
{
packet.writeD(_activeChar.getHenna(4).getDyeId());
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(_activeChar.getHenna(4).isAllowedClass(_activeChar.getClassId()) ? 0x01 : 0x00);
}
else
{
packet.writeD(0x00); // Premium Slot Dye ID
packet.writeD(0x00); // Premium Slot Dye Time Left
packet.writeD(0x00); // Premium Slot Dye ID isValid
}
return true;
}
}

View File

@ -16,6 +16,7 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.items.L2Henna;
@ -39,8 +40,14 @@ public class HennaRemoveList implements IClientOutgoingPacket
OutgoingPackets.HENNA_UNEQUIP_LIST.writeId(packet);
packet.writeQ(_player.getAdena());
packet.writeD(0x03); // seems to be max size
packet.writeD(3 - _player.getHennaEmptySlots());
boolean premiumSlotEnabled = false;
if (_player.hasPremiumStatus() && Config.PREMIUM_HENNA_SLOT_ENABLED && (_player.getClassId().level() > 1) && (_player.getHenna(4) != null))
{
premiumSlotEnabled = true;
}
packet.writeD(premiumSlotEnabled ? 0x04 : 0x03); // seems to be max size
packet.writeD((premiumSlotEnabled ? 4 : 3) - _player.getHennaEmptySlots()); // slots used
for (L2Henna henna : _player.getHennaList())
{

View File

@ -49,6 +49,7 @@ public class PremiumManager
private static final String LOAD_SQL = "SELECT account_name,enddate FROM account_premium";
private static final String UPDATE_SQL = "UPDATE account_premium SET enddate = ? WHERE account_name = ?";
private static final String ADD_SQL = "INSERT INTO account_premium (enddate,account_name) VALUE (?,?)";
private static final String DELETE_SQL = "DELETE FROM account_premium WHERE account_name = ?";
class PremiumExpireTask implements Runnable
{
@ -208,10 +209,9 @@ public class PremiumManager
// UPDATE DATABASE
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement stmt = con.prepareStatement(UPDATE_SQL))
PreparedStatement stmt = con.prepareStatement(DELETE_SQL))
{
stmt.setLong(1, 0L);
stmt.setString(2, accountName);
stmt.setString(1, accountName);
stmt.execute();
}
catch (SQLException e)

View File

@ -7914,7 +7914,7 @@ public final class L2PcInstance extends L2Playable
{
totalSlots = 2;
}
else
else if (getClassId().level() > 1)
{
totalSlots = 3;
}

View File

@ -50,6 +50,7 @@ public class PremiumManager
private static final String LOAD_SQL = "SELECT account_name,enddate FROM account_premium";
private static final String UPDATE_SQL = "UPDATE account_premium SET enddate = ? WHERE account_name = ?";
private static final String ADD_SQL = "INSERT INTO account_premium (enddate,account_name) VALUE (?,?)";
private static final String DELETE_SQL = "DELETE FROM account_premium WHERE account_name = ?";
class PremiumExpireTask implements Runnable
{
@ -209,10 +210,9 @@ public class PremiumManager
// UPDATE DATABASE
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement stmt = con.prepareStatement(UPDATE_SQL))
PreparedStatement stmt = con.prepareStatement(DELETE_SQL))
{
stmt.setLong(1, 0L);
stmt.setString(2, accountName);
stmt.setString(1, accountName);
stmt.execute();
}
catch (SQLException e)

View File

@ -7797,7 +7797,7 @@ public final class L2PcInstance extends L2Playable
{
totalSlots = 2;
}
else
else if (getClassId().level() > 1)
{
totalSlots = 3;
}