diff --git a/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/skills/29400-29499.xml b/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/skills/29400-29499.xml
index ece21bf8f3..82fa9744c1 100644
--- a/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/skills/29400-29499.xml
+++ b/L2J_Mobius_8.0_Homunculus/dist/game/data/stats/skills/29400-29499.xml
@@ -148,13 +148,79 @@
- icon.skill0000
- A1
+ icon.karma
+ A2
+
+ 1
+ 2
+ 3
+ 4
+
+ PK_DEBUFF1
+
+ 1800
+ 3600
+ 7200
+ 10800
+
+ false
+ SELF
+ SINGLE
+ 0
+ true
+ 2
+ -5
+ true
+ true
+
+
+
+ -5
+ -10
+ -15
+ -30
+
+ PER
+
+
+
+ -5
+ -10
+ -15
+ -30
+
+ PER
+
+
+
+ -5
+ -10
+ -30
+ -35
+
+ DIFF
+
+
- icon.skill0000
- A1
+ icon.karma
+ A2
+ 1
+ PK_DEBUFF2
+ 10800
+ false
+ SELF
+ SINGLE
+ 0
+ true
+ 2
+ -5
+ true
+ true
+
+
+
diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/World.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/World.java
index c1510e8c0e..bd533a1661 100644
--- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/World.java
+++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/World.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
@@ -94,6 +95,9 @@ public class World
private static final AtomicInteger _partyNumber = new AtomicInteger();
private static final AtomicInteger _memberInPartyNumber = new AtomicInteger();
+ private static final Set _pkPlayers = ConcurrentHashMap.newKeySet(30);
+ private static final AtomicInteger _lastPkTime = new AtomicInteger((int) System.currentTimeMillis() / 1000);
+
private static final WorldRegion[][] _worldRegions = new WorldRegion[REGIONS_X + 1][REGIONS_Y + 1];
/** Constructor of World. */
@@ -817,6 +821,49 @@ public class World
return _memberInPartyNumber.get();
}
+ public synchronized void addPkPlayer(PlayerInstance player)
+ {
+ if (_pkPlayers.size() > 29)
+ {
+ PlayerInstance lowestPk = null;
+ int lowestPkCount = Integer.MAX_VALUE;
+ for (PlayerInstance pk : _pkPlayers)
+ {
+ if (pk.getPkKills() < lowestPkCount)
+ {
+ lowestPk = pk;
+ lowestPkCount = pk.getPkKills();
+ }
+ }
+ if ((lowestPk != null) && (lowestPkCount < player.getPkKills()))
+ {
+ _pkPlayers.remove(lowestPk);
+ }
+ else
+ {
+ return;
+ }
+ }
+ _pkPlayers.add(player);
+ _lastPkTime.set((int) System.currentTimeMillis() / 1000);
+ }
+
+ public void removePkPlayer(PlayerInstance player)
+ {
+ _pkPlayers.remove(player);
+ _lastPkTime.set((int) System.currentTimeMillis() / 1000);
+ }
+
+ public Set getPkPlayers()
+ {
+ return _pkPlayers;
+ }
+
+ public int getLastPkTime()
+ {
+ return _lastPkTime.get();
+ }
+
/**
* @return the current instance of World
*/
diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
index f06fac7644..00ab39b574 100644
--- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
+++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
@@ -1947,6 +1947,10 @@ public class PlayerInstance extends Playable
{
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerPKChanged(this, _pkKills, pkKills), this);
_pkKills = pkKills;
+ if (_pkKills > 9)
+ {
+ World.getInstance().addPkPlayer(this);
+ }
}
/**
@@ -2083,6 +2087,11 @@ public class PlayerInstance extends Playable
sendPacket(new SystemMessage(SystemMessageId.YOUR_REPUTATION_HAS_BEEN_CHANGED_TO_S1).addInt(getReputation()));
broadcastReputation();
+
+ if (getReputation() >= 0)
+ {
+ World.getInstance().removePkPlayer(this);
+ }
}
public int getWeightPenalty()
@@ -5132,6 +5141,25 @@ public class PlayerInstance extends Playable
{
setReputation(getReputation() - Formulas.calculateKarmaGain(getPkKills(), killedPlayable.isSummon()));
setPkKills(getPkKills() + 1);
+
+ // Einhasad debuffs.
+ if (_pkKills > 9)
+ {
+ SkillCaster.triggerCast(this, this, CommonSkill.EINHASAD_OVERSEEING_4.getSkill());
+ SkillCaster.triggerCast(this, this, CommonSkill.EINHASAD_CHAINS.getSkill());
+ }
+ else if (_pkKills > 7)
+ {
+ SkillCaster.triggerCast(this, this, CommonSkill.EINHASAD_OVERSEEING_3.getSkill());
+ }
+ else if (_pkKills > 5)
+ {
+ SkillCaster.triggerCast(this, this, CommonSkill.EINHASAD_OVERSEEING_2.getSkill());
+ }
+ else if (_pkKills > 3)
+ {
+ SkillCaster.triggerCast(this, this, CommonSkill.EINHASAD_OVERSEEING_1.getSkill());
+ }
}
}
@@ -10095,6 +10123,11 @@ public class PlayerInstance extends Playable
setCurrentMp(_originalMp);
}
+ if ((_pkKills > 9) && (getReputation() < 0))
+ {
+ World.getInstance().addPkPlayer(this);
+ }
+
revalidateZone(true);
notifyFriends(FriendStatus.MODE_ONLINE);
@@ -10786,6 +10819,8 @@ public class PlayerInstance extends Playable
{
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLogout(this), this);
+ World.getInstance().removePkPlayer(this);
+
try
{
for (ZoneType zone : ZoneManager.getInstance().getZones(this))
diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/skills/AbnormalType.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/skills/AbnormalType.java
index 348b279ba5..5685a7796e 100644
--- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/skills/AbnormalType.java
+++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/skills/AbnormalType.java
@@ -261,6 +261,8 @@ public enum AbnormalType
SANTIAGO_SCROLL(-1),
POWERFUL_GRAVITY(-1),
AIR_LIGHT(-1),
+ PK_DEBUFF1(-1),
+ PK_DEBUFF2(-1),
AB_HAWK_EYE(0),
ALL_ATTACK_DOWN(1),
ALL_ATTACK_UP(2),
diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/skills/CommonSkill.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/skills/CommonSkill.java
index b2fbacc6c2..f2937d1eaa 100644
--- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/skills/CommonSkill.java
+++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/skills/CommonSkill.java
@@ -64,7 +64,12 @@ public enum CommonSkill
CHILD_TRANSFORM(6202, 1),
NATIVE_TRANSFORM(6203, 1),
LUCKY_CLOVER(18103, 1),
- TRANQUIL_SOUL(32935, 1);
+ TRANQUIL_SOUL(32935, 1),
+ EINHASAD_OVERSEEING_1(29413, 1),
+ EINHASAD_OVERSEEING_2(29413, 2),
+ EINHASAD_OVERSEEING_3(29413, 3),
+ EINHASAD_OVERSEEING_4(29413, 4),
+ EINHASAD_CHAINS(29414, 1);
private final SkillHolder _holder;
diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
index 485ec8c42b..315304e4a4 100644
--- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
+++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/ExIncomingPackets.java
@@ -93,6 +93,8 @@ import org.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeAdd
import org.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMenteeWaitingList;
import org.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMentorCancel;
import org.l2jmobius.gameserver.network.clientpackets.mentoring.RequestMentorList;
+import org.l2jmobius.gameserver.network.clientpackets.pk.RequestExPkPenaltyList;
+import org.l2jmobius.gameserver.network.clientpackets.pk.RequestExPkPenaltyListOnlyLoc;
import org.l2jmobius.gameserver.network.clientpackets.pledgeV2.RequestExPledgeAnnounce;
import org.l2jmobius.gameserver.network.clientpackets.pledgeV2.RequestExPledgeItemBuy;
import org.l2jmobius.gameserver.network.clientpackets.pledgeV2.RequestExPledgeItemList;
@@ -595,8 +597,8 @@ public enum ExIncomingPackets implements IIncomingPackets
EX_PLEDGE_ENEMY_INFO_LIST(0x1C6, null, ConnectionState.IN_GAME),
EX_PLEDGE_ENEMY_REGISTER(0x1C7, null, ConnectionState.IN_GAME),
EX_PLEDGE_ENEMY_DELETE(0x1C8, null, ConnectionState.IN_GAME),
- EX_PK_PENALTY_LIST(0x1C9, null, ConnectionState.IN_GAME),
- EX_PK_PENALTY_LIST_ONLY_LOC(0x1CA, null, ConnectionState.IN_GAME),
+ EX_PK_PENALTY_LIST(0x1C9, RequestExPkPenaltyList::new, ConnectionState.IN_GAME),
+ EX_PK_PENALTY_LIST_ONLY_LOC(0x1CA, RequestExPkPenaltyListOnlyLoc::new, ConnectionState.IN_GAME),
EX_TRY_PET_EXTRACT_SYSTEM(0x1CB, null, ConnectionState.IN_GAME),
EX_PLEDGE_V3_SET_ANNOUNCE(0x1CC, null, ConnectionState.IN_GAME),
EX_MAX(0x1CD, null, ConnectionState.IN_GAME);
diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/clientpackets/pk/RequestExPkPenaltyList.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/clientpackets/pk/RequestExPkPenaltyList.java
new file mode 100644
index 0000000000..a9fb5589d8
--- /dev/null
+++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/clientpackets/pk/RequestExPkPenaltyList.java
@@ -0,0 +1,47 @@
+/*
+ * 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.pk;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.pk.ExPkPenaltyList;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPkPenaltyList implements IClientIncomingPacket
+{
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final PlayerInstance player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ player.sendPacket(new ExPkPenaltyList());
+ }
+}
diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/clientpackets/pk/RequestExPkPenaltyListOnlyLoc.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/clientpackets/pk/RequestExPkPenaltyListOnlyLoc.java
new file mode 100644
index 0000000000..b202151d5c
--- /dev/null
+++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/clientpackets/pk/RequestExPkPenaltyListOnlyLoc.java
@@ -0,0 +1,47 @@
+/*
+ * 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.pk;
+
+import org.l2jmobius.commons.network.PacketReader;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.GameClient;
+import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
+import org.l2jmobius.gameserver.network.serverpackets.pk.ExPkPenaltyListOnlyLoc;
+
+/**
+ * @author Mobius
+ */
+public class RequestExPkPenaltyListOnlyLoc implements IClientIncomingPacket
+{
+ @Override
+ public boolean read(GameClient client, PacketReader packet)
+ {
+ return true;
+ }
+
+ @Override
+ public void run(GameClient client)
+ {
+ final PlayerInstance player = client.getPlayer();
+ if (player == null)
+ {
+ return;
+ }
+
+ player.sendPacket(new ExPkPenaltyListOnlyLoc());
+ }
+}
diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/serverpackets/pk/ExPkPenaltyList.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/serverpackets/pk/ExPkPenaltyList.java
new file mode 100644
index 0000000000..4526b7f4d2
--- /dev/null
+++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/serverpackets/pk/ExPkPenaltyList.java
@@ -0,0 +1,54 @@
+/*
+ * 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.pk;
+
+import java.util.Set;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author Mobius
+ */
+public class ExPkPenaltyList implements IClientOutgoingPacket
+{
+ public ExPkPenaltyList()
+ {
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_PK_PENALTY_LIST.writeId(packet);
+
+ final Set players = World.getInstance().getPkPlayers();
+ packet.writeD(World.getInstance().getLastPkTime());
+ packet.writeD(players.size());
+ for (PlayerInstance player : players)
+ {
+ packet.writeD(player.getObjectId());
+ packet.writeS(String.format("%1$-" + 23 + "s", player.getName()));
+ packet.writeD(player.getLevel());
+ packet.writeD(player.getClassId().getId());
+ }
+
+ return true;
+ }
+}
diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/serverpackets/pk/ExPkPenaltyListOnlyLoc.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/serverpackets/pk/ExPkPenaltyListOnlyLoc.java
new file mode 100644
index 0000000000..dcd4a22ef3
--- /dev/null
+++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/serverpackets/pk/ExPkPenaltyListOnlyLoc.java
@@ -0,0 +1,54 @@
+/*
+ * 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.pk;
+
+import java.util.Set;
+
+import org.l2jmobius.commons.network.PacketWriter;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.OutgoingPackets;
+import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
+
+/**
+ * @author Mobius
+ */
+public class ExPkPenaltyListOnlyLoc implements IClientOutgoingPacket
+{
+ public ExPkPenaltyListOnlyLoc()
+ {
+ }
+
+ @Override
+ public boolean write(PacketWriter packet)
+ {
+ OutgoingPackets.EX_PK_PENALTY_LIST_ONLY_LOC.writeId(packet);
+
+ final Set players = World.getInstance().getPkPlayers();
+ packet.writeD(World.getInstance().getLastPkTime());
+ packet.writeD(players.size());
+ for (PlayerInstance player : players)
+ {
+ packet.writeD(player.getObjectId());
+ packet.writeD(player.getX());
+ packet.writeD(player.getY());
+ packet.writeD(player.getZ());
+ }
+
+ return true;
+ }
+}