Addition of revenge system.

This commit is contained in:
MobiusDevelopment
2022-10-20 21:29:23 +00:00
parent 68af1ad1e7
commit c457a227e6
51 changed files with 2825 additions and 58 deletions

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -6,38 +6,19 @@
<operateType>P</operateType>
<effectPoint>5000</effectPoint>
</skill>
<skill id="60002" toLevel="3" name="Einhasad Overseeing">
<skill id="60002" toLevel="10" name="Einhasad Overseeing">
<!-- In case of death during PvP/ PK Increased chance to lose items. Up to $s1 items can be lost. -->
<icon>icon.karma</icon>
<magicLevel>10</magicLevel>
<operateType>P</operateType>
<magicCriticalRate>5</magicCriticalRate>
<effects>
<effect name="PhysicalDefence">
<amount>
<value level="1">-5</value>
<value level="2">-10</value>
<value level="3">-15</value>
</amount>
<mode>PER</mode>
</effect>
<effect name="MagicalDefence">
<amount>
<value level="1">-5</value>
<value level="2">-10</value>
<value level="3">-15</value>
</amount>
<mode>PER</mode>
</effect>
<effect name="Speed">
<amount>
<value level="1">-5</value>
<value level="2">-10</value>
<value level="3">-30</value>
</amount>
<mode>DIFF</mode>
</effect>
</effects>
<operateType>A2</operateType>
<targetType>SELF</targetType>
<affectScope>SINGLE</affectScope>
<isMagic>4</isMagic>
<abnormalLevel>1</abnormalLevel>
<abnormalTime>-1</abnormalTime>
<isTriggeredSkill>true</isTriggeredSkill>
<irreplacableBuff>true</irreplacableBuff>
<canBeDispelled>false</canBeDispelled>
<stayAfterDeath>true</stayAfterDeath>
</skill>
<skill id="60003" toLevel="1" name="Server Level Ranking I">
<!-- Bonus for the 1st place in the list of ranks for level on the server. STR +1 INT +1 CON +1 MEN +1 DEX +1 WIT +1 Recovery Potions' Effect +50 Weight limit +100,000 P. Evasion +20 -->
@@ -320,6 +301,9 @@
<icon>icon.skill0000</icon>
<operateType>A1</operateType>
<hitTime>2000</hitTime>
<effects>
<effect name="Teleport" />
</effects>
</skill>
<skill id="60019" toLevel="4" name="Jaban's Blessing">
<!-- Jaban's Blessing. Max HP $s1 Received PvP damage $s2 -->

View File

@@ -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");

View File

@@ -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

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.enums;
/**
* @author Mobius
*/
public enum RevengeType
{
OWN_HELP_REQUEST,
REVENGE,
HELP_REQUEST;
}

View File

@@ -148,6 +148,8 @@ public class DailyTaskManager
{
GlobalVariablesManager.getInstance().storeMe();
RevengeHistoryManager.getInstance().storeMe();
if (Config.WORLD_EXCHANGE_LAZY_UPDATE)
{
WorldExchangeManager.getInstance().storeMe();

View File

@@ -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

View File

@@ -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<Player> getTop50()
{
final List<Player> 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;

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<Integer, List<RevengeHistoryHolder>> 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<RevengeHistoryHolder> 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<Integer, List<RevengeHistoryHolder>> entry : REVENGE_HISTORY.entrySet())
{
final List<RevengeHistoryHolder> history = entry.getValue();
if (history != null)
{
final long currentTime = System.currentTimeMillis();
final List<RevengeHistoryHolder> 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<Integer, List<RevengeHistoryHolder>> entry : REVENGE_HISTORY.entrySet())
{
final List<RevengeHistoryHolder> 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<RevengeHistoryHolder> removals = new ArrayList<>();
final List<RevengeHistoryHolder> 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<RevengeHistoryHolder> 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<RevengeHistoryHolder> 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<RevengeHistoryHolder> 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<RevengeHistoryHolder> 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<Player> 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<RevengeHistoryHolder> 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<RevengeHistoryHolder> 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();
}
}

View File

@@ -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<DamageTakenHolder> _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;

View File

@@ -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)
{

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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<GameClient>
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),

View File

@@ -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)

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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));
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<RevengeHistoryHolder> _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;
}
}

View File

@@ -0,0 +1,49 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.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;
}
}

View File

@@ -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