From 198be02ca51e8884335030ea27e9d25f4f6e31d0 Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Sun, 26 Jun 2022 02:34:08 +0000 Subject: [PATCH] Resurrection with payment. Contributed by Index. --- .../dist/game/config/Character.ini | 68 ++++++++++ .../java/org/l2jmobius/Config.java | 95 ++++++++++++++ .../instancemanager/DailyTaskManager.java | 27 ++++ .../holders/ResurrectByPaymentHolder.java | 49 ++++++++ .../model/variables/PlayerVariables.java | 1 + .../clientpackets/RequestRestartPoint.java | 91 ++++++++++++++ .../gameserver/network/serverpackets/Die.java | 118 +++++++++++++++++- L2J_Mobius_Essence_5.2_FrostLord/readme.txt | 3 +- .../dist/game/config/Character.ini | 68 ++++++++++ .../java/org/l2jmobius/Config.java | 95 ++++++++++++++ .../instancemanager/DailyTaskManager.java | 27 ++++ .../holders/ResurrectByPaymentHolder.java | 49 ++++++++ .../model/variables/PlayerVariables.java | 1 + .../clientpackets/RequestRestartPoint.java | 91 ++++++++++++++ .../gameserver/network/serverpackets/Die.java | 118 +++++++++++++++++- .../readme.txt | 2 +- .../dist/game/config/Character.ini | 68 ++++++++++ .../java/org/l2jmobius/Config.java | 95 ++++++++++++++ .../instancemanager/DailyTaskManager.java | 27 ++++ .../holders/ResurrectByPaymentHolder.java | 49 ++++++++ .../model/variables/PlayerVariables.java | 1 + .../clientpackets/RequestRestartPoint.java | 91 ++++++++++++++ .../gameserver/network/serverpackets/Die.java | 118 +++++++++++++++++- L2J_Mobius_Essence_6.2_Vanguard/readme.txt | 2 +- 24 files changed, 1345 insertions(+), 9 deletions(-) create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java create mode 100644 L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java diff --git a/L2J_Mobius_Essence_5.2_FrostLord/dist/game/config/Character.ini b/L2J_Mobius_Essence_5.2_FrostLord/dist/game/config/Character.ini index e92a32d789..99853dab05 100644 --- a/L2J_Mobius_Essence_5.2_FrostLord/dist/game/config/Character.ini +++ b/L2J_Mobius_Essence_5.2_FrostLord/dist/game/config/Character.ini @@ -46,6 +46,74 @@ MpRegenMultiplier = 100 CpRegenMultiplier = 100 +# --------------------------------------------------------------------------- +# Die recovery by payment +# --------------------------------------------------------------------------- + +# Enable die recovery. +# Default: True +EnabledResurrectByPay = True + +# Total number of free resurrections per day. +# Default: 2 +MaxFreeResurrectionsByDay = 2 + +# Upper window resurrect item ID. +# Default: 91663 - L-Coin / MAKE CLIENT CHANGES! +FirstResurrectItemID = 91663 + +# List of for first case. +# level : times , count , restoration percent / times , count , percent; +# level : times , count , restoration percent / times , count , percent; +# the "\"indicates new line, +# NO FREE SPACES! +# Default: 60:3,1,100.0/4,2,100.0/5,3,100.0;\ +# 75:3,1,100.0/4,3,100.0/5,4,100.0;\ +# 79:3,2,100.0/4,5,100.0/5,10,100.0;\ +# 81:3,5,100.0/4,10,100.0/5,15,100.0;\ +# 84:3,15,100.0/4,20,100.0/5,25,100.0;\ +# 86:3,20,100.0/4,40,100.0/5,80,100.0;\ +# 88:3,25,100.0/4,50,100.0/5,100,100.0;\ +# 90:3,25,100.0/4,50,100.0/5,100,100.0; + +FirstResurrectList = 60:3,1,100.0/4,2,100.0/5,3,100.0;\ +75:3,1,100.0/4,3,100.0/5,4,100.0;\ +79:3,2,100.0/4,5,100.0/5,10,100.0;\ +81:3,5,100.0/4,10,100.0/5,15,100.0;\ +84:3,15,100.0/4,20,100.0/5,25,100.0;\ +86:3,20,100.0/4,40,100.0/5,80,100.0;\ +88:3,25,100.0/4,50,100.0/5,100,100.0;\ +90:3,25,100.0/4,50,100.0/5,100,100.0; + +# Lowest window resurrect item ID. +# Default: 57 - Adena / MAKE CLIENT CHANGES! +SecondResurrectItemID = 57 + +# List of for second case. +# level : times , count , restoration percent / times , count , percent; +# level : times , count , restoration percent / times , count , percent; +# the "\"indicates new line, +# NO FREE SPACES! +# Default: +# 60:3,5000,90.0/4,5000,80.0/5,5000,80.0/6,5000,70.0/7,5000,70.0/8,5000,60.0/9,5000,50.0;\ +# 75:3,10000,90.0/4,10000,80.0/5,10000,80.0/6,10000,70.0/7,10000,70.0/8,10000,60.0/9,10000,50.0;\ +# 79:3,20000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +# 81:3,30000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +# 84:3,60000,90.0/4,60000,80.0/5,60000,80.0/6,60000,70.0/7,60000,70.0/8,60000,60.0/9,60000,50.0;\ +# 86:3,125000,90.0/4,125000,80.0/5,125000,80.0/6,125000,70.0/7,125000,70.0/8,125000,60.0/9,125000,50.0;\ +# 88:3,240000,90.0/4,240000,80.0/5,240000,80.0/6,240000,70.0/7,240000,70.0/8,240000,60.0/9,240000,50.0;\ +# 90:3,400000,90.0/4,400000,80.0/5,400000,80.0/6,400000,70.0/7,400000,70.0/8,400000,60.0/9,400000,50.0; + +SecondResurrectList = 60:3,5000,90.0/4,5000,80.0/5,5000,80.0/6,5000,70.0/7,5000,70.0/8,5000,60.0/9,5000,50.0;\ +75:3,10000,90.0/4,10000,80.0/5,10000,80.0/6,10000,70.0/7,10000,70.0/8,10000,60.0/9,10000,50.0;\ +79:3,20000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +81:3,30000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +84:3,60000,90.0/4,60000,80.0/5,60000,80.0/6,60000,70.0/7,60000,70.0/8,60000,60.0/9,60000,50.0;\ +86:3,125000,90.0/4,125000,80.0/5,125000,80.0/6,125000,70.0/7,125000,70.0/8,125000,60.0/9,125000,50.0;\ +88:3,240000,90.0/4,240000,80.0/5,240000,80.0/6,240000,70.0/7,240000,70.0/8,240000,60.0/9,240000,50.0;\ +90:3,400000,90.0/4,400000,80.0/5,400000,80.0/6,400000,70.0/7,400000,70.0/8,400000,60.0/9,400000,50.0; + + # --------------------------------------------------------------------------- # Skills & Effects # --------------------------------------------------------------------------- diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/Config.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/Config.java index 0676fab29c..f448a7af6b 100644 --- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/Config.java @@ -44,6 +44,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -65,6 +66,7 @@ import org.l2jmobius.gameserver.enums.GeoType; import org.l2jmobius.gameserver.enums.IllegalActionPunishmentType; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.holders.ItemHolder; +import org.l2jmobius.gameserver.model.holders.ResurrectByPaymentHolder; import org.l2jmobius.gameserver.util.FloodProtectorConfig; import org.l2jmobius.gameserver.util.Util; @@ -890,6 +892,12 @@ public class Config public static int MAX_CONNECTION_PER_IP; public static boolean ENABLE_CMD_LINE_LOGIN; public static boolean ONLY_CMD_LINE_LOGIN; + public static boolean RESURRECT_BY_PAYMENT_ENABLED; + public static int RESURRECT_BY_PAYMENT_MAX_FREE_TIMES; + public static int RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM; + public static Map> RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES; + public static int RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM; + public static Map> RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES; // Magic Lamp public static boolean ENABLE_MAGIC_LAMP; @@ -1654,6 +1662,93 @@ public class Config HP_REGEN_MULTIPLIER = characterConfig.getDouble("HpRegenMultiplier", 100) / 100; MP_REGEN_MULTIPLIER = characterConfig.getDouble("MpRegenMultiplier", 100) / 100; CP_REGEN_MULTIPLIER = characterConfig.getDouble("CpRegenMultiplier", 100) / 100; + + RESURRECT_BY_PAYMENT_ENABLED = characterConfig.getBoolean("EnabledResurrectByPay", true); + if (RESURRECT_BY_PAYMENT_ENABLED) + { + Map RESURRECT_DATA = new TreeMap<>(); + RESURRECT_BY_PAYMENT_MAX_FREE_TIMES = characterConfig.getInt("MaxFreeResurrectionsByDay", 0); + RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM = characterConfig.getInt("FirstResurrectItemID", 0); + final String[] firstPaymentSplit = characterConfig.getString("FirstResurrectList", "").split(";"); + RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES = new TreeMap<>(); + for (String timeData : firstPaymentSplit) + { + RESURRECT_DATA = new TreeMap<>(); + final String[] timeSplit = timeData.split(":"); + if (timeSplit.length != 2) + { + LOGGER.warning("[FirstResurrectList]: invalid config property -> Level data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + final String[] dataSplit = timeSplit[1].split("/"); + for (String data : dataSplit) + { + while (data.contains(" ")) + { + data = data.replace(" ", ""); + } + final String[] values = data.split(","); + if (values.length < 3) + { + LOGGER.warning("[FirstResurrectList]: invalid config property -> Times data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + try + { + final int time = Integer.parseInt(values[0]); + final int count = Integer.parseInt(values[1]); + final double percent = Double.parseDouble(values[2]); + RESURRECT_DATA.put(time, new ResurrectByPaymentHolder(time, count, percent)); + } + catch (Exception e) + { + LOGGER.warning("[FirstResurrectList]: invalid config property -> Times data cannot be parsed. Look on exception " + timeSplit[0]); + e.printStackTrace(); + } + } + RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.put(Integer.parseInt(timeSplit[0]), RESURRECT_DATA); + } + final String[] secondPaymentSplit = characterConfig.getString("SecondResurrectList", "").split(";"); + RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES = new TreeMap<>(); + for (String timeData : secondPaymentSplit) + { + RESURRECT_DATA = new TreeMap<>(); + final String[] timeSplit = timeData.split(":"); + if (timeSplit.length != 2) + { + LOGGER.warning("[SecondResurrectList]: invalid config property -> Level data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + final String[] dataSplit = timeSplit[1].split("/"); + for (String data : dataSplit) + { + while (data.contains(" ")) + { + data = data.replace(" ", ""); + } + final String[] values = data.split(","); + if (values.length < 3) + { + LOGGER.warning("[SecondResurrectList]: invalid config property -> Times data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + try + { + final int time = Integer.parseInt(values[0]); + final int count = Integer.parseInt(values[1]); + final double percent = Double.parseDouble(values[2]); + RESURRECT_DATA.put(time, new ResurrectByPaymentHolder(time, count, percent)); + } + catch (Exception e) + { + LOGGER.warning("[SecondResurrectList]: invalid config property -> Times data cannot be parsed. Look on exception " + timeSplit[0]); + e.printStackTrace(); + } + } + RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.put(Integer.parseInt(timeSplit[0]), RESURRECT_DATA); + } + RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM = characterConfig.getInt("SecondResurrectItemID", 0); + } ENABLE_MODIFY_SKILL_DURATION = characterConfig.getBoolean("EnableModifySkillDuration", false); if (ENABLE_MODIFY_SKILL_DURATION) { diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java index 9a0ff18983..f236a91132 100644 --- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java +++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java @@ -140,6 +140,7 @@ public class DailyTaskManager resetDailyMissionRewards(); resetAttendanceRewards(); resetVip(); + resetResurrectionByPayment(); } private void onSave() @@ -667,6 +668,32 @@ public class DailyTaskManager LOGGER.info("LimitShopData has been resetted."); } + private void resetResurrectionByPayment() + { + // Update data for offline players. + try (Connection con = DatabaseFactory.getConnection()) + { + try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_variables WHERE var=?")) + { + ps.setString(1, PlayerVariables.RESURRECT_BY_PAYMENT_COUNT); + ps.execute(); + } + } + catch (Exception e) + { + LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Could not reset payment resurrection count for players: " + e); + } + + // Update data for online players. + for (Player player : World.getInstance().getPlayers()) + { + player.getVariables().remove(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT); + player.getVariables().storeMe(); + } + + LOGGER.info("Daily payment resurrection count for player has been resetted."); + } + public static DailyTaskManager getInstance() { return SingletonHolder.INSTANCE; diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java new file mode 100644 index 0000000000..15e61c74cd --- /dev/null +++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java @@ -0,0 +1,49 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.l2jmobius.gameserver.model.holders; + +/** + * @author Index + */ +public class ResurrectByPaymentHolder +{ + private final int _time; + private final int _amount; + private final double _resurrectPercent; + + public ResurrectByPaymentHolder(int time, int amount, double percent) + { + _time = time; + _amount = amount; + _resurrectPercent = percent; + } + + public int getTime() + { + return _time; + } + + public int getAmount() + { + return _amount; + } + + public double getResurrectPercent() + { + return _resurrectPercent; + } +} diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java index e24538a5da..8914176931 100644 --- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java +++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java @@ -79,6 +79,7 @@ public class PlayerVariables extends AbstractVariables public static final String STAT_INT = "STAT_INT"; public static final String STAT_WIT = "STAT_WIT"; public static final String STAT_MEN = "STAT_MEN"; + public static final String RESURRECT_BY_PAYMENT_COUNT = "RESURRECT_BY_PAYMENT_COUNT"; public static final String CLAN_JOIN_TIME = "CLAN_JOIN_TIME"; private final int _objectId; diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java index 703b7702f9..ce1feef717 100644 --- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java +++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java @@ -16,6 +16,11 @@ */ package org.l2jmobius.gameserver.network.clientpackets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.threads.ThreadPool; import org.l2jmobius.gameserver.data.xml.ClanHallData; @@ -29,7 +34,9 @@ import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.events.EventType; import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; +import org.l2jmobius.gameserver.model.holders.ResurrectByPaymentHolder; import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.model.item.instance.Item; import org.l2jmobius.gameserver.model.quest.Event; import org.l2jmobius.gameserver.model.residences.ClanHall; import org.l2jmobius.gameserver.model.residences.ResidenceFunctionType; @@ -38,8 +45,11 @@ import org.l2jmobius.gameserver.model.siege.Castle.CastleFunction; import org.l2jmobius.gameserver.model.siege.Fort; import org.l2jmobius.gameserver.model.siege.Fort.FortFunction; import org.l2jmobius.gameserver.model.skill.CommonSkill; +import org.l2jmobius.gameserver.model.variables.PlayerVariables; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.PacketLogger; +import org.l2jmobius.gameserver.network.SystemMessageId; +import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * @version $Revision: 1.7.2.3.2.6 $ $Date: 2005/03/27 15:29:30 $ @@ -48,11 +58,18 @@ public class RequestRestartPoint implements IClientIncomingPacket { protected int _requestedPointType; protected boolean _continuation; + protected int _resItemID; + protected int _resCount; @Override public boolean read(GameClient client, PacketReader packet) { _requestedPointType = packet.readD(); + if (packet.getReadableBytes() != 0) + { + _resItemID = packet.readD(); + _resCount = packet.readD(); + } return true; } @@ -270,6 +287,80 @@ public class RequestRestartPoint implements IClientIncomingPacket { break; } + case 9: + { + if (Config.RESURRECT_BY_PAYMENT_ENABLED) + { + if (!player.isDead()) + { + break; + } + + final int originalValue = player.getVariables().getInt(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, 0); + if (originalValue < Config.RESURRECT_BY_PAYMENT_MAX_FREE_TIMES) + { + player.getVariables().set(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, originalValue + 1); + player.doRevive(100.0); + loc = MapRegionManager.getInstance().getTeleToLocation(player, TeleportWhereType.TOWN); + player.teleToLocation(loc, true, instance); + break; + } + + final int firstID = Config.RESURRECT_BY_PAYMENT_ENABLED ? Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM : 91663; + final int secondID = Config.RESURRECT_BY_PAYMENT_ENABLED ? Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM : 57; + Map> resMAP = null; + Item item = null; + if (_resItemID == firstID) + { + resMAP = Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES; + item = player.getInventory().getItemByItemId(Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM); + } + else if (_resItemID == secondID) + { + resMAP = Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES; + item = player.getInventory().getItemByItemId(Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM); + } + if ((resMAP == null) || (item == null)) + { + break; + } + + final List levelList = new ArrayList<>(resMAP.keySet()); + for (int level : levelList) + { + if ((player.getLevel() >= level) && (levelList.lastIndexOf(level) != (levelList.size() - 1))) + { + continue; + } + + int maxResTime; + try + { + maxResTime = resMAP.get(level).keySet().stream().max(Integer::compareTo).get(); + } + catch (Exception e) + { + player.sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS)); + e.printStackTrace(); + return; + } + + final int getValue = maxResTime <= originalValue ? maxResTime : originalValue + 1; + final ResurrectByPaymentHolder rbph = resMAP.get(level).get(getValue); + if (item.getCount() < rbph.getAmount()) + { + return; + } + + player.getVariables().set(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, originalValue + 1); + player.destroyItem("item revive", item, rbph.getAmount(), player, true); + player.doRevive(rbph.getResurrectPercent()); + loc = MapRegionManager.getInstance().getTeleToLocation(player, TeleportWhereType.TOWN); + player.teleToLocation(loc, true, instance); + break; + } + } + } case 27: // to jail { if (!player.isJailed()) diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/Die.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/Die.java index f2986bb241..7daa6dd8de 100644 --- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/Die.java +++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/Die.java @@ -16,16 +16,23 @@ */ package org.l2jmobius.gameserver.network.serverpackets; +import java.util.ArrayList; +import java.util.List; + +import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketWriter; import org.l2jmobius.gameserver.instancemanager.CastleManager; import org.l2jmobius.gameserver.instancemanager.FortManager; import org.l2jmobius.gameserver.model.SiegeClan; import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.clan.Clan; +import org.l2jmobius.gameserver.model.holders.ResurrectByPaymentHolder; import org.l2jmobius.gameserver.model.siege.Castle; import org.l2jmobius.gameserver.model.siege.Fort; import org.l2jmobius.gameserver.model.skill.BuffInfo; import org.l2jmobius.gameserver.model.skill.CommonSkill; +import org.l2jmobius.gameserver.model.variables.PlayerVariables; import org.l2jmobius.gameserver.network.OutgoingPackets; /** @@ -37,6 +44,7 @@ public class Die implements IClientOutgoingPacket private final boolean _isSweepable; private int _flags = 0; private int _delayFeather = 0; + private Player _player; public Die(Creature creature) { @@ -44,7 +52,8 @@ public class Die implements IClientOutgoingPacket _isSweepable = creature.isAttackable() && creature.isSweepActive(); if (creature.isPlayer()) { - final Clan clan = creature.getActingPlayer().getClan(); + _player = creature.getActingPlayer(); + final Clan clan = _player.getClan(); boolean isInCastleDefense = false; boolean isInFortDefense = false; SiegeClan siegeClan = null; @@ -108,8 +117,113 @@ public class Die implements IClientOutgoingPacket packet.writeD(_delayFeather); // Feather item time. packet.writeC(0); // Hide die animation. packet.writeD(0); - packet.writeD(0); + if ((_player != null) && Config.RESURRECT_BY_PAYMENT_ENABLED) + { + int resurrectTimes = _player.getVariables().getInt(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, 0) + 1; + int originalValue = resurrectTimes - 1; + if (originalValue < Config.RESURRECT_BY_PAYMENT_MAX_FREE_TIMES) + { + packet.writeD(Config.RESURRECT_BY_PAYMENT_MAX_FREE_TIMES - originalValue); // free round resurrection + packet.writeD(0); // Adena resurrection + packet.writeD(0); // Adena count% + packet.writeD(0); // L-Coin resurrection + packet.writeD(0); // L-Coin count% + } + else + { + packet.writeD(0); + getValues(_player, packet, originalValue); + } + } + else + { + packet.writeD(1); // free round resurrection + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + } packet.writeD(0); return true; } + + private void getValues(Player player, PacketWriter packet, int originalValue) + { + if ((Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES == null) || (Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES == null)) + { + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + return; + } + + final List levelListFirst = new ArrayList<>(Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.keySet()); + final List levelListSecond = new ArrayList<>(Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.keySet()); + for (int level : levelListSecond) + { + if (Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.isEmpty()) + { + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + break; + } + + if ((player.getLevel() >= level) && (levelListSecond.lastIndexOf(level) != (levelListSecond.size() - 1))) + { + continue; + } + + int maxResTime; + try + { + maxResTime = Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.get(level).keySet().stream().max(Integer::compareTo).get(); + } + catch (Exception e) + { + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + return; + } + + int getValue = maxResTime <= originalValue ? maxResTime : originalValue + 1; + ResurrectByPaymentHolder rbph = Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.get(level).get(getValue); + packet.writeD(rbph.getAmount()); // Adena resurrection + packet.writeD(Math.toIntExact(Math.round(rbph.getResurrectPercent()))); // Adena count% + break; + } + + for (int level : levelListFirst) + { + if (Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.isEmpty()) + { + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + break; + } + + if ((player.getLevel() >= level) && (levelListFirst.lastIndexOf(level) != (levelListFirst.size() - 1))) + { + continue; + } + + int maxResTime; + try + { + maxResTime = Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.get(level).keySet().stream().max(Integer::compareTo).get(); + } + catch (Exception e) + { + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + return; + } + + final int getValue = maxResTime <= originalValue ? maxResTime : originalValue + 1; + ResurrectByPaymentHolder rbph = Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.get(level).get(getValue); + packet.writeD(rbph.getAmount()); // L-Coin resurrection + packet.writeD(Math.toIntExact(Math.round(rbph.getResurrectPercent()))); // L-Coin count% + break; + } + } } diff --git a/L2J_Mobius_Essence_5.2_FrostLord/readme.txt b/L2J_Mobius_Essence_5.2_FrostLord/readme.txt index 2643d411ed..638c1c973f 100644 --- a/L2J_Mobius_Essence_5.2_FrostLord/readme.txt +++ b/L2J_Mobius_Essence_5.2_FrostLord/readme.txt @@ -131,7 +131,8 @@ Sylph: https://eu.4game.com/patchnotes/lineage2essence/281/ -Pledge donation system Frost Lord: https://eu.4game.com/patchnotes/lineage2essence/329/ --Client support +-Resurrection with payment +-Frost Lord castle Customs: -Newbie Helper NPC location info diff --git a/L2J_Mobius_Essence_6.1_BattleChronicle/dist/game/config/Character.ini b/L2J_Mobius_Essence_6.1_BattleChronicle/dist/game/config/Character.ini index e92a32d789..99853dab05 100644 --- a/L2J_Mobius_Essence_6.1_BattleChronicle/dist/game/config/Character.ini +++ b/L2J_Mobius_Essence_6.1_BattleChronicle/dist/game/config/Character.ini @@ -46,6 +46,74 @@ MpRegenMultiplier = 100 CpRegenMultiplier = 100 +# --------------------------------------------------------------------------- +# Die recovery by payment +# --------------------------------------------------------------------------- + +# Enable die recovery. +# Default: True +EnabledResurrectByPay = True + +# Total number of free resurrections per day. +# Default: 2 +MaxFreeResurrectionsByDay = 2 + +# Upper window resurrect item ID. +# Default: 91663 - L-Coin / MAKE CLIENT CHANGES! +FirstResurrectItemID = 91663 + +# List of for first case. +# level : times , count , restoration percent / times , count , percent; +# level : times , count , restoration percent / times , count , percent; +# the "\"indicates new line, +# NO FREE SPACES! +# Default: 60:3,1,100.0/4,2,100.0/5,3,100.0;\ +# 75:3,1,100.0/4,3,100.0/5,4,100.0;\ +# 79:3,2,100.0/4,5,100.0/5,10,100.0;\ +# 81:3,5,100.0/4,10,100.0/5,15,100.0;\ +# 84:3,15,100.0/4,20,100.0/5,25,100.0;\ +# 86:3,20,100.0/4,40,100.0/5,80,100.0;\ +# 88:3,25,100.0/4,50,100.0/5,100,100.0;\ +# 90:3,25,100.0/4,50,100.0/5,100,100.0; + +FirstResurrectList = 60:3,1,100.0/4,2,100.0/5,3,100.0;\ +75:3,1,100.0/4,3,100.0/5,4,100.0;\ +79:3,2,100.0/4,5,100.0/5,10,100.0;\ +81:3,5,100.0/4,10,100.0/5,15,100.0;\ +84:3,15,100.0/4,20,100.0/5,25,100.0;\ +86:3,20,100.0/4,40,100.0/5,80,100.0;\ +88:3,25,100.0/4,50,100.0/5,100,100.0;\ +90:3,25,100.0/4,50,100.0/5,100,100.0; + +# Lowest window resurrect item ID. +# Default: 57 - Adena / MAKE CLIENT CHANGES! +SecondResurrectItemID = 57 + +# List of for second case. +# level : times , count , restoration percent / times , count , percent; +# level : times , count , restoration percent / times , count , percent; +# the "\"indicates new line, +# NO FREE SPACES! +# Default: +# 60:3,5000,90.0/4,5000,80.0/5,5000,80.0/6,5000,70.0/7,5000,70.0/8,5000,60.0/9,5000,50.0;\ +# 75:3,10000,90.0/4,10000,80.0/5,10000,80.0/6,10000,70.0/7,10000,70.0/8,10000,60.0/9,10000,50.0;\ +# 79:3,20000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +# 81:3,30000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +# 84:3,60000,90.0/4,60000,80.0/5,60000,80.0/6,60000,70.0/7,60000,70.0/8,60000,60.0/9,60000,50.0;\ +# 86:3,125000,90.0/4,125000,80.0/5,125000,80.0/6,125000,70.0/7,125000,70.0/8,125000,60.0/9,125000,50.0;\ +# 88:3,240000,90.0/4,240000,80.0/5,240000,80.0/6,240000,70.0/7,240000,70.0/8,240000,60.0/9,240000,50.0;\ +# 90:3,400000,90.0/4,400000,80.0/5,400000,80.0/6,400000,70.0/7,400000,70.0/8,400000,60.0/9,400000,50.0; + +SecondResurrectList = 60:3,5000,90.0/4,5000,80.0/5,5000,80.0/6,5000,70.0/7,5000,70.0/8,5000,60.0/9,5000,50.0;\ +75:3,10000,90.0/4,10000,80.0/5,10000,80.0/6,10000,70.0/7,10000,70.0/8,10000,60.0/9,10000,50.0;\ +79:3,20000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +81:3,30000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +84:3,60000,90.0/4,60000,80.0/5,60000,80.0/6,60000,70.0/7,60000,70.0/8,60000,60.0/9,60000,50.0;\ +86:3,125000,90.0/4,125000,80.0/5,125000,80.0/6,125000,70.0/7,125000,70.0/8,125000,60.0/9,125000,50.0;\ +88:3,240000,90.0/4,240000,80.0/5,240000,80.0/6,240000,70.0/7,240000,70.0/8,240000,60.0/9,240000,50.0;\ +90:3,400000,90.0/4,400000,80.0/5,400000,80.0/6,400000,70.0/7,400000,70.0/8,400000,60.0/9,400000,50.0; + + # --------------------------------------------------------------------------- # Skills & Effects # --------------------------------------------------------------------------- diff --git a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/Config.java b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/Config.java index c22b78bc19..b95225c399 100644 --- a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/Config.java @@ -44,6 +44,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -65,6 +66,7 @@ import org.l2jmobius.gameserver.enums.GeoType; import org.l2jmobius.gameserver.enums.IllegalActionPunishmentType; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.holders.ItemHolder; +import org.l2jmobius.gameserver.model.holders.ResurrectByPaymentHolder; import org.l2jmobius.gameserver.util.FloodProtectorConfig; import org.l2jmobius.gameserver.util.Util; @@ -891,6 +893,12 @@ public class Config public static int MAX_CONNECTION_PER_IP; public static boolean ENABLE_CMD_LINE_LOGIN; public static boolean ONLY_CMD_LINE_LOGIN; + public static boolean RESURRECT_BY_PAYMENT_ENABLED; + public static int RESURRECT_BY_PAYMENT_MAX_FREE_TIMES; + public static int RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM; + public static Map> RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES; + public static int RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM; + public static Map> RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES; // Magic Lamp public static boolean ENABLE_MAGIC_LAMP; @@ -1661,6 +1669,93 @@ public class Config HP_REGEN_MULTIPLIER = characterConfig.getDouble("HpRegenMultiplier", 100) / 100; MP_REGEN_MULTIPLIER = characterConfig.getDouble("MpRegenMultiplier", 100) / 100; CP_REGEN_MULTIPLIER = characterConfig.getDouble("CpRegenMultiplier", 100) / 100; + + RESURRECT_BY_PAYMENT_ENABLED = characterConfig.getBoolean("EnabledResurrectByPay", true); + if (RESURRECT_BY_PAYMENT_ENABLED) + { + Map RESURRECT_DATA = new TreeMap<>(); + RESURRECT_BY_PAYMENT_MAX_FREE_TIMES = characterConfig.getInt("MaxFreeResurrectionsByDay", 0); + RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM = characterConfig.getInt("FirstResurrectItemID", 0); + final String[] firstPaymentSplit = characterConfig.getString("FirstResurrectList", "").split(";"); + RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES = new TreeMap<>(); + for (String timeData : firstPaymentSplit) + { + RESURRECT_DATA = new TreeMap<>(); + final String[] timeSplit = timeData.split(":"); + if (timeSplit.length != 2) + { + LOGGER.warning("[FirstResurrectList]: invalid config property -> Level data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + final String[] dataSplit = timeSplit[1].split("/"); + for (String data : dataSplit) + { + while (data.contains(" ")) + { + data = data.replace(" ", ""); + } + final String[] values = data.split(","); + if (values.length < 3) + { + LOGGER.warning("[FirstResurrectList]: invalid config property -> Times data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + try + { + final int time = Integer.parseInt(values[0]); + final int count = Integer.parseInt(values[1]); + final double percent = Double.parseDouble(values[2]); + RESURRECT_DATA.put(time, new ResurrectByPaymentHolder(time, count, percent)); + } + catch (Exception e) + { + LOGGER.warning("[FirstResurrectList]: invalid config property -> Times data cannot be parsed. Look on exception " + timeSplit[0]); + e.printStackTrace(); + } + } + RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.put(Integer.parseInt(timeSplit[0]), RESURRECT_DATA); + } + final String[] secondPaymentSplit = characterConfig.getString("SecondResurrectList", "").split(";"); + RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES = new TreeMap<>(); + for (String timeData : secondPaymentSplit) + { + RESURRECT_DATA = new TreeMap<>(); + final String[] timeSplit = timeData.split(":"); + if (timeSplit.length != 2) + { + LOGGER.warning("[SecondResurrectList]: invalid config property -> Level data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + final String[] dataSplit = timeSplit[1].split("/"); + for (String data : dataSplit) + { + while (data.contains(" ")) + { + data = data.replace(" ", ""); + } + final String[] values = data.split(","); + if (values.length < 3) + { + LOGGER.warning("[SecondResurrectList]: invalid config property -> Times data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + try + { + final int time = Integer.parseInt(values[0]); + final int count = Integer.parseInt(values[1]); + final double percent = Double.parseDouble(values[2]); + RESURRECT_DATA.put(time, new ResurrectByPaymentHolder(time, count, percent)); + } + catch (Exception e) + { + LOGGER.warning("[SecondResurrectList]: invalid config property -> Times data cannot be parsed. Look on exception " + timeSplit[0]); + e.printStackTrace(); + } + } + RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.put(Integer.parseInt(timeSplit[0]), RESURRECT_DATA); + } + RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM = characterConfig.getInt("SecondResurrectItemID", 0); + } ENABLE_MODIFY_SKILL_DURATION = characterConfig.getBoolean("EnableModifySkillDuration", false); if (ENABLE_MODIFY_SKILL_DURATION) { diff --git a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java index 2d27475d04..1d283647f1 100644 --- a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java +++ b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java @@ -141,6 +141,7 @@ public class DailyTaskManager resetDailyMissionRewards(); resetAttendanceRewards(); resetVip(); + resetResurrectionByPayment(); } private void onSave() @@ -668,6 +669,32 @@ public class DailyTaskManager LOGGER.info("LimitShopData has been resetted."); } + private void resetResurrectionByPayment() + { + // Update data for offline players. + try (Connection con = DatabaseFactory.getConnection()) + { + try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_variables WHERE var=?")) + { + ps.setString(1, PlayerVariables.RESURRECT_BY_PAYMENT_COUNT); + ps.execute(); + } + } + catch (Exception e) + { + LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Could not reset payment resurrection count for players: " + e); + } + + // Update data for online players. + for (Player player : World.getInstance().getPlayers()) + { + player.getVariables().remove(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT); + player.getVariables().storeMe(); + } + + LOGGER.info("Daily payment resurrection count for player has been resetted."); + } + private void resetDailyHennaPattern() { // Update data for offline players. diff --git a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java new file mode 100644 index 0000000000..15e61c74cd --- /dev/null +++ b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java @@ -0,0 +1,49 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.l2jmobius.gameserver.model.holders; + +/** + * @author Index + */ +public class ResurrectByPaymentHolder +{ + private final int _time; + private final int _amount; + private final double _resurrectPercent; + + public ResurrectByPaymentHolder(int time, int amount, double percent) + { + _time = time; + _amount = amount; + _resurrectPercent = percent; + } + + public int getTime() + { + return _time; + } + + public int getAmount() + { + return _amount; + } + + public double getResurrectPercent() + { + return _resurrectPercent; + } +} diff --git a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java index d40fc41a63..fb753317fd 100644 --- a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java +++ b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java @@ -79,6 +79,7 @@ public class PlayerVariables extends AbstractVariables public static final String STAT_INT = "STAT_INT"; public static final String STAT_WIT = "STAT_WIT"; public static final String STAT_MEN = "STAT_MEN"; + public static final String RESURRECT_BY_PAYMENT_COUNT = "RESURRECT_BY_PAYMENT_COUNT"; public static final String CLAN_JOIN_TIME = "CLAN_JOIN_TIME"; public static final String HENNA1_DURATION = "HENNA1_DURATION"; public static final String HENNA2_DURATION = "HENNA2_DURATION"; diff --git a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java index 703b7702f9..ce1feef717 100644 --- a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java +++ b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java @@ -16,6 +16,11 @@ */ package org.l2jmobius.gameserver.network.clientpackets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.threads.ThreadPool; import org.l2jmobius.gameserver.data.xml.ClanHallData; @@ -29,7 +34,9 @@ import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.events.EventType; import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; +import org.l2jmobius.gameserver.model.holders.ResurrectByPaymentHolder; import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.model.item.instance.Item; import org.l2jmobius.gameserver.model.quest.Event; import org.l2jmobius.gameserver.model.residences.ClanHall; import org.l2jmobius.gameserver.model.residences.ResidenceFunctionType; @@ -38,8 +45,11 @@ import org.l2jmobius.gameserver.model.siege.Castle.CastleFunction; import org.l2jmobius.gameserver.model.siege.Fort; import org.l2jmobius.gameserver.model.siege.Fort.FortFunction; import org.l2jmobius.gameserver.model.skill.CommonSkill; +import org.l2jmobius.gameserver.model.variables.PlayerVariables; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.PacketLogger; +import org.l2jmobius.gameserver.network.SystemMessageId; +import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * @version $Revision: 1.7.2.3.2.6 $ $Date: 2005/03/27 15:29:30 $ @@ -48,11 +58,18 @@ public class RequestRestartPoint implements IClientIncomingPacket { protected int _requestedPointType; protected boolean _continuation; + protected int _resItemID; + protected int _resCount; @Override public boolean read(GameClient client, PacketReader packet) { _requestedPointType = packet.readD(); + if (packet.getReadableBytes() != 0) + { + _resItemID = packet.readD(); + _resCount = packet.readD(); + } return true; } @@ -270,6 +287,80 @@ public class RequestRestartPoint implements IClientIncomingPacket { break; } + case 9: + { + if (Config.RESURRECT_BY_PAYMENT_ENABLED) + { + if (!player.isDead()) + { + break; + } + + final int originalValue = player.getVariables().getInt(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, 0); + if (originalValue < Config.RESURRECT_BY_PAYMENT_MAX_FREE_TIMES) + { + player.getVariables().set(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, originalValue + 1); + player.doRevive(100.0); + loc = MapRegionManager.getInstance().getTeleToLocation(player, TeleportWhereType.TOWN); + player.teleToLocation(loc, true, instance); + break; + } + + final int firstID = Config.RESURRECT_BY_PAYMENT_ENABLED ? Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM : 91663; + final int secondID = Config.RESURRECT_BY_PAYMENT_ENABLED ? Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM : 57; + Map> resMAP = null; + Item item = null; + if (_resItemID == firstID) + { + resMAP = Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES; + item = player.getInventory().getItemByItemId(Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM); + } + else if (_resItemID == secondID) + { + resMAP = Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES; + item = player.getInventory().getItemByItemId(Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM); + } + if ((resMAP == null) || (item == null)) + { + break; + } + + final List levelList = new ArrayList<>(resMAP.keySet()); + for (int level : levelList) + { + if ((player.getLevel() >= level) && (levelList.lastIndexOf(level) != (levelList.size() - 1))) + { + continue; + } + + int maxResTime; + try + { + maxResTime = resMAP.get(level).keySet().stream().max(Integer::compareTo).get(); + } + catch (Exception e) + { + player.sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS)); + e.printStackTrace(); + return; + } + + final int getValue = maxResTime <= originalValue ? maxResTime : originalValue + 1; + final ResurrectByPaymentHolder rbph = resMAP.get(level).get(getValue); + if (item.getCount() < rbph.getAmount()) + { + return; + } + + player.getVariables().set(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, originalValue + 1); + player.destroyItem("item revive", item, rbph.getAmount(), player, true); + player.doRevive(rbph.getResurrectPercent()); + loc = MapRegionManager.getInstance().getTeleToLocation(player, TeleportWhereType.TOWN); + player.teleToLocation(loc, true, instance); + break; + } + } + } case 27: // to jail { if (!player.isJailed()) diff --git a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/network/serverpackets/Die.java b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/network/serverpackets/Die.java index caafead57a..c443dd0c52 100644 --- a/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/network/serverpackets/Die.java +++ b/L2J_Mobius_Essence_6.1_BattleChronicle/java/org/l2jmobius/gameserver/network/serverpackets/Die.java @@ -16,16 +16,23 @@ */ package org.l2jmobius.gameserver.network.serverpackets; +import java.util.ArrayList; +import java.util.List; + +import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketWriter; import org.l2jmobius.gameserver.instancemanager.CastleManager; import org.l2jmobius.gameserver.instancemanager.FortManager; import org.l2jmobius.gameserver.model.SiegeClan; import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.clan.Clan; +import org.l2jmobius.gameserver.model.holders.ResurrectByPaymentHolder; import org.l2jmobius.gameserver.model.siege.Castle; import org.l2jmobius.gameserver.model.siege.Fort; import org.l2jmobius.gameserver.model.skill.BuffInfo; import org.l2jmobius.gameserver.model.skill.CommonSkill; +import org.l2jmobius.gameserver.model.variables.PlayerVariables; import org.l2jmobius.gameserver.network.OutgoingPackets; /** @@ -37,6 +44,7 @@ public class Die implements IClientOutgoingPacket private final boolean _isSweepable; private int _flags = 1; // To nearest village. private int _delayFeather = 0; + private Player _player; public Die(Creature creature) { @@ -44,7 +52,8 @@ public class Die implements IClientOutgoingPacket _isSweepable = creature.isAttackable() && creature.isSweepActive(); if (creature.isPlayer()) { - final Clan clan = creature.getActingPlayer().getClan(); + _player = creature.getActingPlayer(); + final Clan clan = _player.getClan(); boolean isInCastleDefense = false; boolean isInFortDefense = false; SiegeClan siegeClan = null; @@ -108,8 +117,113 @@ public class Die implements IClientOutgoingPacket packet.writeD(_delayFeather); // Feather item time. packet.writeC(0); // Hide die animation. packet.writeD(0); - packet.writeD(0); + if ((_player != null) && Config.RESURRECT_BY_PAYMENT_ENABLED) + { + int resurrectTimes = _player.getVariables().getInt(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, 0) + 1; + int originalValue = resurrectTimes - 1; + if (originalValue < Config.RESURRECT_BY_PAYMENT_MAX_FREE_TIMES) + { + packet.writeD(Config.RESURRECT_BY_PAYMENT_MAX_FREE_TIMES - originalValue); // free round resurrection + packet.writeD(0); // Adena resurrection + packet.writeD(0); // Adena count% + packet.writeD(0); // L-Coin resurrection + packet.writeD(0); // L-Coin count% + } + else + { + packet.writeD(0); + getValues(_player, packet, originalValue); + } + } + else + { + packet.writeD(1); // free round resurrection + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + } packet.writeD(0); return true; } + + private void getValues(Player player, PacketWriter packet, int originalValue) + { + if ((Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES == null) || (Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES == null)) + { + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + return; + } + + final List levelListFirst = new ArrayList<>(Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.keySet()); + final List levelListSecond = new ArrayList<>(Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.keySet()); + for (int level : levelListSecond) + { + if (Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.isEmpty()) + { + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + break; + } + + if ((player.getLevel() >= level) && (levelListSecond.lastIndexOf(level) != (levelListSecond.size() - 1))) + { + continue; + } + + int maxResTime; + try + { + maxResTime = Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.get(level).keySet().stream().max(Integer::compareTo).get(); + } + catch (Exception e) + { + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + return; + } + + int getValue = maxResTime <= originalValue ? maxResTime : originalValue + 1; + ResurrectByPaymentHolder rbph = Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.get(level).get(getValue); + packet.writeD(rbph.getAmount()); // Adena resurrection + packet.writeD(Math.toIntExact(Math.round(rbph.getResurrectPercent()))); // Adena count% + break; + } + + for (int level : levelListFirst) + { + if (Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.isEmpty()) + { + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + break; + } + + if ((player.getLevel() >= level) && (levelListFirst.lastIndexOf(level) != (levelListFirst.size() - 1))) + { + continue; + } + + int maxResTime; + try + { + maxResTime = Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.get(level).keySet().stream().max(Integer::compareTo).get(); + } + catch (Exception e) + { + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + return; + } + + final int getValue = maxResTime <= originalValue ? maxResTime : originalValue + 1; + ResurrectByPaymentHolder rbph = Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.get(level).get(getValue); + packet.writeD(rbph.getAmount()); // L-Coin resurrection + packet.writeD(Math.toIntExact(Math.round(rbph.getResurrectPercent()))); // L-Coin count% + break; + } + } } diff --git a/L2J_Mobius_Essence_6.1_BattleChronicle/readme.txt b/L2J_Mobius_Essence_6.1_BattleChronicle/readme.txt index 372d0f1921..7a67d5fc52 100644 --- a/L2J_Mobius_Essence_6.1_BattleChronicle/readme.txt +++ b/L2J_Mobius_Essence_6.1_BattleChronicle/readme.txt @@ -132,7 +132,7 @@ Sylph: https://eu.4game.com/patchnotes/lineage2essence/281/ -Hellbound spawns Frost Lord: https://eu.4game.com/patchnotes/lineage2essence/329/ --Updated skill trees +-Resurrection with payment -Frost Lord castle Battle Chronicle: https://eu.4game.com/patchnotes/lineage2essence/353/ diff --git a/L2J_Mobius_Essence_6.2_Vanguard/dist/game/config/Character.ini b/L2J_Mobius_Essence_6.2_Vanguard/dist/game/config/Character.ini index e92a32d789..99853dab05 100644 --- a/L2J_Mobius_Essence_6.2_Vanguard/dist/game/config/Character.ini +++ b/L2J_Mobius_Essence_6.2_Vanguard/dist/game/config/Character.ini @@ -46,6 +46,74 @@ MpRegenMultiplier = 100 CpRegenMultiplier = 100 +# --------------------------------------------------------------------------- +# Die recovery by payment +# --------------------------------------------------------------------------- + +# Enable die recovery. +# Default: True +EnabledResurrectByPay = True + +# Total number of free resurrections per day. +# Default: 2 +MaxFreeResurrectionsByDay = 2 + +# Upper window resurrect item ID. +# Default: 91663 - L-Coin / MAKE CLIENT CHANGES! +FirstResurrectItemID = 91663 + +# List of for first case. +# level : times , count , restoration percent / times , count , percent; +# level : times , count , restoration percent / times , count , percent; +# the "\"indicates new line, +# NO FREE SPACES! +# Default: 60:3,1,100.0/4,2,100.0/5,3,100.0;\ +# 75:3,1,100.0/4,3,100.0/5,4,100.0;\ +# 79:3,2,100.0/4,5,100.0/5,10,100.0;\ +# 81:3,5,100.0/4,10,100.0/5,15,100.0;\ +# 84:3,15,100.0/4,20,100.0/5,25,100.0;\ +# 86:3,20,100.0/4,40,100.0/5,80,100.0;\ +# 88:3,25,100.0/4,50,100.0/5,100,100.0;\ +# 90:3,25,100.0/4,50,100.0/5,100,100.0; + +FirstResurrectList = 60:3,1,100.0/4,2,100.0/5,3,100.0;\ +75:3,1,100.0/4,3,100.0/5,4,100.0;\ +79:3,2,100.0/4,5,100.0/5,10,100.0;\ +81:3,5,100.0/4,10,100.0/5,15,100.0;\ +84:3,15,100.0/4,20,100.0/5,25,100.0;\ +86:3,20,100.0/4,40,100.0/5,80,100.0;\ +88:3,25,100.0/4,50,100.0/5,100,100.0;\ +90:3,25,100.0/4,50,100.0/5,100,100.0; + +# Lowest window resurrect item ID. +# Default: 57 - Adena / MAKE CLIENT CHANGES! +SecondResurrectItemID = 57 + +# List of for second case. +# level : times , count , restoration percent / times , count , percent; +# level : times , count , restoration percent / times , count , percent; +# the "\"indicates new line, +# NO FREE SPACES! +# Default: +# 60:3,5000,90.0/4,5000,80.0/5,5000,80.0/6,5000,70.0/7,5000,70.0/8,5000,60.0/9,5000,50.0;\ +# 75:3,10000,90.0/4,10000,80.0/5,10000,80.0/6,10000,70.0/7,10000,70.0/8,10000,60.0/9,10000,50.0;\ +# 79:3,20000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +# 81:3,30000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +# 84:3,60000,90.0/4,60000,80.0/5,60000,80.0/6,60000,70.0/7,60000,70.0/8,60000,60.0/9,60000,50.0;\ +# 86:3,125000,90.0/4,125000,80.0/5,125000,80.0/6,125000,70.0/7,125000,70.0/8,125000,60.0/9,125000,50.0;\ +# 88:3,240000,90.0/4,240000,80.0/5,240000,80.0/6,240000,70.0/7,240000,70.0/8,240000,60.0/9,240000,50.0;\ +# 90:3,400000,90.0/4,400000,80.0/5,400000,80.0/6,400000,70.0/7,400000,70.0/8,400000,60.0/9,400000,50.0; + +SecondResurrectList = 60:3,5000,90.0/4,5000,80.0/5,5000,80.0/6,5000,70.0/7,5000,70.0/8,5000,60.0/9,5000,50.0;\ +75:3,10000,90.0/4,10000,80.0/5,10000,80.0/6,10000,70.0/7,10000,70.0/8,10000,60.0/9,10000,50.0;\ +79:3,20000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +81:3,30000,90.0/4,20000,80.0/5,20000,80.0/6,20000,70.0/7,20000,70.0/8,20000,60.0/9,20000,50.0;\ +84:3,60000,90.0/4,60000,80.0/5,60000,80.0/6,60000,70.0/7,60000,70.0/8,60000,60.0/9,60000,50.0;\ +86:3,125000,90.0/4,125000,80.0/5,125000,80.0/6,125000,70.0/7,125000,70.0/8,125000,60.0/9,125000,50.0;\ +88:3,240000,90.0/4,240000,80.0/5,240000,80.0/6,240000,70.0/7,240000,70.0/8,240000,60.0/9,240000,50.0;\ +90:3,400000,90.0/4,400000,80.0/5,400000,80.0/6,400000,70.0/7,400000,70.0/8,400000,60.0/9,400000,50.0; + + # --------------------------------------------------------------------------- # Skills & Effects # --------------------------------------------------------------------------- diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/Config.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/Config.java index ec05c79b47..d1ba0ebe02 100644 --- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/Config.java @@ -44,6 +44,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -65,6 +66,7 @@ import org.l2jmobius.gameserver.enums.GeoType; import org.l2jmobius.gameserver.enums.IllegalActionPunishmentType; import org.l2jmobius.gameserver.model.Location; import org.l2jmobius.gameserver.model.holders.ItemHolder; +import org.l2jmobius.gameserver.model.holders.ResurrectByPaymentHolder; import org.l2jmobius.gameserver.util.FloodProtectorConfig; import org.l2jmobius.gameserver.util.Util; @@ -891,6 +893,12 @@ public class Config public static int MAX_CONNECTION_PER_IP; public static boolean ENABLE_CMD_LINE_LOGIN; public static boolean ONLY_CMD_LINE_LOGIN; + public static boolean RESURRECT_BY_PAYMENT_ENABLED; + public static int RESURRECT_BY_PAYMENT_MAX_FREE_TIMES; + public static int RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM; + public static Map> RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES; + public static int RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM; + public static Map> RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES; // Magic Lamp public static boolean ENABLE_MAGIC_LAMP; @@ -1661,6 +1669,93 @@ public class Config HP_REGEN_MULTIPLIER = characterConfig.getDouble("HpRegenMultiplier", 100) / 100; MP_REGEN_MULTIPLIER = characterConfig.getDouble("MpRegenMultiplier", 100) / 100; CP_REGEN_MULTIPLIER = characterConfig.getDouble("CpRegenMultiplier", 100) / 100; + + RESURRECT_BY_PAYMENT_ENABLED = characterConfig.getBoolean("EnabledResurrectByPay", true); + if (RESURRECT_BY_PAYMENT_ENABLED) + { + Map RESURRECT_DATA = new TreeMap<>(); + RESURRECT_BY_PAYMENT_MAX_FREE_TIMES = characterConfig.getInt("MaxFreeResurrectionsByDay", 0); + RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM = characterConfig.getInt("FirstResurrectItemID", 0); + final String[] firstPaymentSplit = characterConfig.getString("FirstResurrectList", "").split(";"); + RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES = new TreeMap<>(); + for (String timeData : firstPaymentSplit) + { + RESURRECT_DATA = new TreeMap<>(); + final String[] timeSplit = timeData.split(":"); + if (timeSplit.length != 2) + { + LOGGER.warning("[FirstResurrectList]: invalid config property -> Level data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + final String[] dataSplit = timeSplit[1].split("/"); + for (String data : dataSplit) + { + while (data.contains(" ")) + { + data = data.replace(" ", ""); + } + final String[] values = data.split(","); + if (values.length < 3) + { + LOGGER.warning("[FirstResurrectList]: invalid config property -> Times data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + try + { + final int time = Integer.parseInt(values[0]); + final int count = Integer.parseInt(values[1]); + final double percent = Double.parseDouble(values[2]); + RESURRECT_DATA.put(time, new ResurrectByPaymentHolder(time, count, percent)); + } + catch (Exception e) + { + LOGGER.warning("[FirstResurrectList]: invalid config property -> Times data cannot be parsed. Look on exception " + timeSplit[0]); + e.printStackTrace(); + } + } + RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.put(Integer.parseInt(timeSplit[0]), RESURRECT_DATA); + } + final String[] secondPaymentSplit = characterConfig.getString("SecondResurrectList", "").split(";"); + RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES = new TreeMap<>(); + for (String timeData : secondPaymentSplit) + { + RESURRECT_DATA = new TreeMap<>(); + final String[] timeSplit = timeData.split(":"); + if (timeSplit.length != 2) + { + LOGGER.warning("[SecondResurrectList]: invalid config property -> Level data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + final String[] dataSplit = timeSplit[1].split("/"); + for (String data : dataSplit) + { + while (data.contains(" ")) + { + data = data.replace(" ", ""); + } + final String[] values = data.split(","); + if (values.length < 3) + { + LOGGER.warning("[SecondResurrectList]: invalid config property -> Times data cannot be parsed. Looking like not exist " + timeSplit[0]); + continue; + } + try + { + final int time = Integer.parseInt(values[0]); + final int count = Integer.parseInt(values[1]); + final double percent = Double.parseDouble(values[2]); + RESURRECT_DATA.put(time, new ResurrectByPaymentHolder(time, count, percent)); + } + catch (Exception e) + { + LOGGER.warning("[SecondResurrectList]: invalid config property -> Times data cannot be parsed. Look on exception " + timeSplit[0]); + e.printStackTrace(); + } + } + RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.put(Integer.parseInt(timeSplit[0]), RESURRECT_DATA); + } + RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM = characterConfig.getInt("SecondResurrectItemID", 0); + } ENABLE_MODIFY_SKILL_DURATION = characterConfig.getBoolean("EnableModifySkillDuration", false); if (ENABLE_MODIFY_SKILL_DURATION) { diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java index 2d27475d04..1d283647f1 100644 --- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java +++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/DailyTaskManager.java @@ -141,6 +141,7 @@ public class DailyTaskManager resetDailyMissionRewards(); resetAttendanceRewards(); resetVip(); + resetResurrectionByPayment(); } private void onSave() @@ -668,6 +669,32 @@ public class DailyTaskManager LOGGER.info("LimitShopData has been resetted."); } + private void resetResurrectionByPayment() + { + // Update data for offline players. + try (Connection con = DatabaseFactory.getConnection()) + { + try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_variables WHERE var=?")) + { + ps.setString(1, PlayerVariables.RESURRECT_BY_PAYMENT_COUNT); + ps.execute(); + } + } + catch (Exception e) + { + LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Could not reset payment resurrection count for players: " + e); + } + + // Update data for online players. + for (Player player : World.getInstance().getPlayers()) + { + player.getVariables().remove(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT); + player.getVariables().storeMe(); + } + + LOGGER.info("Daily payment resurrection count for player has been resetted."); + } + private void resetDailyHennaPattern() { // Update data for offline players. diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java new file mode 100644 index 0000000000..15e61c74cd --- /dev/null +++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/holders/ResurrectByPaymentHolder.java @@ -0,0 +1,49 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.l2jmobius.gameserver.model.holders; + +/** + * @author Index + */ +public class ResurrectByPaymentHolder +{ + private final int _time; + private final int _amount; + private final double _resurrectPercent; + + public ResurrectByPaymentHolder(int time, int amount, double percent) + { + _time = time; + _amount = amount; + _resurrectPercent = percent; + } + + public int getTime() + { + return _time; + } + + public int getAmount() + { + return _amount; + } + + public double getResurrectPercent() + { + return _resurrectPercent; + } +} diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java index e7c0ae175b..1196724657 100644 --- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java +++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/variables/PlayerVariables.java @@ -80,6 +80,7 @@ public class PlayerVariables extends AbstractVariables public static final String STAT_INT = "STAT_INT"; public static final String STAT_WIT = "STAT_WIT"; public static final String STAT_MEN = "STAT_MEN"; + public static final String RESURRECT_BY_PAYMENT_COUNT = "RESURRECT_BY_PAYMENT_COUNT"; public static final String CLAN_JOIN_TIME = "CLAN_JOIN_TIME"; public static final String HENNA1_DURATION = "HENNA1_DURATION"; public static final String HENNA2_DURATION = "HENNA2_DURATION"; diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java index 703b7702f9..ce1feef717 100644 --- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java +++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java @@ -16,6 +16,11 @@ */ package org.l2jmobius.gameserver.network.clientpackets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.threads.ThreadPool; import org.l2jmobius.gameserver.data.xml.ClanHallData; @@ -29,7 +34,9 @@ import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.events.EventType; import org.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; +import org.l2jmobius.gameserver.model.holders.ResurrectByPaymentHolder; import org.l2jmobius.gameserver.model.instancezone.Instance; +import org.l2jmobius.gameserver.model.item.instance.Item; import org.l2jmobius.gameserver.model.quest.Event; import org.l2jmobius.gameserver.model.residences.ClanHall; import org.l2jmobius.gameserver.model.residences.ResidenceFunctionType; @@ -38,8 +45,11 @@ import org.l2jmobius.gameserver.model.siege.Castle.CastleFunction; import org.l2jmobius.gameserver.model.siege.Fort; import org.l2jmobius.gameserver.model.siege.Fort.FortFunction; import org.l2jmobius.gameserver.model.skill.CommonSkill; +import org.l2jmobius.gameserver.model.variables.PlayerVariables; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.PacketLogger; +import org.l2jmobius.gameserver.network.SystemMessageId; +import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * @version $Revision: 1.7.2.3.2.6 $ $Date: 2005/03/27 15:29:30 $ @@ -48,11 +58,18 @@ public class RequestRestartPoint implements IClientIncomingPacket { protected int _requestedPointType; protected boolean _continuation; + protected int _resItemID; + protected int _resCount; @Override public boolean read(GameClient client, PacketReader packet) { _requestedPointType = packet.readD(); + if (packet.getReadableBytes() != 0) + { + _resItemID = packet.readD(); + _resCount = packet.readD(); + } return true; } @@ -270,6 +287,80 @@ public class RequestRestartPoint implements IClientIncomingPacket { break; } + case 9: + { + if (Config.RESURRECT_BY_PAYMENT_ENABLED) + { + if (!player.isDead()) + { + break; + } + + final int originalValue = player.getVariables().getInt(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, 0); + if (originalValue < Config.RESURRECT_BY_PAYMENT_MAX_FREE_TIMES) + { + player.getVariables().set(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, originalValue + 1); + player.doRevive(100.0); + loc = MapRegionManager.getInstance().getTeleToLocation(player, TeleportWhereType.TOWN); + player.teleToLocation(loc, true, instance); + break; + } + + final int firstID = Config.RESURRECT_BY_PAYMENT_ENABLED ? Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM : 91663; + final int secondID = Config.RESURRECT_BY_PAYMENT_ENABLED ? Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM : 57; + Map> resMAP = null; + Item item = null; + if (_resItemID == firstID) + { + resMAP = Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES; + item = player.getInventory().getItemByItemId(Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_ITEM); + } + else if (_resItemID == secondID) + { + resMAP = Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES; + item = player.getInventory().getItemByItemId(Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM); + } + if ((resMAP == null) || (item == null)) + { + break; + } + + final List levelList = new ArrayList<>(resMAP.keySet()); + for (int level : levelList) + { + if ((player.getLevel() >= level) && (levelList.lastIndexOf(level) != (levelList.size() - 1))) + { + continue; + } + + int maxResTime; + try + { + maxResTime = resMAP.get(level).keySet().stream().max(Integer::compareTo).get(); + } + catch (Exception e) + { + player.sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS)); + e.printStackTrace(); + return; + } + + final int getValue = maxResTime <= originalValue ? maxResTime : originalValue + 1; + final ResurrectByPaymentHolder rbph = resMAP.get(level).get(getValue); + if (item.getCount() < rbph.getAmount()) + { + return; + } + + player.getVariables().set(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, originalValue + 1); + player.destroyItem("item revive", item, rbph.getAmount(), player, true); + player.doRevive(rbph.getResurrectPercent()); + loc = MapRegionManager.getInstance().getTeleToLocation(player, TeleportWhereType.TOWN); + player.teleToLocation(loc, true, instance); + break; + } + } + } case 27: // to jail { if (!player.isJailed()) diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/Die.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/Die.java index caafead57a..c443dd0c52 100644 --- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/Die.java +++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/Die.java @@ -16,16 +16,23 @@ */ package org.l2jmobius.gameserver.network.serverpackets; +import java.util.ArrayList; +import java.util.List; + +import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketWriter; import org.l2jmobius.gameserver.instancemanager.CastleManager; import org.l2jmobius.gameserver.instancemanager.FortManager; import org.l2jmobius.gameserver.model.SiegeClan; import org.l2jmobius.gameserver.model.actor.Creature; +import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.clan.Clan; +import org.l2jmobius.gameserver.model.holders.ResurrectByPaymentHolder; import org.l2jmobius.gameserver.model.siege.Castle; import org.l2jmobius.gameserver.model.siege.Fort; import org.l2jmobius.gameserver.model.skill.BuffInfo; import org.l2jmobius.gameserver.model.skill.CommonSkill; +import org.l2jmobius.gameserver.model.variables.PlayerVariables; import org.l2jmobius.gameserver.network.OutgoingPackets; /** @@ -37,6 +44,7 @@ public class Die implements IClientOutgoingPacket private final boolean _isSweepable; private int _flags = 1; // To nearest village. private int _delayFeather = 0; + private Player _player; public Die(Creature creature) { @@ -44,7 +52,8 @@ public class Die implements IClientOutgoingPacket _isSweepable = creature.isAttackable() && creature.isSweepActive(); if (creature.isPlayer()) { - final Clan clan = creature.getActingPlayer().getClan(); + _player = creature.getActingPlayer(); + final Clan clan = _player.getClan(); boolean isInCastleDefense = false; boolean isInFortDefense = false; SiegeClan siegeClan = null; @@ -108,8 +117,113 @@ public class Die implements IClientOutgoingPacket packet.writeD(_delayFeather); // Feather item time. packet.writeC(0); // Hide die animation. packet.writeD(0); - packet.writeD(0); + if ((_player != null) && Config.RESURRECT_BY_PAYMENT_ENABLED) + { + int resurrectTimes = _player.getVariables().getInt(PlayerVariables.RESURRECT_BY_PAYMENT_COUNT, 0) + 1; + int originalValue = resurrectTimes - 1; + if (originalValue < Config.RESURRECT_BY_PAYMENT_MAX_FREE_TIMES) + { + packet.writeD(Config.RESURRECT_BY_PAYMENT_MAX_FREE_TIMES - originalValue); // free round resurrection + packet.writeD(0); // Adena resurrection + packet.writeD(0); // Adena count% + packet.writeD(0); // L-Coin resurrection + packet.writeD(0); // L-Coin count% + } + else + { + packet.writeD(0); + getValues(_player, packet, originalValue); + } + } + else + { + packet.writeD(1); // free round resurrection + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + } packet.writeD(0); return true; } + + private void getValues(Player player, PacketWriter packet, int originalValue) + { + if ((Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES == null) || (Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES == null)) + { + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + return; + } + + final List levelListFirst = new ArrayList<>(Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.keySet()); + final List levelListSecond = new ArrayList<>(Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.keySet()); + for (int level : levelListSecond) + { + if (Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.isEmpty()) + { + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + break; + } + + if ((player.getLevel() >= level) && (levelListSecond.lastIndexOf(level) != (levelListSecond.size() - 1))) + { + continue; + } + + int maxResTime; + try + { + maxResTime = Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.get(level).keySet().stream().max(Integer::compareTo).get(); + } + catch (Exception e) + { + packet.writeD(0); // Adena resurrection + packet.writeD(-1); // Adena count% + return; + } + + int getValue = maxResTime <= originalValue ? maxResTime : originalValue + 1; + ResurrectByPaymentHolder rbph = Config.RESURRECT_BY_PAYMENT_SECOND_RESURRECT_VALUES.get(level).get(getValue); + packet.writeD(rbph.getAmount()); // Adena resurrection + packet.writeD(Math.toIntExact(Math.round(rbph.getResurrectPercent()))); // Adena count% + break; + } + + for (int level : levelListFirst) + { + if (Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.isEmpty()) + { + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + break; + } + + if ((player.getLevel() >= level) && (levelListFirst.lastIndexOf(level) != (levelListFirst.size() - 1))) + { + continue; + } + + int maxResTime; + try + { + maxResTime = Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.get(level).keySet().stream().max(Integer::compareTo).get(); + } + catch (Exception e) + { + packet.writeD(0); // L-Coin resurrection + packet.writeD(-1); // L-Coin count% + return; + } + + final int getValue = maxResTime <= originalValue ? maxResTime : originalValue + 1; + ResurrectByPaymentHolder rbph = Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.get(level).get(getValue); + packet.writeD(rbph.getAmount()); // L-Coin resurrection + packet.writeD(Math.toIntExact(Math.round(rbph.getResurrectPercent()))); // L-Coin count% + break; + } + } } diff --git a/L2J_Mobius_Essence_6.2_Vanguard/readme.txt b/L2J_Mobius_Essence_6.2_Vanguard/readme.txt index 77f21a2d99..e60c549690 100644 --- a/L2J_Mobius_Essence_6.2_Vanguard/readme.txt +++ b/L2J_Mobius_Essence_6.2_Vanguard/readme.txt @@ -132,7 +132,7 @@ Sylph: https://eu.4game.com/patchnotes/lineage2essence/281/ -Hellbound spawns Frost Lord: https://eu.4game.com/patchnotes/lineage2essence/329/ --Updated skill trees +-Resurrection with payment -Frost Lord castle Battle Chronicle: https://eu.4game.com/patchnotes/lineage2essence/353/