Resurrection with payment.
Contributed by Index.
This commit is contained in:
@@ -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
|
||||
# ---------------------------------------------------------------------------
|
||||
|
@@ -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<Integer, Map<Integer, ResurrectByPaymentHolder>> RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES;
|
||||
public static int RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM;
|
||||
public static Map<Integer, Map<Integer, ResurrectByPaymentHolder>> 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<Integer, ResurrectByPaymentHolder> 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)
|
||||
{
|
||||
|
@@ -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;
|
||||
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@@ -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;
|
||||
|
@@ -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<Integer, Map<Integer, ResurrectByPaymentHolder>> 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<Integer> 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())
|
||||
|
@@ -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<Integer> levelListFirst = new ArrayList<>(Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.keySet());
|
||||
final List<Integer> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
# ---------------------------------------------------------------------------
|
||||
|
@@ -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<Integer, Map<Integer, ResurrectByPaymentHolder>> RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES;
|
||||
public static int RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM;
|
||||
public static Map<Integer, Map<Integer, ResurrectByPaymentHolder>> 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<Integer, ResurrectByPaymentHolder> 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)
|
||||
{
|
||||
|
@@ -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.
|
||||
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@@ -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";
|
||||
|
@@ -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<Integer, Map<Integer, ResurrectByPaymentHolder>> 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<Integer> 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())
|
||||
|
@@ -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<Integer> levelListFirst = new ArrayList<>(Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.keySet());
|
||||
final List<Integer> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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/
|
||||
|
@@ -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
|
||||
# ---------------------------------------------------------------------------
|
||||
|
@@ -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<Integer, Map<Integer, ResurrectByPaymentHolder>> RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES;
|
||||
public static int RESURRECT_BY_PAYMENT_SECOND_RESURRECT_ITEM;
|
||||
public static Map<Integer, Map<Integer, ResurrectByPaymentHolder>> 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<Integer, ResurrectByPaymentHolder> 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)
|
||||
{
|
||||
|
@@ -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.
|
||||
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@@ -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";
|
||||
|
@@ -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<Integer, Map<Integer, ResurrectByPaymentHolder>> 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<Integer> 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())
|
||||
|
@@ -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<Integer> levelListFirst = new ArrayList<>(Config.RESURRECT_BY_PAYMENT_FIRST_RESURRECT_VALUES.keySet());
|
||||
final List<Integer> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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/
|
||||
|
Reference in New Issue
Block a user