From c457a227e66aa810201c2f270bdd5c3c978dfe5f Mon Sep 17 00:00:00 2001
From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com>
Date: Thu, 20 Oct 2022 21:29:23 +0000
Subject: [PATCH] Addition of revenge system.
---
.../sql/game/character_revenge_history.sql | 21 +
.../handlers/effecthandlers/Teleport.java | 5 +-
.../game/data/stats/skills/60000-60099.xml | 30 +-
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../org/l2jmobius/gameserver/Shutdown.java | 11 +
.../gameserver/enums/RevengeType.java | 27 +
.../instancemanager/DailyTaskManager.java | 2 +
.../gameserver/instancemanager/IdManager.java | 1 +
.../instancemanager/RankManager.java | 26 +
.../RevengeHistoryManager.java | 480 ++++++++++++++++++
.../gameserver/model/actor/Player.java | 71 +++
.../model/holders/RevengeHistoryHolder.java | 223 ++++++++
.../gameserver/model/skill/CommonSkill.java | 1 +
.../gameserver/model/skill/SkillCaster.java | 6 +
.../gameserver/network/ExIncomingPackets.java | 15 +-
.../network/clientpackets/EnterWorld.java | 2 +
...stExPvpBookShareRevengeKillerLocation.java | 51 ++
.../RequestExPvpBookShareRevengeList.java | 55 ++
...vpBookShareRevengeReqShareRevengeInfo.java | 71 +++
...ookShareRevengeSharedTeleportToKiller.java | 52 ++
...ExPvpBookShareRevengeTeleportToKiller.java | 57 +++
.../ExPvpBookShareRevengeKillerLocation.java | 46 ++
.../revenge/ExPvpBookShareRevengeList.java | 83 +++
.../ExPvpBookShareRevengeNewRevengeInfo.java | 49 ++
L2J_Mobius_Essence_5.2_FrostLord/readme.txt | 1 +
.../sql/game/character_revenge_history.sql | 21 +
.../handlers/effecthandlers/Teleport.java | 5 +-
.../game/data/stats/skills/60000-60099.xml | 44 +-
.../org/l2jmobius/gameserver/GameServer.java | 2 +
.../org/l2jmobius/gameserver/Shutdown.java | 11 +
.../gameserver/enums/RevengeType.java | 27 +
.../instancemanager/DailyTaskManager.java | 2 +
.../gameserver/instancemanager/IdManager.java | 1 +
.../instancemanager/RankManager.java | 26 +
.../RevengeHistoryManager.java | 480 ++++++++++++++++++
.../gameserver/model/actor/Player.java | 93 +++-
.../model/actor/stat/PlayerStat.java | 40 ++
.../model/holders/RevengeHistoryHolder.java | 223 ++++++++
.../gameserver/model/skill/CommonSkill.java | 1 +
.../gameserver/model/skill/SkillCaster.java | 37 +-
.../gameserver/network/ExIncomingPackets.java | 15 +-
.../network/clientpackets/EnterWorld.java | 2 +
...stExPvpBookShareRevengeKillerLocation.java | 51 ++
.../RequestExPvpBookShareRevengeList.java | 55 ++
...vpBookShareRevengeReqShareRevengeInfo.java | 71 +++
...ookShareRevengeSharedTeleportToKiller.java | 52 ++
...ExPvpBookShareRevengeTeleportToKiller.java | 57 +++
.../ExPvpBookShareRevengeKillerLocation.java | 46 ++
.../revenge/ExPvpBookShareRevengeList.java | 83 +++
.../ExPvpBookShareRevengeNewRevengeInfo.java | 49 ++
L2J_Mobius_Essence_6.2_Vanguard/readme.txt | 1 +
51 files changed, 2825 insertions(+), 58 deletions(-)
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/dist/db_installer/sql/game/character_revenge_history.sql
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/enums/RevengeType.java
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/RevengeHistoryManager.java
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/holders/RevengeHistoryHolder.java
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeKillerLocation.java
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeList.java
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeReqShareRevengeInfo.java
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeSharedTeleportToKiller.java
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeTeleportToKiller.java
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeKillerLocation.java
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeList.java
create mode 100644 L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeNewRevengeInfo.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/dist/db_installer/sql/game/character_revenge_history.sql
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/enums/RevengeType.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/RevengeHistoryManager.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/holders/RevengeHistoryHolder.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeKillerLocation.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeList.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeReqShareRevengeInfo.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeSharedTeleportToKiller.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeTeleportToKiller.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeKillerLocation.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeList.java
create mode 100644 L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeNewRevengeInfo.java
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/dist/db_installer/sql/game/character_revenge_history.sql b/L2J_Mobius_Essence_5.2_FrostLord/dist/db_installer/sql/game/character_revenge_history.sql
new file mode 100644
index 0000000000..5be9d849cf
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/dist/db_installer/sql/game/character_revenge_history.sql
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS `character_revenge_history`;
+CREATE TABLE IF NOT EXISTS `character_revenge_history` (
+ `charId` int(10) UNSIGNED NOT NULL,
+ `type` int(10) NOT NULL,
+ `killer_name` VARCHAR(35),
+ `killer_clan` VARCHAR(45),
+ `killer_level` int UNSIGNED NOT NULL,
+ `killer_race` int NOT NULL DEFAULT 0,
+ `killer_class` int NOT NULL DEFAULT 0,
+ `victim_name` VARCHAR(35),
+ `victim_clan` VARCHAR(45),
+ `victim_level` int UNSIGNED NOT NULL,
+ `victim_race` int NOT NULL DEFAULT 0,
+ `victim_class` int NOT NULL DEFAULT 0,
+ `shared` TINYINT(1) NOT NULL DEFAULT 0,
+ `show_location_remaining` int NOT NULL DEFAULT 0,
+ `teleport_remaining` int NOT NULL DEFAULT 0,
+ `shared_teleport_remaining` int NOT NULL DEFAULT 0,
+ `kill_time` BIGINT(10) UNSIGNED NOT NULL,
+ `share_time` BIGINT(10) UNSIGNED NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/dist/game/data/scripts/handlers/effecthandlers/Teleport.java b/L2J_Mobius_Essence_5.2_FrostLord/dist/game/data/scripts/handlers/effecthandlers/Teleport.java
index 673f0d4609..6f77938d03 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/dist/game/data/scripts/handlers/effecthandlers/Teleport.java
+++ b/L2J_Mobius_Essence_5.2_FrostLord/dist/game/data/scripts/handlers/effecthandlers/Teleport.java
@@ -52,6 +52,9 @@ public class Teleport extends AbstractEffect
@Override
public void instant(Creature effector, Creature effected, Skill skill, Item item)
{
- effected.teleToLocation(_loc, true, null);
+ if ((_loc.getX() != 0) && (_loc.getY() != 0) && (_loc.getZ() != 0))
+ {
+ effected.teleToLocation(_loc, true, null);
+ }
}
}
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/dist/game/data/stats/skills/60000-60099.xml b/L2J_Mobius_Essence_5.2_FrostLord/dist/game/data/stats/skills/60000-60099.xml
index a70115c588..0f5d872bac 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/dist/game/data/stats/skills/60000-60099.xml
+++ b/L2J_Mobius_Essence_5.2_FrostLord/dist/game/data/stats/skills/60000-60099.xml
@@ -6,34 +6,35 @@
P
5000
-
+
icon.karma
- 10
- P
- 5
+ A2
+ SELF
+ SINGLE
+ 4
+ 1
+ -1
+ true
+ true
+ false
+ true
- -5
- -10
- -15
+ -30
PER
- -5
- -10
- -15
+ -30
PER
- -5
- -10
- -30
+ -40
DIFF
@@ -320,6 +321,9 @@
icon.skill0000
A1
2000
+
+
+
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/GameServer.java
index 7d7fd2d72b..8ef7b8b7aa 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/GameServer.java
@@ -156,6 +156,7 @@ import org.l2jmobius.gameserver.instancemanager.PurgeRankingManager;
import org.l2jmobius.gameserver.instancemanager.QuestManager;
import org.l2jmobius.gameserver.instancemanager.RankManager;
import org.l2jmobius.gameserver.instancemanager.RankingPowerManager;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
import org.l2jmobius.gameserver.instancemanager.SellBuffsManager;
import org.l2jmobius.gameserver.instancemanager.ServerRestartManager;
import org.l2jmobius.gameserver.instancemanager.SharedTeleportManager;
@@ -314,6 +315,7 @@ public class GameServer
AttendanceRewardData.getInstance();
MagicLampData.getInstance();
RandomCraftData.getInstance();
+ RevengeHistoryManager.getInstance();
VipData.getInstance();
printSection("Characters");
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/Shutdown.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/Shutdown.java
index 8da5b7bc14..cc4be61e6a 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/Shutdown.java
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/Shutdown.java
@@ -36,6 +36,7 @@ import org.l2jmobius.gameserver.instancemanager.ItemAuctionManager;
import org.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
import org.l2jmobius.gameserver.instancemanager.PrecautionaryRestartManager;
import org.l2jmobius.gameserver.instancemanager.QuestManager;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.olympiad.Hero;
@@ -145,6 +146,16 @@ public class Shutdown extends Thread
// ignore
}
+ try
+ {
+ RevengeHistoryManager.getInstance().storeMe();
+ LOGGER.info("Saved Revenge History(" + tc.getEstimatedTimeAndRestartCounter() + "ms).");
+ }
+ catch (Throwable t)
+ {
+ // ignore
+ }
+
// ensure all services are stopped
try
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/enums/RevengeType.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/enums/RevengeType.java
new file mode 100644
index 0000000000..962e4f5fe6
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/enums/RevengeType.java
@@ -0,0 +1,27 @@
+/*
+ * 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.enums;
+
+/**
+ * @author Mobius
+ */
+public enum RevengeType
+{
+ OWN_HELP_REQUEST,
+ REVENGE,
+ HELP_REQUEST;
+}
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 547de579c3..8adc39fb95 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
@@ -147,6 +147,8 @@ public class DailyTaskManager
{
GlobalVariablesManager.getInstance().storeMe();
+ RevengeHistoryManager.getInstance().storeMe();
+
if (Olympiad.getInstance().inCompPeriod())
{
Olympiad.getInstance().saveOlympiadStatus();
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/IdManager.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/IdManager.java
index 93bfd8b78c..96a825d4bc 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/IdManager.java
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/IdManager.java
@@ -129,6 +129,7 @@ public class IdManager
cleanCount += statement.executeUpdate("DELETE FROM character_offline_trade_items WHERE character_offline_trade_items.charId NOT IN (SELECT charId FROM characters);");
cleanCount += statement.executeUpdate("DELETE FROM character_tpbookmark WHERE character_tpbookmark.charId NOT IN (SELECT charId FROM characters);");
cleanCount += statement.executeUpdate("DELETE FROM character_variables WHERE character_variables.charId NOT IN (SELECT charId FROM characters);");
+ cleanCount += statement.executeUpdate("DELETE FROM character_revenge_history WHERE character_revenge_history.charId NOT IN (SELECT charId FROM characters);");
cleanCount += statement.executeUpdate("DELETE FROM bot_reported_char_data WHERE bot_reported_char_data.botId NOT IN (SELECT charId FROM characters);");
// Clan
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/RankManager.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/RankManager.java
index bfe1bccd8e..37b2440c44 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/RankManager.java
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/RankManager.java
@@ -19,6 +19,9 @@ package org.l2jmobius.gameserver.instancemanager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
@@ -31,6 +34,7 @@ import org.l2jmobius.gameserver.data.sql.ClanTable;
import org.l2jmobius.gameserver.data.xml.PetDataTable;
import org.l2jmobius.gameserver.model.PetData;
import org.l2jmobius.gameserver.model.StatSet;
+import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.olympiad.Hero;
@@ -435,6 +439,28 @@ public class RankManager
return 0;
}
+ public Collection getTop50()
+ {
+ final List result = new LinkedList<>();
+ for (int i = 1; i <= 50; i++)
+ {
+ final StatSet rank = _mainList.get(i);
+ if (rank == null)
+ {
+ break;
+ }
+
+ final Player player = World.getInstance().getPlayer(rank.getInt("charId"));
+ if ((player == null) || (player.isOnlineInt() != 1))
+ {
+ continue;
+ }
+
+ result.add(player);
+ }
+ return result;
+ }
+
public static RankManager getInstance()
{
return SingletonHolder.INSTANCE;
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/RevengeHistoryManager.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/RevengeHistoryManager.java
new file mode 100644
index 0000000000..13415a79a4
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/instancemanager/RevengeHistoryManager.java
@@ -0,0 +1,480 @@
+/*
+ * 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.instancemanager;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Logger;
+
+import org.l2jmobius.commons.database.DatabaseFactory;
+import org.l2jmobius.gameserver.enums.RevengeType;
+import org.l2jmobius.gameserver.model.StatSet;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.model.actor.Summon;
+import org.l2jmobius.gameserver.model.holders.RevengeHistoryHolder;
+import org.l2jmobius.gameserver.model.holders.SkillHolder;
+import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
+import org.l2jmobius.gameserver.model.zone.ZoneId;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.revenge.ExPvpBookShareRevengeKillerLocation;
+import org.l2jmobius.gameserver.network.serverpackets.revenge.ExPvpBookShareRevengeList;
+import org.l2jmobius.gameserver.network.serverpackets.revenge.ExPvpBookShareRevengeNewRevengeInfo;
+
+/**
+ * @author Mobius
+ */
+public class RevengeHistoryManager
+{
+ private static final Logger LOGGER = Logger.getLogger(RevengeHistoryManager.class.getName());
+
+ private static final Map> REVENGE_HISTORY = new ConcurrentHashMap<>();
+ private static final String DELETE_REVENGE_HISTORY = "TRUNCATE TABLE character_revenge_history";
+ private static final String INSERT_REVENGE_HISTORY = "INSERT INTO character_revenge_history (charId, type, killer_name, killer_clan, killer_level, killer_race, killer_class, victim_name, victim_clan, victim_level, victim_race, victim_class, shared, show_location_remaining, teleport_remaining, shared_teleport_remaining, kill_time, share_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ private static final SkillHolder HIDE_SKILL = new SkillHolder(922, 1);
+ private static final long REVENGE_DURATION = 21600000; // Six hours.
+ private static final int[] LOCATION_PRICE =
+ {
+ 0,
+ 50000,
+ 100000,
+ 100000,
+ 200000
+ };
+ private static final int[] TELEPORT_PRICE =
+ {
+ 10,
+ 50,
+ 100,
+ 100,
+ 200
+ };
+
+ protected RevengeHistoryManager()
+ {
+ try (Connection con = DatabaseFactory.getConnection();
+ PreparedStatement ps = con.prepareStatement("SELECT * FROM character_revenge_history"))
+ {
+ ResultSet rs = ps.executeQuery();
+ while (rs.next())
+ {
+ final int charId = rs.getInt("charId");
+ final List history = REVENGE_HISTORY.containsKey(charId) ? REVENGE_HISTORY.get(charId) : new CopyOnWriteArrayList<>();
+ final StatSet killer = new StatSet();
+ killer.set("name", rs.getString("killer_name"));
+ killer.set("clan", rs.getString("killer_clan"));
+ killer.set("level", rs.getInt("killer_level"));
+ killer.set("race", rs.getInt("killer_race"));
+ killer.set("class", rs.getInt("killer_class"));
+ final StatSet victim = new StatSet();
+ victim.set("name", rs.getString("victim_name"));
+ victim.set("clan", rs.getString("victim_clan"));
+ victim.set("level", rs.getInt("victim_level"));
+ victim.set("race", rs.getInt("victim_race"));
+ victim.set("class", rs.getInt("victim_class"));
+ history.add(new RevengeHistoryHolder(killer, victim, RevengeType.values()[rs.getInt("type")], rs.getBoolean("shared"), rs.getInt("show_location_remaining"), rs.getInt("teleport_remaining"), rs.getInt("shared_teleport_remaining"), rs.getLong("kill_time"), rs.getLong("share_time")));
+ REVENGE_HISTORY.put(charId, history);
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.warning("Failed loading revenge history! " + e);
+ }
+ }
+
+ public void storeMe()
+ {
+ for (Entry> entry : REVENGE_HISTORY.entrySet())
+ {
+ final List history = entry.getValue();
+ if (history != null)
+ {
+ final long currentTime = System.currentTimeMillis();
+ final List removals = new ArrayList<>();
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (((holder.getKillTime() != 0) && ((holder.getKillTime() + REVENGE_DURATION) < currentTime)) || //
+ ((holder.getShareTime() != 0) && ((holder.getShareTime() + REVENGE_DURATION) < currentTime)))
+ {
+ removals.add(holder);
+ }
+ }
+ for (RevengeHistoryHolder holder : removals)
+ {
+ history.remove(holder);
+ }
+ }
+ }
+
+ try (Connection con = DatabaseFactory.getConnection();
+ PreparedStatement ps1 = con.prepareStatement(DELETE_REVENGE_HISTORY);
+ PreparedStatement ps2 = con.prepareStatement(INSERT_REVENGE_HISTORY))
+ {
+ ps1.execute();
+
+ for (Entry> entry : REVENGE_HISTORY.entrySet())
+ {
+ final List history = entry.getValue();
+ if ((history == null) || history.isEmpty())
+ {
+ continue;
+ }
+
+ for (RevengeHistoryHolder holder : history)
+ {
+ ps2.clearParameters();
+ ps2.setInt(1, entry.getKey());
+ ps2.setInt(2, holder.getType().ordinal());
+ ps2.setString(3, holder.getKillerName());
+ ps2.setString(4, holder.getKillerClanName());
+ ps2.setInt(5, holder.getKillerLevel());
+ ps2.setInt(6, holder.getKillerRaceId());
+ ps2.setInt(7, holder.getKillerClassId());
+ ps2.setString(8, holder.getVictimName());
+ ps2.setString(9, holder.getVictimClanName());
+ ps2.setInt(10, holder.getVictimLevel());
+ ps2.setInt(11, holder.getVictimRaceId());
+ ps2.setInt(12, holder.getVictimClassId());
+ ps2.setBoolean(13, holder.wasShared());
+ ps2.setInt(14, holder.getShowLocationRemaining());
+ ps2.setInt(15, holder.getTeleportRemaining());
+ ps2.setInt(16, holder.getSharedTeleportRemaining());
+ ps2.setLong(17, holder.getKillTime());
+ ps2.setLong(18, holder.getShareTime());
+ ps2.addBatch();
+ }
+ }
+ ps2.executeBatch();
+ }
+ catch (Exception e)
+ {
+ LOGGER.warning(getClass().getSimpleName() + " Error while saving revenge history. " + e);
+ }
+ }
+
+ public void addNewKill(Player victim, Player killer)
+ {
+ try
+ {
+ boolean found = false;
+ final int victimObjectId = victim.getObjectId();
+ final long currentTime = System.currentTimeMillis();
+ final List removals = new ArrayList<>();
+ final List history = REVENGE_HISTORY.containsKey(victimObjectId) ? REVENGE_HISTORY.get(victimObjectId) : new CopyOnWriteArrayList<>();
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (((holder.getKillTime() != 0) && ((holder.getKillTime() + REVENGE_DURATION) < currentTime)) || //
+ ((holder.getShareTime() != 0) && ((holder.getShareTime() + REVENGE_DURATION) < currentTime)))
+ {
+ removals.add(holder);
+ }
+ else if (holder.getKillerName().equals(killer.getName()))
+ {
+ found = true;
+ }
+ }
+
+ history.removeAll(removals);
+
+ if (!found)
+ {
+ history.add(new RevengeHistoryHolder(killer, victim, RevengeType.REVENGE));
+ REVENGE_HISTORY.put(victimObjectId, history);
+ victim.sendPacket(new ExPvpBookShareRevengeNewRevengeInfo(victim.getName(), killer.getName(), RevengeType.REVENGE));
+ victim.sendPacket(new ExPvpBookShareRevengeList(victim));
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.warning(getClass().getSimpleName() + ": Failed adding revenge history! " + e);
+ }
+ }
+
+ public void locateKiller(Player player, String killerName)
+ {
+ final List history = REVENGE_HISTORY.get(player.getObjectId());
+ if (history == null)
+ {
+ return;
+ }
+
+ RevengeHistoryHolder revenge = null;
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (holder.getKillerName().equals(killerName))
+ {
+ revenge = holder;
+ break;
+ }
+ }
+
+ if (revenge == null)
+ {
+ return;
+ }
+
+ final Player killer = World.getInstance().getPlayer(killerName);
+ if ((killer == null) || !killer.isOnline())
+ {
+ player.sendPacket(SystemMessageId.THE_ENEMY_IS_OFFLINE_AND_CANNOT_BE_FOUND_RIGHT_NOW);
+ return;
+ }
+
+ if (killer.isInsideZone(ZoneId.PEACE) || killer.isInInstance() || killer.isInTimedHuntingZone() || killer.isInsideZone(ZoneId.SIEGE) //
+ || player.isDead() || player.isInInstance() || player.isInTimedHuntingZone() || player.isInsideZone(ZoneId.SIEGE))
+ {
+ player.sendPacket(SystemMessageId.THE_CHARACTER_IS_IN_A_LOCATION_WHERE_IT_IS_IMPOSSIBLE_TO_USE_THIS_FUNCTION);
+ return;
+ }
+
+ if (revenge.getShowLocationRemaining() > 0)
+ {
+ final int price = LOCATION_PRICE[Math.min(LOCATION_PRICE.length - revenge.getShowLocationRemaining(), LOCATION_PRICE.length - 1)];
+ if (player.reduceAdena("Revenge find location", price, player, true))
+ {
+ revenge.setShowLocationRemaining(revenge.getShowLocationRemaining() - 1);
+ player.sendPacket(new ExPvpBookShareRevengeKillerLocation(killer));
+ player.sendPacket(new ExPvpBookShareRevengeList(player));
+ }
+ }
+ }
+
+ private boolean checkTeleportConditions(Player player, Player killer)
+ {
+ if ((killer == null) || !killer.isOnline())
+ {
+ player.sendPacket(SystemMessageId.THE_ENEMY_IS_OFFLINE_AND_CANNOT_BE_FOUND_RIGHT_NOW);
+ return false;
+ }
+ if (killer.isTeleporting() || killer.isInsideZone(ZoneId.PEACE) || killer.isInInstance() || killer.isInTimedHuntingZone() || killer.isInsideZone(ZoneId.SIEGE) || killer.isInsideZone(ZoneId.NO_BOOKMARK))
+ {
+ player.sendPacket(SystemMessageId.THE_CHARACTER_IS_IN_A_LOCATION_WHERE_IT_IS_IMPOSSIBLE_TO_USE_THIS_FUNCTION);
+ return false;
+ }
+ if (killer.isDead())
+ {
+ player.sendPacket(SystemMessageId.THE_CHARACTER_IS_IN_A_LOCATION_WHERE_IT_IS_IMPOSSIBLE_TO_USE_THIS_FUNCTION);
+ return false;
+ }
+
+ if (player.isInInstance() || player.isInTimedHuntingZone() || player.isInsideZone(ZoneId.SIEGE))
+ {
+ player.sendPacket(SystemMessageId.THE_CHARACTER_IS_IN_A_LOCATION_WHERE_IT_IS_IMPOSSIBLE_TO_USE_THIS_FUNCTION);
+ return false;
+ }
+ if (player.isDead())
+ {
+ player.sendPacket(SystemMessageId.YOU_CANNOT_USE_TELEPORT_WHILE_YOU_ARE_DEAD);
+ return false;
+ }
+ if (player.isInCombat() || player.isDisabled())
+ {
+ player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_IN_COMBAT);
+ return false;
+ }
+
+ return true;
+ }
+
+ public void teleportToKiller(Player player, String killerName)
+ {
+ final List history = REVENGE_HISTORY.get(player.getObjectId());
+ if (history == null)
+ {
+ return;
+ }
+
+ RevengeHistoryHolder revenge = null;
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (holder.getKillerName().equals(killerName))
+ {
+ revenge = holder;
+ break;
+ }
+ }
+
+ if (revenge == null)
+ {
+ return;
+ }
+
+ if (revenge.wasShared())
+ {
+ return;
+ }
+
+ final Player killer = World.getInstance().getPlayer(killerName);
+ if (!checkTeleportConditions(player, killer))
+ {
+ return;
+ }
+
+ if (revenge.getTeleportRemaining() > 0)
+ {
+ final int price = TELEPORT_PRICE[Math.min(TELEPORT_PRICE.length - revenge.getTeleportRemaining(), TELEPORT_PRICE.length - 1)];
+ if (player.destroyItemByItemId("Revenge Teleport", Inventory.LCOIN_ID, price, player, true))
+ {
+ revenge.setTeleportRemaining(revenge.getTeleportRemaining() - 1);
+ HIDE_SKILL.getSkill().applyEffects(player, player);
+ for (Summon summon : player.getServitorsAndPets())
+ {
+ HIDE_SKILL.getSkill().applyEffects(summon, summon);
+ }
+ player.teleToLocation(killer.getLocation());
+ }
+ }
+ }
+
+ public void teleportToSharedKiller(Player player, String victimName, String killerName)
+ {
+ if (player.getName().equals(killerName))
+ {
+ return;
+ }
+
+ final List history = REVENGE_HISTORY.get(player.getObjectId());
+ if (history == null)
+ {
+ return;
+ }
+
+ RevengeHistoryHolder revenge = null;
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (holder.getVictimName().equals(victimName) && holder.getKillerName().equals(killerName))
+ {
+ revenge = holder;
+ break;
+ }
+ }
+
+ if (revenge == null)
+ {
+ return;
+ }
+
+ if (!revenge.wasShared())
+ {
+ return;
+ }
+
+ final Player killer = World.getInstance().getPlayer(killerName);
+ if (!checkTeleportConditions(player, killer))
+ {
+ return;
+ }
+
+ if ((revenge.getSharedTeleportRemaining() > 0) && player.destroyItemByItemId("Revenge Teleport", Inventory.LCOIN_ID, 100, player, true))
+ {
+ revenge.setSharedTeleportRemaining(revenge.getSharedTeleportRemaining() - 1);
+ HIDE_SKILL.getSkill().applyEffects(player, player);
+ for (Summon summon : player.getServitorsAndPets())
+ {
+ HIDE_SKILL.getSkill().applyEffects(summon, summon);
+ }
+ player.teleToLocation(killer.getLocation());
+ }
+ }
+
+ public void requestHelp(Player player, Player killer, int type)
+ {
+ final List history = REVENGE_HISTORY.get(player.getObjectId());
+ if (history == null)
+ {
+ return;
+ }
+
+ RevengeHistoryHolder revenge = null;
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (holder.getKillerName().equals(killer.getName()))
+ {
+ revenge = holder;
+ break;
+ }
+ }
+
+ if (revenge == null)
+ {
+ return;
+ }
+
+ if (revenge.wasShared())
+ {
+ return;
+ }
+
+ if (player.reduceAdena("Revenge request help", 100000, player, true))
+ {
+ final long currentTime = System.currentTimeMillis();
+ revenge.setShared(true);
+ revenge.setType(RevengeType.OWN_HELP_REQUEST);
+ revenge.setShareTime(currentTime);
+
+ final Collection targets = type == 1 ? (player.getClan() == null ? Collections.emptyList() : player.getClan().getOnlineMembers(player.getObjectId())) : type == 2 ? RankManager.getInstance().getTop50() : Collections.emptyList();
+ for (Player target : targets)
+ {
+ if (target == killer)
+ {
+ continue;
+ }
+
+ final int targetObjectId = target.getObjectId();
+ final List targetHistory = REVENGE_HISTORY.containsKey(targetObjectId) ? REVENGE_HISTORY.get(targetObjectId) : new CopyOnWriteArrayList<>();
+ for (RevengeHistoryHolder temp : targetHistory)
+ {
+ if (temp.getVictimName().equals(player.getName()) && temp.getKillerName().equals(killer.getName()) && (temp != revenge))
+ {
+ targetHistory.remove(temp);
+ break;
+ }
+ }
+ targetHistory.add(new RevengeHistoryHolder(killer, player, RevengeType.HELP_REQUEST, 1, revenge.getKillTime(), currentTime));
+ REVENGE_HISTORY.put(targetObjectId, targetHistory);
+
+ target.sendPacket(new ExPvpBookShareRevengeNewRevengeInfo(player.getName(), killer.getName(), RevengeType.HELP_REQUEST));
+ target.sendPacket(new ExPvpBookShareRevengeList(target));
+ }
+ }
+ player.sendPacket(new ExPvpBookShareRevengeList(player));
+ }
+
+ public Collection getHistory(Player player)
+ {
+ return REVENGE_HISTORY.get(player.getObjectId());
+ }
+
+ public static RevengeHistoryManager getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final RevengeHistoryManager INSTANCE = new RevengeHistoryManager();
+ }
+}
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/actor/Player.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/actor/Player.java
index 9a17929089..1be5a6813d 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/actor/Player.java
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/actor/Player.java
@@ -136,6 +136,7 @@ import org.l2jmobius.gameserver.instancemanager.MentorManager;
import org.l2jmobius.gameserver.instancemanager.PunishmentManager;
import org.l2jmobius.gameserver.instancemanager.QuestManager;
import org.l2jmobius.gameserver.instancemanager.RecipeManager;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
import org.l2jmobius.gameserver.instancemanager.SellBuffsManager;
import org.l2jmobius.gameserver.instancemanager.SiegeManager;
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
@@ -534,6 +535,8 @@ public class Player extends Playable
/** The PvP Flag state of the Player (0=White, 1=Purple) */
private byte _pvpFlag;
+ private int _einhasadOverseeingLevel = 0;
+
private final List _lastDamageTaken = new ArrayList<>(21);
/** The Fame of this Player */
@@ -2173,6 +2176,67 @@ public class Player extends Playable
sendPacket(new SystemMessage(SystemMessageId.YOUR_REPUTATION_HAS_BEEN_CHANGED_TO_S1).addInt(getReputation()));
broadcastReputation();
+
+ applyKarmaPenalty();
+ }
+
+ public void applyKarmaPenalty()
+ {
+ final int expectedLevel;
+ if (getReputation() < -33840)
+ {
+ expectedLevel = 5;
+ }
+ else if (getReputation() < -30240)
+ {
+ expectedLevel = 4;
+ }
+ else if (getReputation() < -27000)
+ {
+ expectedLevel = 3;
+ }
+ else if (getReputation() < -18000)
+ {
+ expectedLevel = 2;
+ }
+ else if (getReputation() < 0)
+ {
+ expectedLevel = 1;
+ }
+ else
+ {
+ expectedLevel = 0;
+ }
+
+ if (expectedLevel > 0)
+ {
+ if (_einhasadOverseeingLevel != expectedLevel)
+ {
+ getEffectList().stopSkillEffects(SkillFinishType.REMOVED, CommonSkill.EINHASAD_OVERSEEING.getId());
+ SkillData.getInstance().getSkill(CommonSkill.EINHASAD_OVERSEEING.getId(), expectedLevel).applyEffects(this, this);
+ }
+ }
+ else
+ {
+ getEffectList().stopSkillEffects(SkillFinishType.REMOVED, CommonSkill.EINHASAD_OVERSEEING.getId());
+ getServitors().values().forEach(s -> s.getEffectList().stopSkillEffects(SkillFinishType.REMOVED, CommonSkill.EINHASAD_OVERSEEING.getId()));
+ if (getPet() != null)
+ {
+ getPet().getEffectList().stopSkillEffects(SkillFinishType.REMOVED, CommonSkill.EINHASAD_OVERSEEING.getId());
+ }
+ }
+
+ _einhasadOverseeingLevel = expectedLevel;
+ }
+
+ public int getEinhasadOverseeingLevel()
+ {
+ return _einhasadOverseeingLevel;
+ }
+
+ public void setEinhasadOverseeingLevel(int level)
+ {
+ _einhasadOverseeingLevel = level;
}
public int getWeightPenalty()
@@ -4897,6 +4961,11 @@ public class Player extends Playable
setTotalDeaths(getTotalDeaths() + 1);
+ if (pk != this)
+ {
+ RevengeHistoryManager.getInstance().addNewKill(this, pk);
+ }
+
// pvp/pk item rewards
if (!(Config.DISABLE_REWARDS_IN_INSTANCES && (getInstanceId() != 0)) && //
!(Config.DISABLE_REWARDS_IN_PVP_ZONES && isInsideZone(ZoneId.PVP)))
@@ -10343,6 +10412,8 @@ public class Player extends Playable
DecayTaskManager.getInstance().cancel(this);
}
+ applyKarmaPenalty();
+
sendPacket(new EtcStatusUpdate(this));
_revivePet = false;
_reviveRequested = 0;
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/holders/RevengeHistoryHolder.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/holders/RevengeHistoryHolder.java
new file mode 100644
index 0000000000..af044bcebb
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/holders/RevengeHistoryHolder.java
@@ -0,0 +1,223 @@
+/*
+ * 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;
+
+import org.l2jmobius.gameserver.enums.RevengeType;
+import org.l2jmobius.gameserver.model.StatSet;
+import org.l2jmobius.gameserver.model.actor.Player;
+
+/**
+ * @author Mobius
+ */
+public class RevengeHistoryHolder
+{
+ private final String _killerName;
+ private final String _killerClanName;
+ private final int _killerLevel;
+ private final int _killerRaceId;
+ private final int _killerClassId;
+ private final long _killTime;
+ private final String _victimName;
+ private final String _victimClanName;
+ private final int _victimLevel;
+ private final int _victimRaceId;
+ private final int _victimClassId;
+ private RevengeType _type;
+ private boolean _wasShared;
+ private long _shareTime;
+ private int _showLocationRemaining;
+ private int _teleportRemaining;
+ private int _sharedTeleportRemaining;
+
+ public RevengeHistoryHolder(Player killer, Player victim, RevengeType type)
+ {
+ _type = type;
+ _wasShared = false;
+ _killerName = killer.getName();
+ _killerClanName = killer.getClan() == null ? "" : killer.getClan().getName();
+ _killerLevel = killer.getLevel();
+ _killerRaceId = killer.getRace().ordinal();
+ _killerClassId = killer.getClassId().getId();
+ _killTime = System.currentTimeMillis();
+ _shareTime = 0;
+ _showLocationRemaining = 5;
+ _teleportRemaining = 5;
+ _sharedTeleportRemaining = 1;
+ _victimName = victim.getName();
+ _victimClanName = victim.getClan() == null ? "" : victim.getClan().getName();
+ _victimLevel = victim.getLevel();
+ _victimRaceId = victim.getRace().ordinal();
+ _victimClassId = victim.getClassId().getId();
+ }
+
+ public RevengeHistoryHolder(Player killer, Player victim, RevengeType type, int sharedTeleportRemaining, long killTime, long shareTime)
+ {
+ _type = type;
+ _wasShared = true;
+ _killerName = killer.getName();
+ _killerClanName = killer.getClan() == null ? "" : killer.getClan().getName();
+ _killerLevel = killer.getLevel();
+ _killerRaceId = killer.getRace().ordinal();
+ _killerClassId = killer.getClassId().getId();
+ _killTime = killTime;
+ _shareTime = shareTime;
+ _showLocationRemaining = 0;
+ _teleportRemaining = 0;
+ _sharedTeleportRemaining = sharedTeleportRemaining;
+ _victimName = victim.getName();
+ _victimClanName = victim.getClan() == null ? "" : victim.getClan().getName();
+ _victimLevel = victim.getLevel();
+ _victimRaceId = victim.getRace().ordinal();
+ _victimClassId = victim.getClassId().getId();
+ }
+
+ public RevengeHistoryHolder(StatSet killer, StatSet victim, RevengeType type, boolean wasShared, int showLocationRemaining, int teleportRemaining, int sharedTeleportRemaining, long killTime, long shareTime)
+ {
+ _type = type;
+ _wasShared = wasShared;
+ _killerName = killer.getString("name");
+ _killerClanName = killer.getString("clan");
+ _killerLevel = killer.getInt("level");
+ _killerRaceId = killer.getInt("race");
+ _killerClassId = killer.getInt("class");
+ _killTime = killTime;
+ _shareTime = shareTime;
+ _showLocationRemaining = showLocationRemaining;
+ _teleportRemaining = teleportRemaining;
+ _sharedTeleportRemaining = sharedTeleportRemaining;
+ _victimName = victim.getString("name");
+ _victimClanName = victim.getString("clan");
+ _victimLevel = victim.getInt("level");
+ _victimRaceId = victim.getInt("race");
+ _victimClassId = victim.getInt("class");
+ }
+
+ public RevengeType getType()
+ {
+ return _type;
+ }
+
+ public void setType(RevengeType type)
+ {
+ _type = type;
+ }
+
+ public boolean wasShared()
+ {
+ return _wasShared;
+ }
+
+ public void setShared(boolean wasShared)
+ {
+ _wasShared = wasShared;
+ }
+
+ public String getKillerName()
+ {
+ return _killerName;
+ }
+
+ public String getKillerClanName()
+ {
+ return _killerClanName;
+ }
+
+ public int getKillerLevel()
+ {
+ return _killerLevel;
+ }
+
+ public int getKillerRaceId()
+ {
+ return _killerRaceId;
+ }
+
+ public int getKillerClassId()
+ {
+ return _killerClassId;
+ }
+
+ public long getKillTime()
+ {
+ return _killTime;
+ }
+
+ public long getShareTime()
+ {
+ return _shareTime;
+ }
+
+ public void setShareTime(long shareTime)
+ {
+ _shareTime = shareTime;
+ }
+
+ public int getShowLocationRemaining()
+ {
+ return _showLocationRemaining;
+ }
+
+ public void setShowLocationRemaining(int count)
+ {
+ _showLocationRemaining = count;
+ }
+
+ public int getTeleportRemaining()
+ {
+ return _teleportRemaining;
+ }
+
+ public void setTeleportRemaining(int count)
+ {
+ _teleportRemaining = count;
+ }
+
+ public int getSharedTeleportRemaining()
+ {
+ return _sharedTeleportRemaining;
+ }
+
+ public void setSharedTeleportRemaining(int count)
+ {
+ _sharedTeleportRemaining = count;
+ }
+
+ public String getVictimName()
+ {
+ return _victimName;
+ }
+
+ public String getVictimClanName()
+ {
+ return _victimClanName;
+ }
+
+ public int getVictimLevel()
+ {
+ return _victimLevel;
+ }
+
+ public int getVictimRaceId()
+ {
+ return _victimRaceId;
+ }
+
+ public int getVictimClassId()
+ {
+ return _victimClassId;
+ }
+}
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/skill/CommonSkill.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/skill/CommonSkill.java
index 1243e35f39..8adfc24af9 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/skill/CommonSkill.java
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/skill/CommonSkill.java
@@ -78,6 +78,7 @@ public enum CommonSkill
MEN_INCREASE_BONUS_1(45196, 1),
MEN_INCREASE_BONUS_2(45196, 2),
MEN_INCREASE_BONUS_3(45196, 3),
+ EINHASAD_OVERSEEING(60002, 1),
TELEPORT(60018, 1);
private final SkillHolder _holder;
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/skill/SkillCaster.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/skill/SkillCaster.java
index f870ade2b2..a16af95a50 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/skill/SkillCaster.java
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/model/skill/SkillCaster.java
@@ -1168,6 +1168,12 @@ public class SkillCaster implements Runnable
return false;
}
+ // Einhasad Overseeing
+ if (skill.hasEffectType(EffectType.TELEPORT) && (player.getEinhasadOverseeingLevel() == 5))
+ {
+ return false;
+ }
+
// Events.
if (player.isOnEvent())
{
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
index 5b3e949d65..643f5f50a5 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
@@ -141,6 +141,11 @@ import org.l2jmobius.gameserver.network.clientpackets.ranking.RequestPvpRankingL
import org.l2jmobius.gameserver.network.clientpackets.ranking.RequestPvpRankingMyInfo;
import org.l2jmobius.gameserver.network.clientpackets.ranking.RequestRankingCharInfo;
import org.l2jmobius.gameserver.network.clientpackets.ranking.RequestRankingCharRankers;
+import org.l2jmobius.gameserver.network.clientpackets.revenge.RequestExPvpBookShareRevengeKillerLocation;
+import org.l2jmobius.gameserver.network.clientpackets.revenge.RequestExPvpBookShareRevengeList;
+import org.l2jmobius.gameserver.network.clientpackets.revenge.RequestExPvpBookShareRevengeReqShareRevengeInfo;
+import org.l2jmobius.gameserver.network.clientpackets.revenge.RequestExPvpBookShareRevengeSharedTeleportToKiller;
+import org.l2jmobius.gameserver.network.clientpackets.revenge.RequestExPvpBookShareRevengeTeleportToKiller;
import org.l2jmobius.gameserver.network.clientpackets.sayune.RequestFlyMove;
import org.l2jmobius.gameserver.network.clientpackets.sayune.RequestFlyMoveStart;
import org.l2jmobius.gameserver.network.clientpackets.settings.ExInteractModify;
@@ -660,11 +665,11 @@ public enum ExIncomingPackets implements IIncomingPackets
EX_COLLECTION_SUMMARY(0x1DF, null, ConnectionState.IN_GAME),
EX_COLLECTION_REGISTER(0x1E0, RequestCollectionRegister::new, ConnectionState.IN_GAME),
EX_COLLECTION_RECEIVE_REWARD(0x1E1, RequestCollectionReceiveReward::new, ConnectionState.IN_GAME),
- EX_PVPBOOK_SHARE_REVENGE_LIST(0x1E2, null, ConnectionState.IN_GAME),
- EX_PVPBOOK_SHARE_REVENGE_REQ_SHARE_REVENGEINFO(0x1E3, null, ConnectionState.IN_GAME),
- EX_PVPBOOK_SHARE_REVENGE_KILLER_LOCATION(0x1E4, null, ConnectionState.IN_GAME),
- EX_PVPBOOK_SHARE_REVENGE_TELEPORT_TO_KILLER(0x1E5, null, ConnectionState.IN_GAME),
- EX_PVPBOOK_SHARE_REVENGE_SHARED_TELEPORT_TO_KILLER(0x1E6, null, ConnectionState.IN_GAME),
+ EX_PVPBOOK_SHARE_REVENGE_LIST(0x1E2, RequestExPvpBookShareRevengeList::new, ConnectionState.IN_GAME),
+ EX_PVPBOOK_SHARE_REVENGE_REQ_SHARE_REVENGEINFO(0x1E3, RequestExPvpBookShareRevengeReqShareRevengeInfo::new, ConnectionState.IN_GAME),
+ EX_PVPBOOK_SHARE_REVENGE_KILLER_LOCATION(0x1E4, RequestExPvpBookShareRevengeKillerLocation::new, ConnectionState.IN_GAME),
+ EX_PVPBOOK_SHARE_REVENGE_TELEPORT_TO_KILLER(0x1E5, RequestExPvpBookShareRevengeTeleportToKiller::new, ConnectionState.IN_GAME),
+ EX_PVPBOOK_SHARE_REVENGE_SHARED_TELEPORT_TO_KILLER(0x1E6, RequestExPvpBookShareRevengeSharedTeleportToKiller::new, ConnectionState.IN_GAME),
EX_PENALTY_ITEM_LIST(0x1E7, null, ConnectionState.IN_GAME),
EX_PENALTY_ITEM_RESTORE(0x1E8, null, ConnectionState.IN_GAME),
EX_USER_WATCHER_TARGET_LIST(0x1E9, null, ConnectionState.IN_GAME),
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
index 5816f830d2..8465de5b99 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
@@ -682,6 +682,8 @@ public class EnterWorld implements IClientIncomingPacket
player.sendPacket(new ItemDeletionInfo());
+ player.applyKarmaPenalty();
+
// Activate first agathion when available.
final Item agathion = player.getInventory().unEquipItemInBodySlot(ItemTemplate.SLOT_AGATHION);
if (agathion != null)
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeKillerLocation.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeKillerLocation.java
new file mode 100644
index 0000000000..ac5cd36b13
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeKillerLocation.java
@@ -0,0 +1,51 @@
+/*
+ * 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.network.clientpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPvpBookShareRevengeKillerLocation implements IClientIncomingPacket
+{
+ private String _killerName;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ packet.readString(); // Victim name.
+ _killerName = packet.readString();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final Player player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ RevengeHistoryManager.getInstance().locateKiller(player, _killerName);
+ }
+}
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeList.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeList.java
new file mode 100644
index 0000000000..257e28d67c
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeList.java
@@ -0,0 +1,55 @@
+/*
+ * 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.network.clientpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.revenge.ExPvpBookShareRevengeList;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPvpBookShareRevengeList implements IClientIncomingPacket
+{
+ private int _objectId;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _objectId = packet.readD();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final Player player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ if (_objectId != player.getObjectId())
+ {
+ return;
+ }
+
+ player.sendPacket(new ExPvpBookShareRevengeList(player));
+ }
+}
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeReqShareRevengeInfo.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeReqShareRevengeInfo.java
new file mode 100644
index 0000000000..21105f159c
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeReqShareRevengeInfo.java
@@ -0,0 +1,71 @@
+/*
+ * 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.network.clientpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPvpBookShareRevengeReqShareRevengeInfo implements IClientIncomingPacket
+{
+ private String _victimName;
+ private String _killerName;
+ private int _type;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _victimName = packet.readString();
+ _killerName = packet.readString();
+ _type = packet.readD();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final Player player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ if (!_victimName.equals(player.getName()))
+ {
+ return;
+ }
+
+ final Player killer = World.getInstance().getPlayer(_killerName);
+ if ((killer == null) || !killer.isOnline())
+ {
+ SystemMessage sm = new SystemMessage(SystemMessageId.S1_CURRENTLY_OFFLINE);
+ sm.addString(_killerName);
+ player.sendPacket(sm);
+ return;
+ }
+
+ RevengeHistoryManager.getInstance().requestHelp(player, killer, _type);
+ }
+}
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeSharedTeleportToKiller.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeSharedTeleportToKiller.java
new file mode 100644
index 0000000000..ad1c3ce25f
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeSharedTeleportToKiller.java
@@ -0,0 +1,52 @@
+/*
+ * 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.network.clientpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPvpBookShareRevengeSharedTeleportToKiller implements IClientIncomingPacket
+{
+ private String _victimName;
+ private String _killerName;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _victimName = packet.readString();
+ _killerName = packet.readString();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final Player player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ RevengeHistoryManager.getInstance().teleportToSharedKiller(player, _victimName, _killerName);
+ }
+}
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeTeleportToKiller.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeTeleportToKiller.java
new file mode 100644
index 0000000000..3dc8ba3a86
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeTeleportToKiller.java
@@ -0,0 +1,57 @@
+/*
+ * 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.network.clientpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPvpBookShareRevengeTeleportToKiller implements IClientIncomingPacket
+{
+ private String _victimName;
+ private String _killerName;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _victimName = packet.readString();
+ _killerName = packet.readString();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final Player player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ if (!_victimName.equals(player.getName()))
+ {
+ return;
+ }
+
+ RevengeHistoryManager.getInstance().teleportToKiller(player, _killerName);
+ }
+}
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeKillerLocation.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeKillerLocation.java
new file mode 100644
index 0000000000..40cd3d3505
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeKillerLocation.java
@@ -0,0 +1,46 @@
+/*
+ * 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.network.serverpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author Mobius
+ */
+public class ExPvpBookShareRevengeKillerLocation implements IClientOutgoingPacket
+{
+ private final Player _player;
+
+ public ExPvpBookShareRevengeKillerLocation(Player player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_PVPBOOK_SHARE_REVENGE_KILLER_LOCATION.writeId(packet);
+ packet.writeString(_player.getName());
+ packet.writeD(_player.getX());
+ packet.writeD(_player.getY());
+ packet.writeD(_player.getZ());
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeList.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeList.java
new file mode 100644
index 0000000000..c0836c2ec8
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeList.java
@@ -0,0 +1,83 @@
+/*
+ * 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.network.serverpackets.revenge;
+
+import java.util.Collection;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.model.holders.RevengeHistoryHolder;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author Mobius
+ */
+public class ExPvpBookShareRevengeList implements IClientOutgoingPacket
+{
+ private final Collection _history;
+
+ public ExPvpBookShareRevengeList(Player player)
+ {
+ _history = RevengeHistoryManager.getInstance().getHistory(player);
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_PVPBOOK_SHARE_REVENGE_LIST.writeId(packet);
+ if (_history == null)
+ {
+ packet.writeC(1); // CurrentPage
+ packet.writeC(1); // MaxPage
+ packet.writeD(0);
+ }
+ else
+ {
+ packet.writeC(1); // CurrentPage
+ packet.writeC(1); // MaxPage
+ packet.writeD(_history.size());
+ for (RevengeHistoryHolder holder : _history)
+ {
+ packet.writeD(holder.getType().ordinal()); // ShareType (2 - help request, 1 - revenge, 0 - both)
+ packet.writeD((int) (holder.getKillTime() / 1000)); // KilledTime
+ packet.writeD(holder.getShowLocationRemaining()); // ShowKillerCount
+ packet.writeD(holder.getTeleportRemaining()); // TeleportKillerCount
+ packet.writeD(holder.getSharedTeleportRemaining()); // SharedTeleportKillerCount
+ packet.writeD(0); // KilledUserDBID
+ packet.writeString(holder.getVictimName()); // KilledUserName
+ packet.writeString(holder.getVictimClanName()); // KilledUserPledgeName
+ packet.writeD(holder.getVictimLevel()); // KilledUserLevel
+ packet.writeD(holder.getVictimRaceId()); // KilledUserRace
+ packet.writeD(holder.getVictimClassId()); // KilledUserClass
+ packet.writeD(0); // KillUserDBID
+ packet.writeString(holder.getKillerName()); // KillUserName
+ packet.writeString(holder.getKillerClanName()); // KillUserPledgeName
+ packet.writeD(holder.getKillerLevel()); // KillUserLevel
+ packet.writeD(holder.getKillerRaceId()); // KillUserRace
+ packet.writeD(holder.getKillerClassId()); // KillUserClass
+ Player killer = World.getInstance().getPlayer(holder.getKillerName());
+ packet.writeD((killer != null) && killer.isOnline() ? 2 : 0); // KillUserOnline (2 - online, 0 - offline)
+ packet.writeD(0); // KillUserKarma
+ packet.writeD((int) (holder.getShareTime() / 1000)); // nSharedTime
+ }
+ }
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeNewRevengeInfo.java b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeNewRevengeInfo.java
new file mode 100644
index 0000000000..28cb903401
--- /dev/null
+++ b/L2J_Mobius_Essence_5.2_FrostLord/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeNewRevengeInfo.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.network.serverpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.enums.RevengeType;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author Mobius
+ */
+public class ExPvpBookShareRevengeNewRevengeInfo implements IClientOutgoingPacket
+{
+ private final String _victimName;
+ private final String _killerName;
+ private final RevengeType _type;
+
+ public ExPvpBookShareRevengeNewRevengeInfo(String victimName, String killerName, RevengeType type)
+ {
+ _victimName = victimName;
+ _killerName = killerName;
+ _type = type;
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_PVPBOOK_SHARE_REVENGE_NEW_REVENGEINFO.writeId(packet);
+ packet.writeD(_type.ordinal());
+ packet.writeString(_victimName);
+ packet.writeString(_killerName);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_5.2_FrostLord/readme.txt b/L2J_Mobius_Essence_5.2_FrostLord/readme.txt
index d885184bf2..d62bc0da4b 100644
--- a/L2J_Mobius_Essence_5.2_FrostLord/readme.txt
+++ b/L2J_Mobius_Essence_5.2_FrostLord/readme.txt
@@ -136,6 +136,7 @@ Sylph: https://eu.4game.com/patchnotes/lineage2essence/281/
Frost Lord: https://eu.4game.com/patchnotes/lineage2essence/329/
-Resurrection with payment
-Frost Lord castle
+-Revenge system
Customs:
-Newbie Helper NPC location info
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/dist/db_installer/sql/game/character_revenge_history.sql b/L2J_Mobius_Essence_6.2_Vanguard/dist/db_installer/sql/game/character_revenge_history.sql
new file mode 100644
index 0000000000..5be9d849cf
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/dist/db_installer/sql/game/character_revenge_history.sql
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS `character_revenge_history`;
+CREATE TABLE IF NOT EXISTS `character_revenge_history` (
+ `charId` int(10) UNSIGNED NOT NULL,
+ `type` int(10) NOT NULL,
+ `killer_name` VARCHAR(35),
+ `killer_clan` VARCHAR(45),
+ `killer_level` int UNSIGNED NOT NULL,
+ `killer_race` int NOT NULL DEFAULT 0,
+ `killer_class` int NOT NULL DEFAULT 0,
+ `victim_name` VARCHAR(35),
+ `victim_clan` VARCHAR(45),
+ `victim_level` int UNSIGNED NOT NULL,
+ `victim_race` int NOT NULL DEFAULT 0,
+ `victim_class` int NOT NULL DEFAULT 0,
+ `shared` TINYINT(1) NOT NULL DEFAULT 0,
+ `show_location_remaining` int NOT NULL DEFAULT 0,
+ `teleport_remaining` int NOT NULL DEFAULT 0,
+ `shared_teleport_remaining` int NOT NULL DEFAULT 0,
+ `kill_time` BIGINT(10) UNSIGNED NOT NULL,
+ `share_time` BIGINT(10) UNSIGNED NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/dist/game/data/scripts/handlers/effecthandlers/Teleport.java b/L2J_Mobius_Essence_6.2_Vanguard/dist/game/data/scripts/handlers/effecthandlers/Teleport.java
index 673f0d4609..6f77938d03 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/dist/game/data/scripts/handlers/effecthandlers/Teleport.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/dist/game/data/scripts/handlers/effecthandlers/Teleport.java
@@ -52,6 +52,9 @@ public class Teleport extends AbstractEffect
@Override
public void instant(Creature effector, Creature effected, Skill skill, Item item)
{
- effected.teleToLocation(_loc, true, null);
+ if ((_loc.getX() != 0) && (_loc.getY() != 0) && (_loc.getZ() != 0))
+ {
+ effected.teleToLocation(_loc, true, null);
+ }
}
}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/dist/game/data/stats/skills/60000-60099.xml b/L2J_Mobius_Essence_6.2_Vanguard/dist/game/data/stats/skills/60000-60099.xml
index a70115c588..778a790e05 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/dist/game/data/stats/skills/60000-60099.xml
+++ b/L2J_Mobius_Essence_6.2_Vanguard/dist/game/data/stats/skills/60000-60099.xml
@@ -6,38 +6,19 @@
P
5000
-
+
icon.karma
- 10
- P
- 5
-
-
-
- -5
- -10
- -15
-
- PER
-
-
-
- -5
- -10
- -15
-
- PER
-
-
-
- -5
- -10
- -30
-
- DIFF
-
-
+ A2
+ SELF
+ SINGLE
+ 4
+ 1
+ -1
+ true
+ true
+ false
+ true
@@ -320,6 +301,9 @@
icon.skill0000
A1
2000
+
+
+
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/GameServer.java
index d3d4987cf4..d511b555fa 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/GameServer.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/GameServer.java
@@ -159,6 +159,7 @@ import org.l2jmobius.gameserver.instancemanager.PurgeRankingManager;
import org.l2jmobius.gameserver.instancemanager.QuestManager;
import org.l2jmobius.gameserver.instancemanager.RankManager;
import org.l2jmobius.gameserver.instancemanager.RankingPowerManager;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
import org.l2jmobius.gameserver.instancemanager.SellBuffsManager;
import org.l2jmobius.gameserver.instancemanager.ServerRestartManager;
import org.l2jmobius.gameserver.instancemanager.SharedTeleportManager;
@@ -322,6 +323,7 @@ public class GameServer
AttendanceRewardData.getInstance();
MagicLampData.getInstance();
RandomCraftData.getInstance();
+ RevengeHistoryManager.getInstance();
VipData.getInstance();
printSection("Characters");
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/Shutdown.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/Shutdown.java
index b22ad02193..22f8e4af27 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/Shutdown.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/Shutdown.java
@@ -36,6 +36,7 @@ import org.l2jmobius.gameserver.instancemanager.ItemAuctionManager;
import org.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
import org.l2jmobius.gameserver.instancemanager.PrecautionaryRestartManager;
import org.l2jmobius.gameserver.instancemanager.QuestManager;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.olympiad.Hero;
@@ -145,6 +146,16 @@ public class Shutdown extends Thread
// ignore
}
+ try
+ {
+ RevengeHistoryManager.getInstance().storeMe();
+ LOGGER.info("Saved Revenge History(" + tc.getEstimatedTimeAndRestartCounter() + "ms).");
+ }
+ catch (Throwable t)
+ {
+ // ignore
+ }
+
// ensure all services are stopped
try
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/enums/RevengeType.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/enums/RevengeType.java
new file mode 100644
index 0000000000..962e4f5fe6
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/enums/RevengeType.java
@@ -0,0 +1,27 @@
+/*
+ * 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.enums;
+
+/**
+ * @author Mobius
+ */
+public enum RevengeType
+{
+ OWN_HELP_REQUEST,
+ REVENGE,
+ HELP_REQUEST;
+}
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 a68e644717..3d71f39fdf 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
@@ -148,6 +148,8 @@ public class DailyTaskManager
{
GlobalVariablesManager.getInstance().storeMe();
+ RevengeHistoryManager.getInstance().storeMe();
+
if (Config.WORLD_EXCHANGE_LAZY_UPDATE)
{
WorldExchangeManager.getInstance().storeMe();
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/IdManager.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/IdManager.java
index 93bfd8b78c..96a825d4bc 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/IdManager.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/IdManager.java
@@ -129,6 +129,7 @@ public class IdManager
cleanCount += statement.executeUpdate("DELETE FROM character_offline_trade_items WHERE character_offline_trade_items.charId NOT IN (SELECT charId FROM characters);");
cleanCount += statement.executeUpdate("DELETE FROM character_tpbookmark WHERE character_tpbookmark.charId NOT IN (SELECT charId FROM characters);");
cleanCount += statement.executeUpdate("DELETE FROM character_variables WHERE character_variables.charId NOT IN (SELECT charId FROM characters);");
+ cleanCount += statement.executeUpdate("DELETE FROM character_revenge_history WHERE character_revenge_history.charId NOT IN (SELECT charId FROM characters);");
cleanCount += statement.executeUpdate("DELETE FROM bot_reported_char_data WHERE bot_reported_char_data.botId NOT IN (SELECT charId FROM characters);");
// Clan
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/RankManager.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/RankManager.java
index bfe1bccd8e..37b2440c44 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/RankManager.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/RankManager.java
@@ -19,6 +19,9 @@ package org.l2jmobius.gameserver.instancemanager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
@@ -31,6 +34,7 @@ import org.l2jmobius.gameserver.data.sql.ClanTable;
import org.l2jmobius.gameserver.data.xml.PetDataTable;
import org.l2jmobius.gameserver.model.PetData;
import org.l2jmobius.gameserver.model.StatSet;
+import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.olympiad.Hero;
@@ -435,6 +439,28 @@ public class RankManager
return 0;
}
+ public Collection getTop50()
+ {
+ final List result = new LinkedList<>();
+ for (int i = 1; i <= 50; i++)
+ {
+ final StatSet rank = _mainList.get(i);
+ if (rank == null)
+ {
+ break;
+ }
+
+ final Player player = World.getInstance().getPlayer(rank.getInt("charId"));
+ if ((player == null) || (player.isOnlineInt() != 1))
+ {
+ continue;
+ }
+
+ result.add(player);
+ }
+ return result;
+ }
+
public static RankManager getInstance()
{
return SingletonHolder.INSTANCE;
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/RevengeHistoryManager.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/RevengeHistoryManager.java
new file mode 100644
index 0000000000..05d418fa3c
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/instancemanager/RevengeHistoryManager.java
@@ -0,0 +1,480 @@
+/*
+ * 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.instancemanager;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Logger;
+
+import org.l2jmobius.commons.database.DatabaseFactory;
+import org.l2jmobius.gameserver.enums.RevengeType;
+import org.l2jmobius.gameserver.model.StatSet;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.model.actor.Summon;
+import org.l2jmobius.gameserver.model.holders.RevengeHistoryHolder;
+import org.l2jmobius.gameserver.model.holders.SkillHolder;
+import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
+import org.l2jmobius.gameserver.model.zone.ZoneId;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.revenge.ExPvpBookShareRevengeKillerLocation;
+import org.l2jmobius.gameserver.network.serverpackets.revenge.ExPvpBookShareRevengeList;
+import org.l2jmobius.gameserver.network.serverpackets.revenge.ExPvpBookShareRevengeNewRevengeInfo;
+
+/**
+ * @author Mobius
+ */
+public class RevengeHistoryManager
+{
+ private static final Logger LOGGER = Logger.getLogger(RevengeHistoryManager.class.getName());
+
+ private static final Map> REVENGE_HISTORY = new ConcurrentHashMap<>();
+ private static final String DELETE_REVENGE_HISTORY = "TRUNCATE TABLE character_revenge_history";
+ private static final String INSERT_REVENGE_HISTORY = "INSERT INTO character_revenge_history (charId, type, killer_name, killer_clan, killer_level, killer_race, killer_class, victim_name, victim_clan, victim_level, victim_race, victim_class, shared, show_location_remaining, teleport_remaining, shared_teleport_remaining, kill_time, share_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ private static final SkillHolder HIDE_SKILL = new SkillHolder(922, 1);
+ private static final long REVENGE_DURATION = 21600000; // Six hours.
+ private static final int[] LOCATION_PRICE =
+ {
+ 0,
+ 50000,
+ 100000,
+ 100000,
+ 200000
+ };
+ private static final int[] TELEPORT_PRICE =
+ {
+ 10,
+ 50,
+ 100,
+ 100,
+ 200
+ };
+
+ protected RevengeHistoryManager()
+ {
+ try (Connection con = DatabaseFactory.getConnection();
+ PreparedStatement ps = con.prepareStatement("SELECT * FROM character_revenge_history"))
+ {
+ ResultSet rs = ps.executeQuery();
+ while (rs.next())
+ {
+ final int charId = rs.getInt("charId");
+ final List history = REVENGE_HISTORY.containsKey(charId) ? REVENGE_HISTORY.get(charId) : new CopyOnWriteArrayList<>();
+ final StatSet killer = new StatSet();
+ killer.set("name", rs.getString("killer_name"));
+ killer.set("clan", rs.getString("killer_clan"));
+ killer.set("level", rs.getInt("killer_level"));
+ killer.set("race", rs.getInt("killer_race"));
+ killer.set("class", rs.getInt("killer_class"));
+ final StatSet victim = new StatSet();
+ victim.set("name", rs.getString("victim_name"));
+ victim.set("clan", rs.getString("victim_clan"));
+ victim.set("level", rs.getInt("victim_level"));
+ victim.set("race", rs.getInt("victim_race"));
+ victim.set("class", rs.getInt("victim_class"));
+ history.add(new RevengeHistoryHolder(killer, victim, RevengeType.values()[rs.getInt("type")], rs.getBoolean("shared"), rs.getInt("show_location_remaining"), rs.getInt("teleport_remaining"), rs.getInt("shared_teleport_remaining"), rs.getLong("kill_time"), rs.getLong("share_time")));
+ REVENGE_HISTORY.put(charId, history);
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.warning("Failed loading revenge history! " + e);
+ }
+ }
+
+ public void storeMe()
+ {
+ for (Entry> entry : REVENGE_HISTORY.entrySet())
+ {
+ final List history = entry.getValue();
+ if (history != null)
+ {
+ final long currentTime = System.currentTimeMillis();
+ final List removals = new ArrayList<>();
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (((holder.getKillTime() != 0) && ((holder.getKillTime() + REVENGE_DURATION) < currentTime)) || //
+ ((holder.getShareTime() != 0) && ((holder.getShareTime() + REVENGE_DURATION) < currentTime)))
+ {
+ removals.add(holder);
+ }
+ }
+ for (RevengeHistoryHolder holder : removals)
+ {
+ history.remove(holder);
+ }
+ }
+ }
+
+ try (Connection con = DatabaseFactory.getConnection();
+ PreparedStatement ps1 = con.prepareStatement(DELETE_REVENGE_HISTORY);
+ PreparedStatement ps2 = con.prepareStatement(INSERT_REVENGE_HISTORY))
+ {
+ ps1.execute();
+
+ for (Entry> entry : REVENGE_HISTORY.entrySet())
+ {
+ final List history = entry.getValue();
+ if ((history == null) || history.isEmpty())
+ {
+ continue;
+ }
+
+ for (RevengeHistoryHolder holder : history)
+ {
+ ps2.clearParameters();
+ ps2.setInt(1, entry.getKey());
+ ps2.setInt(2, holder.getType().ordinal());
+ ps2.setString(3, holder.getKillerName());
+ ps2.setString(4, holder.getKillerClanName());
+ ps2.setInt(5, holder.getKillerLevel());
+ ps2.setInt(6, holder.getKillerRaceId());
+ ps2.setInt(7, holder.getKillerClassId());
+ ps2.setString(8, holder.getVictimName());
+ ps2.setString(9, holder.getVictimClanName());
+ ps2.setInt(10, holder.getVictimLevel());
+ ps2.setInt(11, holder.getVictimRaceId());
+ ps2.setInt(12, holder.getVictimClassId());
+ ps2.setBoolean(13, holder.wasShared());
+ ps2.setInt(14, holder.getShowLocationRemaining());
+ ps2.setInt(15, holder.getTeleportRemaining());
+ ps2.setInt(16, holder.getSharedTeleportRemaining());
+ ps2.setLong(17, holder.getKillTime());
+ ps2.setLong(18, holder.getShareTime());
+ ps2.addBatch();
+ }
+ }
+ ps2.executeBatch();
+ }
+ catch (Exception e)
+ {
+ LOGGER.warning(getClass().getSimpleName() + " Error while saving revenge history. " + e);
+ }
+ }
+
+ public void addNewKill(Player victim, Player killer)
+ {
+ try
+ {
+ boolean found = false;
+ final int victimObjectId = victim.getObjectId();
+ final long currentTime = System.currentTimeMillis();
+ final List removals = new ArrayList<>();
+ final List history = REVENGE_HISTORY.containsKey(victimObjectId) ? REVENGE_HISTORY.get(victimObjectId) : new CopyOnWriteArrayList<>();
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (((holder.getKillTime() != 0) && ((holder.getKillTime() + REVENGE_DURATION) < currentTime)) || //
+ ((holder.getShareTime() != 0) && ((holder.getShareTime() + REVENGE_DURATION) < currentTime)))
+ {
+ removals.add(holder);
+ }
+ else if (holder.getKillerName().equals(killer.getName()))
+ {
+ found = true;
+ }
+ }
+
+ history.removeAll(removals);
+
+ if (!found)
+ {
+ history.add(new RevengeHistoryHolder(killer, victim, RevengeType.REVENGE));
+ REVENGE_HISTORY.put(victimObjectId, history);
+ victim.sendPacket(new ExPvpBookShareRevengeNewRevengeInfo(victim.getName(), killer.getName(), RevengeType.REVENGE));
+ victim.sendPacket(new ExPvpBookShareRevengeList(victim));
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.warning(getClass().getSimpleName() + ": Failed adding revenge history! " + e);
+ }
+ }
+
+ public void locateKiller(Player player, String killerName)
+ {
+ final List history = REVENGE_HISTORY.get(player.getObjectId());
+ if (history == null)
+ {
+ return;
+ }
+
+ RevengeHistoryHolder revenge = null;
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (holder.getKillerName().equals(killerName))
+ {
+ revenge = holder;
+ break;
+ }
+ }
+
+ if (revenge == null)
+ {
+ return;
+ }
+
+ final Player killer = World.getInstance().getPlayer(killerName);
+ if ((killer == null) || !killer.isOnline())
+ {
+ player.sendPacket(SystemMessageId.THE_ENEMY_IS_OFFLINE_AND_CANNOT_BE_FOUND_RIGHT_NOW);
+ return;
+ }
+
+ if (killer.isInsideZone(ZoneId.PEACE) || killer.isInInstance() || killer.isInTimedHuntingZone() || killer.isInsideZone(ZoneId.SIEGE) //
+ || player.isDead() || player.isInInstance() || player.isInTimedHuntingZone() || player.isInsideZone(ZoneId.SIEGE))
+ {
+ player.sendPacket(SystemMessageId.THE_CHARACTER_IS_IN_A_LOCATION_WHERE_IT_IS_IMPOSSIBLE_TO_USE_THIS_FUNCTION);
+ return;
+ }
+
+ if (revenge.getShowLocationRemaining() > 0)
+ {
+ final int price = LOCATION_PRICE[Math.min(LOCATION_PRICE.length - revenge.getShowLocationRemaining(), LOCATION_PRICE.length - 1)];
+ if (player.reduceAdena("Revenge find location", price, player, true))
+ {
+ revenge.setShowLocationRemaining(revenge.getShowLocationRemaining() - 1);
+ player.sendPacket(new ExPvpBookShareRevengeKillerLocation(killer));
+ player.sendPacket(new ExPvpBookShareRevengeList(player));
+ }
+ }
+ }
+
+ private boolean checkTeleportConditions(Player player, Player killer)
+ {
+ if ((killer == null) || !killer.isOnline())
+ {
+ player.sendPacket(SystemMessageId.THE_ENEMY_IS_OFFLINE_AND_CANNOT_BE_FOUND_RIGHT_NOW);
+ return false;
+ }
+ if (killer.isTeleporting() || killer.isInsideZone(ZoneId.PEACE) || killer.isInInstance() || killer.isInTimedHuntingZone() || killer.isInsideZone(ZoneId.SIEGE) || killer.isInsideZone(ZoneId.NO_BOOKMARK))
+ {
+ player.sendPacket(SystemMessageId.THE_CHARACTER_IS_IN_A_LOCATION_WHERE_IT_IS_IMPOSSIBLE_TO_USE_THIS_FUNCTION);
+ return false;
+ }
+ if (killer.isDead())
+ {
+ player.sendPacket(SystemMessageId.THE_CHARACTER_IS_IN_A_LOCATION_WHERE_IT_IS_IMPOSSIBLE_TO_USE_THIS_FUNCTION);
+ return false;
+ }
+
+ if (player.isInInstance() || player.isInTimedHuntingZone() || player.isInsideZone(ZoneId.SIEGE))
+ {
+ player.sendPacket(SystemMessageId.THE_CHARACTER_IS_IN_A_LOCATION_WHERE_IT_IS_IMPOSSIBLE_TO_USE_THIS_FUNCTION);
+ return false;
+ }
+ if (player.isDead())
+ {
+ player.sendPacket(SystemMessageId.YOU_CANNOT_USE_TELEPORT_WHILE_YOU_ARE_DEAD);
+ return false;
+ }
+ if (player.isInCombat() || player.isDisabled())
+ {
+ player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_WHILE_IN_COMBAT_MODE);
+ return false;
+ }
+
+ return true;
+ }
+
+ public void teleportToKiller(Player player, String killerName)
+ {
+ final List history = REVENGE_HISTORY.get(player.getObjectId());
+ if (history == null)
+ {
+ return;
+ }
+
+ RevengeHistoryHolder revenge = null;
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (holder.getKillerName().equals(killerName))
+ {
+ revenge = holder;
+ break;
+ }
+ }
+
+ if (revenge == null)
+ {
+ return;
+ }
+
+ if (revenge.wasShared())
+ {
+ return;
+ }
+
+ final Player killer = World.getInstance().getPlayer(killerName);
+ if (!checkTeleportConditions(player, killer))
+ {
+ return;
+ }
+
+ if (revenge.getTeleportRemaining() > 0)
+ {
+ final int price = TELEPORT_PRICE[Math.min(TELEPORT_PRICE.length - revenge.getTeleportRemaining(), TELEPORT_PRICE.length - 1)];
+ if (player.destroyItemByItemId("Revenge Teleport", Inventory.LCOIN_ID, price, player, true))
+ {
+ revenge.setTeleportRemaining(revenge.getTeleportRemaining() - 1);
+ HIDE_SKILL.getSkill().applyEffects(player, player);
+ for (Summon summon : player.getServitorsAndPets())
+ {
+ HIDE_SKILL.getSkill().applyEffects(summon, summon);
+ }
+ player.teleToLocation(killer.getLocation());
+ }
+ }
+ }
+
+ public void teleportToSharedKiller(Player player, String victimName, String killerName)
+ {
+ if (player.getName().equals(killerName))
+ {
+ return;
+ }
+
+ final List history = REVENGE_HISTORY.get(player.getObjectId());
+ if (history == null)
+ {
+ return;
+ }
+
+ RevengeHistoryHolder revenge = null;
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (holder.getVictimName().equals(victimName) && holder.getKillerName().equals(killerName))
+ {
+ revenge = holder;
+ break;
+ }
+ }
+
+ if (revenge == null)
+ {
+ return;
+ }
+
+ if (!revenge.wasShared())
+ {
+ return;
+ }
+
+ final Player killer = World.getInstance().getPlayer(killerName);
+ if (!checkTeleportConditions(player, killer))
+ {
+ return;
+ }
+
+ if ((revenge.getSharedTeleportRemaining() > 0) && player.destroyItemByItemId("Revenge Teleport", Inventory.LCOIN_ID, 100, player, true))
+ {
+ revenge.setSharedTeleportRemaining(revenge.getSharedTeleportRemaining() - 1);
+ HIDE_SKILL.getSkill().applyEffects(player, player);
+ for (Summon summon : player.getServitorsAndPets())
+ {
+ HIDE_SKILL.getSkill().applyEffects(summon, summon);
+ }
+ player.teleToLocation(killer.getLocation());
+ }
+ }
+
+ public void requestHelp(Player player, Player killer, int type)
+ {
+ final List history = REVENGE_HISTORY.get(player.getObjectId());
+ if (history == null)
+ {
+ return;
+ }
+
+ RevengeHistoryHolder revenge = null;
+ for (RevengeHistoryHolder holder : history)
+ {
+ if (holder.getKillerName().equals(killer.getName()))
+ {
+ revenge = holder;
+ break;
+ }
+ }
+
+ if (revenge == null)
+ {
+ return;
+ }
+
+ if (revenge.wasShared())
+ {
+ return;
+ }
+
+ if (player.reduceAdena("Revenge request help", 100000, player, true))
+ {
+ final long currentTime = System.currentTimeMillis();
+ revenge.setShared(true);
+ revenge.setType(RevengeType.OWN_HELP_REQUEST);
+ revenge.setShareTime(currentTime);
+
+ final Collection targets = type == 1 ? (player.getClan() == null ? Collections.emptyList() : player.getClan().getOnlineMembers(player.getObjectId())) : type == 2 ? RankManager.getInstance().getTop50() : Collections.emptyList();
+ for (Player target : targets)
+ {
+ if (target == killer)
+ {
+ continue;
+ }
+
+ final int targetObjectId = target.getObjectId();
+ final List targetHistory = REVENGE_HISTORY.containsKey(targetObjectId) ? REVENGE_HISTORY.get(targetObjectId) : new CopyOnWriteArrayList<>();
+ for (RevengeHistoryHolder temp : targetHistory)
+ {
+ if (temp.getVictimName().equals(player.getName()) && temp.getKillerName().equals(killer.getName()) && (temp != revenge))
+ {
+ targetHistory.remove(temp);
+ break;
+ }
+ }
+ targetHistory.add(new RevengeHistoryHolder(killer, player, RevengeType.HELP_REQUEST, 1, revenge.getKillTime(), currentTime));
+ REVENGE_HISTORY.put(targetObjectId, targetHistory);
+
+ target.sendPacket(new ExPvpBookShareRevengeNewRevengeInfo(player.getName(), killer.getName(), RevengeType.HELP_REQUEST));
+ target.sendPacket(new ExPvpBookShareRevengeList(target));
+ }
+ }
+ player.sendPacket(new ExPvpBookShareRevengeList(player));
+ }
+
+ public Collection getHistory(Player player)
+ {
+ return REVENGE_HISTORY.get(player.getObjectId());
+ }
+
+ public static RevengeHistoryManager getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final RevengeHistoryManager INSTANCE = new RevengeHistoryManager();
+ }
+}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/actor/Player.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/actor/Player.java
index 1a855cc06d..3d31023f44 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/actor/Player.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/actor/Player.java
@@ -138,6 +138,7 @@ import org.l2jmobius.gameserver.instancemanager.MentorManager;
import org.l2jmobius.gameserver.instancemanager.PunishmentManager;
import org.l2jmobius.gameserver.instancemanager.QuestManager;
import org.l2jmobius.gameserver.instancemanager.RecipeManager;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
import org.l2jmobius.gameserver.instancemanager.SellBuffsManager;
import org.l2jmobius.gameserver.instancemanager.SiegeManager;
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
@@ -542,6 +543,8 @@ public class Player extends Playable
/** The PvP Flag state of the Player (0=White, 1=Purple) */
private byte _pvpFlag;
+ private int _einhasadOverseeingLevel = 0;
+
private final List _lastDamageTaken = new ArrayList<>(21);
/** The Fame of this Player */
@@ -2198,6 +2201,87 @@ public class Player extends Playable
sendPacket(new SystemMessage(SystemMessageId.YOUR_REPUTATION_HAS_BEEN_CHANGED_TO_S1).addInt(getReputation()));
broadcastReputation();
+
+ applyKarmaPenalty();
+ }
+
+ public void applyKarmaPenalty()
+ {
+ final int expectedLevel;
+ if (getReputation() < -288000)
+ {
+ expectedLevel = 10;
+ }
+ else if (getReputation() < -216000)
+ {
+ expectedLevel = 9;
+ }
+ else if (getReputation() < -144000)
+ {
+ expectedLevel = 8;
+ }
+ else if (getReputation() < -72000)
+ {
+ expectedLevel = 7;
+ }
+ else if (getReputation() < -36000)
+ {
+ expectedLevel = 6;
+ }
+ else if (getReputation() < -33840)
+ {
+ expectedLevel = 5;
+ }
+ else if (getReputation() < -30240)
+ {
+ expectedLevel = 4;
+ }
+ else if (getReputation() < -27000)
+ {
+ expectedLevel = 3;
+ }
+ else if (getReputation() < -18000)
+ {
+ expectedLevel = 2;
+ }
+ else if (getReputation() < 0)
+ {
+ expectedLevel = 1;
+ }
+ else
+ {
+ expectedLevel = 0;
+ }
+
+ if (expectedLevel > 0)
+ {
+ if (_einhasadOverseeingLevel != expectedLevel)
+ {
+ getEffectList().stopSkillEffects(SkillFinishType.REMOVED, CommonSkill.EINHASAD_OVERSEEING.getId());
+ SkillData.getInstance().getSkill(CommonSkill.EINHASAD_OVERSEEING.getId(), expectedLevel).applyEffects(this, this);
+ }
+ }
+ else
+ {
+ getEffectList().stopSkillEffects(SkillFinishType.REMOVED, CommonSkill.EINHASAD_OVERSEEING.getId());
+ getServitors().values().forEach(s -> s.getEffectList().stopSkillEffects(SkillFinishType.REMOVED, CommonSkill.EINHASAD_OVERSEEING.getId()));
+ if (getPet() != null)
+ {
+ getPet().getEffectList().stopSkillEffects(SkillFinishType.REMOVED, CommonSkill.EINHASAD_OVERSEEING.getId());
+ }
+ }
+
+ _einhasadOverseeingLevel = expectedLevel;
+ }
+
+ public int getEinhasadOverseeingLevel()
+ {
+ return _einhasadOverseeingLevel;
+ }
+
+ public void setEinhasadOverseeingLevel(int level)
+ {
+ _einhasadOverseeingLevel = level;
}
public int getWeightPenalty()
@@ -4950,6 +5034,11 @@ public class Player extends Playable
setTotalDeaths(getTotalDeaths() + 1);
+ if (pk != this)
+ {
+ RevengeHistoryManager.getInstance().addNewKill(this, pk);
+ }
+
// pvp/pk item rewards
if (!(Config.DISABLE_REWARDS_IN_INSTANCES && (getInstanceId() != 0)) && //
!(Config.DISABLE_REWARDS_IN_PVP_ZONES && isInsideZone(ZoneId.PVP)))
@@ -8314,7 +8403,7 @@ public class Player extends Playable
if ((hennaPoten != null) && (hennaPoten.getPotenId() > 0) && hennaPoten.isPotentialAvailable() && (hennaPoten.getActiveStep() > 0))
{
final Skill hennaSkill = HennaPatternPotentialData.getInstance().getPotentialSkill(hennaPoten.getPotenId(), i, hennaPoten.getActiveStep());
- if (hennaSkill != null && (hennaSkill.getLevel() > getSkillLevel(hennaSkill.getId())))
+ if ((hennaSkill != null) && (hennaSkill.getLevel() > getSkillLevel(hennaSkill.getId())))
{
addSkill(hennaSkill, false);
}
@@ -10559,6 +10648,8 @@ public class Player extends Playable
DecayTaskManager.getInstance().cancel(this);
}
+ applyKarmaPenalty();
+
sendPacket(new EtcStatusUpdate(this));
_revivePet = false;
_reviveRequested = 0;
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/actor/stat/PlayerStat.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/actor/stat/PlayerStat.java
index ea4c9b6021..6098d996a3 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/actor/stat/PlayerStat.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/actor/stat/PlayerStat.java
@@ -27,6 +27,7 @@ import org.l2jmobius.gameserver.model.Party;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.actor.Summon;
import org.l2jmobius.gameserver.model.actor.instance.Pet;
+import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.events.EventDispatcher;
import org.l2jmobius.gameserver.model.events.EventType;
import org.l2jmobius.gameserver.model.events.impl.creature.player.OnPlayerLevelChanged;
@@ -35,6 +36,7 @@ import org.l2jmobius.gameserver.model.holders.SubClassHolder;
import org.l2jmobius.gameserver.model.item.instance.Item;
import org.l2jmobius.gameserver.model.item.type.WeaponType;
import org.l2jmobius.gameserver.model.skill.AbnormalType;
+import org.l2jmobius.gameserver.model.skill.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas;
import org.l2jmobius.gameserver.model.stats.Stat;
import org.l2jmobius.gameserver.model.zone.ZoneId;
@@ -725,6 +727,44 @@ public class PlayerStat extends PlayableStat
return type == null ? 0 : getValue(type.getDefenseStat(), base);
}
+ @Override
+ public int getReuseTime(Skill skill)
+ {
+ int addedReuse = 0;
+ if (skill.hasEffectType(EffectType.TELEPORT))
+ {
+ switch (getActiveChar().getActingPlayer().getEinhasadOverseeingLevel())
+ {
+ case 6:
+ {
+ addedReuse = 20000;
+ break;
+ }
+ case 7:
+ {
+ addedReuse = 30000;
+ break;
+ }
+ case 8:
+ {
+ addedReuse = 40000;
+ break;
+ }
+ case 9:
+ {
+ addedReuse = 50000;
+ break;
+ }
+ case 10:
+ {
+ addedReuse = 60000;
+ break;
+ }
+ }
+ }
+ return super.getReuseTime(skill) + addedReuse;
+ }
+
@Override
public void recalculateStats(boolean broadcast)
{
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/holders/RevengeHistoryHolder.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/holders/RevengeHistoryHolder.java
new file mode 100644
index 0000000000..af044bcebb
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/holders/RevengeHistoryHolder.java
@@ -0,0 +1,223 @@
+/*
+ * 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;
+
+import org.l2jmobius.gameserver.enums.RevengeType;
+import org.l2jmobius.gameserver.model.StatSet;
+import org.l2jmobius.gameserver.model.actor.Player;
+
+/**
+ * @author Mobius
+ */
+public class RevengeHistoryHolder
+{
+ private final String _killerName;
+ private final String _killerClanName;
+ private final int _killerLevel;
+ private final int _killerRaceId;
+ private final int _killerClassId;
+ private final long _killTime;
+ private final String _victimName;
+ private final String _victimClanName;
+ private final int _victimLevel;
+ private final int _victimRaceId;
+ private final int _victimClassId;
+ private RevengeType _type;
+ private boolean _wasShared;
+ private long _shareTime;
+ private int _showLocationRemaining;
+ private int _teleportRemaining;
+ private int _sharedTeleportRemaining;
+
+ public RevengeHistoryHolder(Player killer, Player victim, RevengeType type)
+ {
+ _type = type;
+ _wasShared = false;
+ _killerName = killer.getName();
+ _killerClanName = killer.getClan() == null ? "" : killer.getClan().getName();
+ _killerLevel = killer.getLevel();
+ _killerRaceId = killer.getRace().ordinal();
+ _killerClassId = killer.getClassId().getId();
+ _killTime = System.currentTimeMillis();
+ _shareTime = 0;
+ _showLocationRemaining = 5;
+ _teleportRemaining = 5;
+ _sharedTeleportRemaining = 1;
+ _victimName = victim.getName();
+ _victimClanName = victim.getClan() == null ? "" : victim.getClan().getName();
+ _victimLevel = victim.getLevel();
+ _victimRaceId = victim.getRace().ordinal();
+ _victimClassId = victim.getClassId().getId();
+ }
+
+ public RevengeHistoryHolder(Player killer, Player victim, RevengeType type, int sharedTeleportRemaining, long killTime, long shareTime)
+ {
+ _type = type;
+ _wasShared = true;
+ _killerName = killer.getName();
+ _killerClanName = killer.getClan() == null ? "" : killer.getClan().getName();
+ _killerLevel = killer.getLevel();
+ _killerRaceId = killer.getRace().ordinal();
+ _killerClassId = killer.getClassId().getId();
+ _killTime = killTime;
+ _shareTime = shareTime;
+ _showLocationRemaining = 0;
+ _teleportRemaining = 0;
+ _sharedTeleportRemaining = sharedTeleportRemaining;
+ _victimName = victim.getName();
+ _victimClanName = victim.getClan() == null ? "" : victim.getClan().getName();
+ _victimLevel = victim.getLevel();
+ _victimRaceId = victim.getRace().ordinal();
+ _victimClassId = victim.getClassId().getId();
+ }
+
+ public RevengeHistoryHolder(StatSet killer, StatSet victim, RevengeType type, boolean wasShared, int showLocationRemaining, int teleportRemaining, int sharedTeleportRemaining, long killTime, long shareTime)
+ {
+ _type = type;
+ _wasShared = wasShared;
+ _killerName = killer.getString("name");
+ _killerClanName = killer.getString("clan");
+ _killerLevel = killer.getInt("level");
+ _killerRaceId = killer.getInt("race");
+ _killerClassId = killer.getInt("class");
+ _killTime = killTime;
+ _shareTime = shareTime;
+ _showLocationRemaining = showLocationRemaining;
+ _teleportRemaining = teleportRemaining;
+ _sharedTeleportRemaining = sharedTeleportRemaining;
+ _victimName = victim.getString("name");
+ _victimClanName = victim.getString("clan");
+ _victimLevel = victim.getInt("level");
+ _victimRaceId = victim.getInt("race");
+ _victimClassId = victim.getInt("class");
+ }
+
+ public RevengeType getType()
+ {
+ return _type;
+ }
+
+ public void setType(RevengeType type)
+ {
+ _type = type;
+ }
+
+ public boolean wasShared()
+ {
+ return _wasShared;
+ }
+
+ public void setShared(boolean wasShared)
+ {
+ _wasShared = wasShared;
+ }
+
+ public String getKillerName()
+ {
+ return _killerName;
+ }
+
+ public String getKillerClanName()
+ {
+ return _killerClanName;
+ }
+
+ public int getKillerLevel()
+ {
+ return _killerLevel;
+ }
+
+ public int getKillerRaceId()
+ {
+ return _killerRaceId;
+ }
+
+ public int getKillerClassId()
+ {
+ return _killerClassId;
+ }
+
+ public long getKillTime()
+ {
+ return _killTime;
+ }
+
+ public long getShareTime()
+ {
+ return _shareTime;
+ }
+
+ public void setShareTime(long shareTime)
+ {
+ _shareTime = shareTime;
+ }
+
+ public int getShowLocationRemaining()
+ {
+ return _showLocationRemaining;
+ }
+
+ public void setShowLocationRemaining(int count)
+ {
+ _showLocationRemaining = count;
+ }
+
+ public int getTeleportRemaining()
+ {
+ return _teleportRemaining;
+ }
+
+ public void setTeleportRemaining(int count)
+ {
+ _teleportRemaining = count;
+ }
+
+ public int getSharedTeleportRemaining()
+ {
+ return _sharedTeleportRemaining;
+ }
+
+ public void setSharedTeleportRemaining(int count)
+ {
+ _sharedTeleportRemaining = count;
+ }
+
+ public String getVictimName()
+ {
+ return _victimName;
+ }
+
+ public String getVictimClanName()
+ {
+ return _victimClanName;
+ }
+
+ public int getVictimLevel()
+ {
+ return _victimLevel;
+ }
+
+ public int getVictimRaceId()
+ {
+ return _victimRaceId;
+ }
+
+ public int getVictimClassId()
+ {
+ return _victimClassId;
+ }
+}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/skill/CommonSkill.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/skill/CommonSkill.java
index 1243e35f39..8adfc24af9 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/skill/CommonSkill.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/skill/CommonSkill.java
@@ -78,6 +78,7 @@ public enum CommonSkill
MEN_INCREASE_BONUS_1(45196, 1),
MEN_INCREASE_BONUS_2(45196, 2),
MEN_INCREASE_BONUS_3(45196, 3),
+ EINHASAD_OVERSEEING(60002, 1),
TELEPORT(60018, 1);
private final SkillHolder _holder;
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/skill/SkillCaster.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/skill/SkillCaster.java
index b125fa3e5e..d7b2338655 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/skill/SkillCaster.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/model/skill/SkillCaster.java
@@ -833,13 +833,46 @@ public class SkillCaster implements Runnable
}
else
{
+ int addedTime = 0;
+ if (skill.hasEffectType(EffectType.TELEPORT) && creature.isPlayer())
+ {
+ switch (creature.getActingPlayer().getEinhasadOverseeingLevel())
+ {
+ case 6:
+ {
+ addedTime = 2000;
+ break;
+ }
+ case 7:
+ {
+ addedTime = 3000;
+ break;
+ }
+ case 8:
+ {
+ addedTime = 4000;
+ break;
+ }
+ case 9:
+ {
+ addedTime = 5000;
+ break;
+ }
+ case 10:
+ {
+ addedTime = 6000;
+ break;
+ }
+ }
+ }
+
if (castTime > -1)
{
- _hitTime = (int) Math.max((castTime / timeFactor) - cancelTime, 0);
+ _hitTime = (int) Math.max((castTime / timeFactor) - cancelTime, 0) + addedTime;
}
else
{
- _hitTime = (int) Math.max((skill.getHitTime() / timeFactor) - cancelTime, 0);
+ _hitTime = (int) Math.max((skill.getHitTime() / timeFactor) - cancelTime, 0) + addedTime;
}
_cancelTime = (int) cancelTime;
}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
index e998cd4d30..34988d2cb1 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
@@ -167,6 +167,11 @@ import org.l2jmobius.gameserver.network.clientpackets.ranking.RequestPvpRankingL
import org.l2jmobius.gameserver.network.clientpackets.ranking.RequestPvpRankingMyInfo;
import org.l2jmobius.gameserver.network.clientpackets.ranking.RequestRankingCharInfo;
import org.l2jmobius.gameserver.network.clientpackets.ranking.RequestRankingCharRankers;
+import org.l2jmobius.gameserver.network.clientpackets.revenge.RequestExPvpBookShareRevengeKillerLocation;
+import org.l2jmobius.gameserver.network.clientpackets.revenge.RequestExPvpBookShareRevengeList;
+import org.l2jmobius.gameserver.network.clientpackets.revenge.RequestExPvpBookShareRevengeReqShareRevengeInfo;
+import org.l2jmobius.gameserver.network.clientpackets.revenge.RequestExPvpBookShareRevengeSharedTeleportToKiller;
+import org.l2jmobius.gameserver.network.clientpackets.revenge.RequestExPvpBookShareRevengeTeleportToKiller;
import org.l2jmobius.gameserver.network.clientpackets.sayune.RequestFlyMove;
import org.l2jmobius.gameserver.network.clientpackets.sayune.RequestFlyMoveStart;
import org.l2jmobius.gameserver.network.clientpackets.settings.ExInteractModify;
@@ -696,11 +701,11 @@ public enum ExIncomingPackets implements IIncomingPackets
EX_COLLECTION_SUMMARY(0x1DF, null, ConnectionState.IN_GAME),
EX_COLLECTION_REGISTER(0x1E0, RequestCollectionRegister::new, ConnectionState.IN_GAME),
EX_COLLECTION_RECEIVE_REWARD(0x1E1, RequestCollectionReceiveReward::new, ConnectionState.IN_GAME),
- EX_PVPBOOK_SHARE_REVENGE_LIST(0x1E2, null, ConnectionState.IN_GAME),
- EX_PVPBOOK_SHARE_REVENGE_REQ_SHARE_REVENGEINFO(0x1E3, null, ConnectionState.IN_GAME),
- EX_PVPBOOK_SHARE_REVENGE_KILLER_LOCATION(0x1E4, null, ConnectionState.IN_GAME),
- EX_PVPBOOK_SHARE_REVENGE_TELEPORT_TO_KILLER(0x1E5, null, ConnectionState.IN_GAME),
- EX_PVPBOOK_SHARE_REVENGE_SHARED_TELEPORT_TO_KILLER(0x1E6, null, ConnectionState.IN_GAME),
+ EX_PVPBOOK_SHARE_REVENGE_LIST(0x1E2, RequestExPvpBookShareRevengeList::new, ConnectionState.IN_GAME),
+ EX_PVPBOOK_SHARE_REVENGE_REQ_SHARE_REVENGEINFO(0x1E3, RequestExPvpBookShareRevengeReqShareRevengeInfo::new, ConnectionState.IN_GAME),
+ EX_PVPBOOK_SHARE_REVENGE_KILLER_LOCATION(0x1E4, RequestExPvpBookShareRevengeKillerLocation::new, ConnectionState.IN_GAME),
+ EX_PVPBOOK_SHARE_REVENGE_TELEPORT_TO_KILLER(0x1E5, RequestExPvpBookShareRevengeTeleportToKiller::new, ConnectionState.IN_GAME),
+ EX_PVPBOOK_SHARE_REVENGE_SHARED_TELEPORT_TO_KILLER(0x1E6, RequestExPvpBookShareRevengeSharedTeleportToKiller::new, ConnectionState.IN_GAME),
EX_PENALTY_ITEM_LIST(0x1E7, null, ConnectionState.IN_GAME),
EX_PENALTY_ITEM_RESTORE(0x1E8, null, ConnectionState.IN_GAME),
EX_USER_WATCHER_TARGET_LIST(0x1E9, null, ConnectionState.IN_GAME),
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
index 5e9a348e4c..4712b9d80b 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java
@@ -698,6 +698,8 @@ public class EnterWorld implements IClientIncomingPacket
player.sendPacket(new ItemDeletionInfo());
+ player.applyKarmaPenalty();
+
// Activate first agathion when available.
final Item agathion = player.getInventory().unEquipItemInBodySlot(ItemTemplate.SLOT_AGATHION);
if (agathion != null)
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeKillerLocation.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeKillerLocation.java
new file mode 100644
index 0000000000..396ec57454
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeKillerLocation.java
@@ -0,0 +1,51 @@
+/*
+ * 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.network.clientpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPvpBookShareRevengeKillerLocation implements IClientIncomingPacket
+{
+ private String _killerName;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ packet.readString(); // Victim name.
+ _killerName = packet.readString();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final Player player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ RevengeHistoryManager.getInstance().locateKiller(player, _killerName);
+ }
+}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeList.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeList.java
new file mode 100644
index 0000000000..2f48f2fec9
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeList.java
@@ -0,0 +1,55 @@
+/*
+ * 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.network.clientpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.revenge.ExPvpBookShareRevengeList;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPvpBookShareRevengeList implements IClientIncomingPacket
+{
+ private int _objectId;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _objectId = packet.readD();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final Player player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ if (_objectId != player.getObjectId())
+ {
+ return;
+ }
+
+ player.sendPacket(new ExPvpBookShareRevengeList(player));
+ }
+}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeReqShareRevengeInfo.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeReqShareRevengeInfo.java
new file mode 100644
index 0000000000..4c07408e07
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeReqShareRevengeInfo.java
@@ -0,0 +1,71 @@
+/*
+ * 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.network.clientpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPvpBookShareRevengeReqShareRevengeInfo implements IClientIncomingPacket
+{
+ private String _victimName;
+ private String _killerName;
+ private int _type;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _victimName = packet.readString();
+ _killerName = packet.readString();
+ _type = packet.readD();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final Player player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ if (!_victimName.equals(player.getName()))
+ {
+ return;
+ }
+
+ final Player killer = World.getInstance().getPlayer(_killerName);
+ if ((killer == null) || !killer.isOnline())
+ {
+ SystemMessage sm = new SystemMessage(SystemMessageId.S1_CURRENTLY_OFFLINE);
+ sm.addString(_killerName);
+ player.sendPacket(sm);
+ return;
+ }
+
+ RevengeHistoryManager.getInstance().requestHelp(player, killer, _type);
+ }
+}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeSharedTeleportToKiller.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeSharedTeleportToKiller.java
new file mode 100644
index 0000000000..98986354e1
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeSharedTeleportToKiller.java
@@ -0,0 +1,52 @@
+/*
+ * 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.network.clientpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPvpBookShareRevengeSharedTeleportToKiller implements IClientIncomingPacket
+{
+ private String _victimName;
+ private String _killerName;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _victimName = packet.readString();
+ _killerName = packet.readString();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final Player player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ RevengeHistoryManager.getInstance().teleportToSharedKiller(player, _victimName, _killerName);
+ }
+}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeTeleportToKiller.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeTeleportToKiller.java
new file mode 100644
index 0000000000..212e01abb9
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/clientpackets/revenge/RequestExPvpBookShareRevengeTeleportToKiller.java
@@ -0,0 +1,57 @@
+/*
+ * 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.network.clientpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPvpBookShareRevengeTeleportToKiller implements IClientIncomingPacket
+{
+ private String _victimName;
+ private String _killerName;
+
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ _victimName = packet.readString();
+ _killerName = packet.readString();
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final Player player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ if (!_victimName.equals(player.getName()))
+ {
+ return;
+ }
+
+ RevengeHistoryManager.getInstance().teleportToKiller(player, _killerName);
+ }
+}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeKillerLocation.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeKillerLocation.java
new file mode 100644
index 0000000000..f6c9bd9791
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeKillerLocation.java
@@ -0,0 +1,46 @@
+/*
+ * 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.network.serverpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author Mobius
+ */
+public class ExPvpBookShareRevengeKillerLocation implements IClientOutgoingPacket
+{
+ private final Player _player;
+
+ public ExPvpBookShareRevengeKillerLocation(Player player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_PVPBOOK_SHARE_REVENGE_KILLER_LOCATION.writeId(packet);
+ packet.writeString(_player.getName());
+ packet.writeD(_player.getX());
+ packet.writeD(_player.getY());
+ packet.writeD(_player.getZ());
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeList.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeList.java
new file mode 100644
index 0000000000..58615d42b0
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeList.java
@@ -0,0 +1,83 @@
+/*
+ * 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.network.serverpackets.revenge;
+
+import java.util.Collection;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.instancemanager.RevengeHistoryManager;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.actor.Player;
+import org.l2jmobius.gameserver.model.holders.RevengeHistoryHolder;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author Mobius
+ */
+public class ExPvpBookShareRevengeList implements IClientOutgoingPacket
+{
+ private final Collection _history;
+
+ public ExPvpBookShareRevengeList(Player player)
+ {
+ _history = RevengeHistoryManager.getInstance().getHistory(player);
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_PVPBOOK_SHARE_REVENGE_LIST.writeId(packet);
+ if (_history == null)
+ {
+ packet.writeC(1); // CurrentPage
+ packet.writeC(1); // MaxPage
+ packet.writeD(0);
+ }
+ else
+ {
+ packet.writeC(1); // CurrentPage
+ packet.writeC(1); // MaxPage
+ packet.writeD(_history.size());
+ for (RevengeHistoryHolder holder : _history)
+ {
+ packet.writeD(holder.getType().ordinal()); // ShareType (2 - help request, 1 - revenge, 0 - both)
+ packet.writeD((int) (holder.getKillTime() / 1000)); // KilledTime
+ packet.writeD(holder.getShowLocationRemaining()); // ShowKillerCount
+ packet.writeD(holder.getTeleportRemaining()); // TeleportKillerCount
+ packet.writeD(holder.getSharedTeleportRemaining()); // SharedTeleportKillerCount
+ packet.writeD(0); // KilledUserDBID
+ packet.writeString(holder.getVictimName()); // KilledUserName
+ packet.writeString(holder.getVictimClanName()); // KilledUserPledgeName
+ packet.writeD(holder.getVictimLevel()); // KilledUserLevel
+ packet.writeD(holder.getVictimRaceId()); // KilledUserRace
+ packet.writeD(holder.getVictimClassId()); // KilledUserClass
+ packet.writeD(0); // KillUserDBID
+ packet.writeString(holder.getKillerName()); // KillUserName
+ packet.writeString(holder.getKillerClanName()); // KillUserPledgeName
+ packet.writeD(holder.getKillerLevel()); // KillUserLevel
+ packet.writeD(holder.getKillerRaceId()); // KillUserRace
+ packet.writeD(holder.getKillerClassId()); // KillUserClass
+ Player killer = World.getInstance().getPlayer(holder.getKillerName());
+ packet.writeD((killer != null) && killer.isOnline() ? 2 : 0); // KillUserOnline (2 - online, 0 - offline)
+ packet.writeD(0); // KillUserKarma
+ packet.writeD((int) (holder.getShareTime() / 1000)); // nSharedTime
+ }
+ }
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeNewRevengeInfo.java b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeNewRevengeInfo.java
new file mode 100644
index 0000000000..fa5336bfce
--- /dev/null
+++ b/L2J_Mobius_Essence_6.2_Vanguard/java/org/l2jmobius/gameserver/network/serverpackets/revenge/ExPvpBookShareRevengeNewRevengeInfo.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.network.serverpackets.revenge;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.enums.RevengeType;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author Mobius
+ */
+public class ExPvpBookShareRevengeNewRevengeInfo implements IClientOutgoingPacket
+{
+ private final String _victimName;
+ private final String _killerName;
+ private final RevengeType _type;
+
+ public ExPvpBookShareRevengeNewRevengeInfo(String victimName, String killerName, RevengeType type)
+ {
+ _victimName = victimName;
+ _killerName = killerName;
+ _type = type;
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_PVPBOOK_SHARE_REVENGE_NEW_REVENGEINFO.writeId(packet);
+ packet.writeD(_type.ordinal());
+ packet.writeString(_victimName);
+ packet.writeString(_killerName);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_Essence_6.2_Vanguard/readme.txt b/L2J_Mobius_Essence_6.2_Vanguard/readme.txt
index 8721488638..5b04044732 100644
--- a/L2J_Mobius_Essence_6.2_Vanguard/readme.txt
+++ b/L2J_Mobius_Essence_6.2_Vanguard/readme.txt
@@ -137,6 +137,7 @@ Sylph: https://eu.4game.com/patchnotes/lineage2essence/281/
Frost Lord: https://eu.4game.com/patchnotes/lineage2essence/329/
-Resurrection with payment
-Frost Lord castle
+-Revenge system
Battle Chronicle: https://eu.4game.com/patchnotes/lineage2essence/353/
-New henna pattern potential system