Skip to content

Instantly share code, notes, and snippets.

@u3games
Created February 19, 2015 08:16
Show Gist options
  • Save u3games/6b34820c2bd2066f60d9 to your computer and use it in GitHub Desktop.
Save u3games/6b34820c2bd2066f60d9 to your computer and use it in GitHub Desktop.
Dev_Engine_Core_v1 - U3Games
Index: dist/game/config/L2JMods.properties
===================================================================
--- dist/game/config/L2JMods.properties (revision 10485)
+++ dist/game/config/L2JMods.properties (working copy)
@@ -127,7 +127,6 @@
# ---------------------------------------------------------------------------
# Team vs. Team Event Engine (by HorridoJoho)
# ---------------------------------------------------------------------------
-
# <u><b><font color="red">WARNING: this mod require custom NPC table support turned on !</font></b></u>
# CustomNpcTable = True in General.properties
# ---------------------------------------------------------------------------
@@ -155,7 +154,7 @@
# Default: 20
TvTEventRunningTime = 20
-# TvT Event NPC (create a custom npc of type L2TvTEventNpc).
+# TvT Event NPC (create a custom npc of type L2Npc).
# Default: 70010
TvTEventParticipationNpcId = 70010
@@ -243,6 +242,274 @@
# ---------------------------------------------------------------------------
+# Capture the Flag Event Engine
+# ---------------------------------------------------------------------------
+# <u><b><font color="red">WARNING: this mod require custom NPC table support turned on !</font></b></u>
+# CustomNpcTable = True in General.properties
+# ---------------------------------------------------------------------------
+# Enable/Disable CTFEvent System.
+CTFEventEnabled = False
+
+# CTF in instance.
+# Recommended (True)
+CTFEventInInstance = True
+
+# Name of the instance file for CTF.
+CTFEventInstanceFile = coliseum.xml
+
+# Times CTF will occur (24h format).
+# Default: 10:30,16:30,22:30,4:30
+CTFEventInterval = 10:30,16:30,22:30,4:30
+
+# Registration timer from start of event (in minutes).
+CTFEventParticipationTime = 30
+
+# Event running time (in minutes).
+CTFEventRunningTime = 20
+
+# CTF Event NPC (create a custom npc of type L2Npc).
+CTFEventParticipationNpcId = 70020
+
+# CTF First Team Headquarters NPC (create a custom npc of type L2Npc).
+CTFEventFirstTeamHeadquarters = 70021
+
+# CTF Second Team Headquarters NPC (create a custom npc of type L2Npc).
+CTFEventSecondTeamHeadquarters = 70022
+
+# CTF Event First Team Flag itemId.
+CTFEventFirstTeamFlag = 13531
+
+# CTF Event First Team Flag itemId.
+CTFEventSecondTeamFlag = 13534
+
+# CTF Event Capture Flag skillId.
+# Magic skill to cast upon capturing flag.
+# Set to 0 for disabling it.
+CTFEventCaptureSkillId = 1034
+
+# CTF Event Participation Fee (itemId, number). Fee is not returned.
+# Example: 57,10000
+# Default = none
+CTFEventParticipationFee = 57,10000
+
+# Location for CTFEvent NPC to spawn in form x,y,z[,heading]
+CTFEventParticipationNpcCoordinates = 83425,148585,-3406
+
+# Minimum amount of players allowed in each team.
+# Recommend not to set less that 2 on live servers,
+# due to flag carriers are unable to cast offensive skills.
+# You may alternatively set to 1 for testing purposes.
+CTFEventMinPlayersInTeams = 2
+
+# Max amount of players allowed in each team.
+CTFEventMaxPlayersInTeams = 20
+
+# Min/Max level of players that may join the event.
+CTFEventMinPlayerLevel = 52
+CTFEventMaxPlayerLevel = 85
+
+# Respawn and exit delay timers (in seconds).
+CTFEventRespawnTeleportDelay = 10
+CTFEventStartLeaveTeleportDelay = 10
+
+# First Team - Name, Start/Death x,y,z location.
+CTFEventTeam1Name = Blue
+CTFEventTeam1Coordinates = -213023,243354,1999
+
+# Second Team - Name, Start/Death x,y,z location.
+CTFEventTeam2Name = Red
+CTFEventTeam2Coordinates = -213896,246446,1999
+
+# First Team - Flag x,y,z location.
+CTFEventTeam1FlagCoordinates = -213491,243365,1999
+
+# Second Team - Flag x,y,z location.
+CTFEventTeam2FlagCoordinates = -213453,246407,1999
+
+# Reward for winning team.
+# Example: CTFEventReward = itemId,amount;itemId,amount;itemId,amount
+CTFEventReward = 57,100000
+
+# CTFEvent Rules
+CTFEventTargetTeamMembersAllowed = True
+CTFEventScrollsAllowed = False
+CTFEventPotionsAllowed = False
+CTFEventSummonByItemAllowed = False
+
+# Door ID's to open/close on start/end.
+# Not supported in instance, use xml template for defining doors.
+# Example: CTFDoorsToOpen = 1;2;3;4;5;6
+CTFDoorsToOpen =
+CTFDoorsToClose =
+
+# Should both teams get reward if there's a tie?
+CTFRewardTeamTie = False
+
+# Participant's effects handling on teleport/death.
+# Effects lasting through death never removed.
+# 0 - always remove all effects.
+# 1 - remove all effects only during port to event (noblesse blessing can be used)
+# 2 - never remove any effect
+# Default: 0
+CTFEventEffectsRemoval = 0
+
+# Restrict specified skills in CTF. SkillID's need to be separated with a comma.
+# Skills will be disabled for the duration of the game.
+# Default: 840,841,842,5982,5983 (Flight transformations).
+CTFEventRestrictedSkills = 840,841,842,5982,5983
+
+# Fighter-class participants will be buffed with those buffs each respawn
+# Format: skill1Id,skill1Level;skill2Id,skill2Level...
+# Example: 1504,1;1501,1;1502,1;1499,1;1086,1
+CTFEventFighterBuffs =
+
+# Mage-class participants will be buffed with those buffs each respawn
+# Format: skill1Id,skill1Level;skill2Id,skill2Level...
+# Example: 1504,1;1500,1;1501,1;1085,3
+CTFEventMageBuffs =
+
+# Maximum number of allowed participants per IP address (dualbox check)
+# Default: 0 (no limits)
+CTFEventMaxParticipantsPerIP = 0
+
+# Voiced command (.ctf) working during CTF event to get information about event status
+CTFAllowVoicedInfoCommand = false
+
+
+# ---------------------------------------------------------------------------
+# Death Match Event Engine
+# ---------------------------------------------------------------------------
+# <u><b><font color="red">WARNING: this mod require custom NPC table support turned on !</font></b></u>
+# CustomNpcTable = True in General.properties
+# ---------------------------------------------------------------------------
+# Enable/Disable DMEvent System
+# Default: False
+DMEventEnabled = False
+
+# DM in instance
+# Default: False
+DMEventInInstance = False
+
+# Name of the instance file for DM
+# Default: coliseum.xml
+DMEventInstanceFile = coliseum.xml
+
+# Times DM will occur (24h format).
+# Default: 12:00,18:00,00:00,6:00
+DMEventInterval = 12:00,18:00,00:00,6:00
+
+# Registration timer from start of event (in minutes).
+# Default: 30
+DMEventParticipationTime = 30
+
+# Event running time (in minutes).
+# Default: 20
+DMEventRunningTime = 20
+
+# DM Event NPC (create a custom npc of type L2Npc).
+# Default: 70010
+DMEventParticipationNpcId = 70030
+
+# DM Event Participation Fee (itemId, number). Fee is not returned.
+# Example: 57,100000
+# Default: 0,0
+DMEventParticipationFee = 0,0
+
+# Location for DMEvent NPC to spawn in form x,y,z[,heading]
+# Default: 83425,148585,-3406
+DMEventParticipationNpcCoordinates = 83425,148585,-3406
+
+# Minimum number of players to start the event.
+# Default: 2
+DMEventMinPlayers = 2
+
+# Maximum number of players to the event.
+# Default: 20
+DMEventMaxPlayers = 20
+
+# Minimum level of players that may join the event.
+# Default: 1
+DMEventMinPlayerLevel = 1
+
+# Maximum level of players that may join the event.
+# Default: 85
+DMEventMaxPlayerLevel = 85
+
+# Respawn delay timer (in seconds).
+# Default: 10
+DMEventRespawnTeleportDelay = 10
+
+# Exit delay timer (in seconds).
+# Default: 10
+DMEventStartLeaveTeleportDelay = 10
+
+# Coordinates for the players spawn.
+# Example: x1,y1,z1;x2,y2,z2;x3,y3,z3
+DMEventPlayerCoordinates = 148695,46725,-3414;149999,46728,-3414;150593,46813,-3414
+
+# Show at the end of the game the rank of the participants.
+# Default: False
+DMEventShowTopRank = False
+
+# Return first winners.
+# For this option you must activate the option: DMEventShowTopRank
+# Default: 10
+DMEventListTopRank = 10
+
+# Reward the first players.
+# If the option DMRewardPlayersTie is True, players spathes counted as one.
+# Default: 3
+DMEventRewardFirstPlayers = 3
+
+# Reward for winning players.
+# Separate awards with | for each position. If the number of positions
+# is greater than the separate items, will be used as the last items
+# to this position.
+# Example: DMEventReward = itemId,amount;itemId,amount;itemId,amount
+DMEventReward = 57,100000;57,50000;57,25000
+
+# Should both player get reward if there's a tie?
+DMRewardPlayerTie = False
+
+# DMEvent Rules
+DMEventTargetTeamMembersAllowed = True
+DMEventScrollsAllowed = False
+DMEventPotionsAllowed = False
+DMEventSummonByItemAllowed = False
+
+# Door ID's to open/close on start/end.
+# Not supported in instance, use xml template for defining doors.
+# Example: DMDoorsToOpen = 1;2;3;4;5;6
+DMDoorsToOpen =
+DMDoorsToClose =
+
+# Participant's effects handling on teleport/death.
+# Effects lasting through death never removed.
+# 0 - always remove all effects.
+# 1 - remove all effects only during port to event (noblesse blessing can be used)
+# 2 - never remove any effect
+# Default: 0
+DMEventEffectsRemoval = 0
+
+# Fighter-class participants will be buffed with those buffs each respawn
+# Format: skill1Id,skill1Level;skill2Id,skill2Level...
+# Example: 1504,1;1501,1;1502,1;1499,1
+DMEventFighterBuffs =
+
+# Mage-class participants will be buffed with those buffs each respawn
+# Format: skill1Id,skill1Level;skill2Id,skill2Level...
+# Example: 1504,1;1500,1;1501,1;1085,3
+DMEventMageBuffs =
+
+# Maximum number of allowed participants per IP address (dualbox check)
+# Default: 0 (no limits)
+DMEventMaxParticipantsPerIP = 0
+
+# Voiced command (.dm) working during DM event to get information about event status
+DMAllowVoicedInfoCommand = false
+
+
+# ---------------------------------------------------------------------------
# L2J Banking System
# ---------------------------------------------------------------------------
Index: java/com/l2jserver/Config.java
===================================================================
--- java/com/l2jserver/Config.java (revision 10485)
+++ java/com/l2jserver/Config.java (working copy)
@@ -59,6 +59,7 @@
import com.l2jserver.gameserver.enums.IllegalActionPunishmentType;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.holders.ItemHolder;
+import com.l2jserver.gameserver.model.holders.SkillHolder;
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
import com.l2jserver.gameserver.util.FloodProtectorConfig;
import com.l2jserver.gameserver.util.Util;
@@ -685,6 +686,8 @@
public static int L2JMOD_CHAMPION_REWARD_QTY;
public static boolean L2JMOD_CHAMPION_ENABLE_VITALITY;
public static boolean L2JMOD_CHAMPION_ENABLE_IN_INSTANCES;
+
+ // TODO: TvT Event
public static boolean TVT_EVENT_ENABLED;
public static boolean TVT_EVENT_IN_INSTANCE;
public static String TVT_EVENT_INSTANCE_FILE;
@@ -717,6 +720,82 @@
public static Map<Integer, Integer> TVT_EVENT_MAGE_BUFFS;
public static int TVT_EVENT_MAX_PARTICIPANTS_PER_IP;
public static boolean TVT_ALLOW_VOICED_COMMAND;
+
+ // TODO: CTF Event
+ public static boolean CTF_EVENT_ENABLED;
+ public static boolean CTF_EVENT_IN_INSTANCE;
+ public static String CTF_EVENT_INSTANCE_FILE;
+ public static String[] CTF_EVENT_INTERVAL;
+ public static int CTF_EVENT_PARTICIPATION_TIME;
+ public static int CTF_EVENT_RUNNING_TIME;
+ public static int CTF_EVENT_PARTICIPATION_NPC_ID;
+ public static int CTF_EVENT_TEAM_1_HEADQUARTERS;
+ public static int CTF_EVENT_TEAM_2_HEADQUARTERS;
+ public static int CTF_EVENT_TEAM_1_FLAG;
+ public static int CTF_EVENT_TEAM_2_FLAG;
+ public static int CTF_EVENT_CAPTURE_SKILL;
+ public static int[] CTF_EVENT_PARTICIPATION_NPC_COORDINATES = new int[4];
+ public static int[] CTF_EVENT_PARTICIPATION_FEE = new int[2];
+ public static int CTF_EVENT_MIN_PLAYERS_IN_TEAMS;
+ public static int CTF_EVENT_MAX_PLAYERS_IN_TEAMS;
+ public static int CTF_EVENT_RESPAWN_TELEPORT_DELAY;
+ public static int CTF_EVENT_START_LEAVE_TELEPORT_DELAY;
+ public static String CTF_EVENT_TEAM_1_NAME;
+ public static int[] CTF_EVENT_TEAM_1_COORDINATES = new int[3];
+ public static String CTF_EVENT_TEAM_2_NAME;
+ public static int[] CTF_EVENT_TEAM_2_COORDINATES = new int[3];
+ public static int[] CTF_EVENT_TEAM_1_FLAG_COORDINATES = new int[3];
+ public static int[] CTF_EVENT_TEAM_2_FLAG_COORDINATES = new int[3];
+ public static List<int[]> CTF_EVENT_REWARDS;
+ public static boolean CTF_EVENT_TARGET_TEAM_MEMBERS_ALLOWED;
+ public static boolean CTF_EVENT_SCROLL_ALLOWED;
+ public static boolean CTF_EVENT_POTIONS_ALLOWED;
+ public static boolean CTF_EVENT_SUMMON_BY_ITEM_ALLOWED;
+ public static List<Integer> CTF_DOORS_IDS_TO_OPEN;
+ public static List<Integer> CTF_DOORS_IDS_TO_CLOSE;
+ public static boolean CTF_REWARD_TEAM_TIE;
+ public static byte CTF_EVENT_MIN_LVL;
+ public static byte CTF_EVENT_MAX_LVL;
+ public static int CTF_EVENT_EFFECTS_REMOVAL;
+ public static List<SkillHolder> CTF_EVENT_RESTRICTED_SKILLS;
+ public static Map<Integer, Integer> CTF_EVENT_FIGHTER_BUFFS;
+ public static Map<Integer, Integer> CTF_EVENT_MAGE_BUFFS;
+ public static int CTF_EVENT_MAX_PARTICIPANTS_PER_IP;
+ public static boolean CTF_ALLOW_VOICED_COMMAND;
+
+ // TODO: DM Event
+ public static boolean DM_EVENT_ENABLED;
+ public static boolean DM_EVENT_IN_INSTANCE;
+ public static String DM_EVENT_INSTANCE_FILE;
+ public static String[] DM_EVENT_INTERVAL;
+ public static int DM_EVENT_PARTICIPATION_TIME;
+ public static int DM_EVENT_RUNNING_TIME;
+ public static int DM_EVENT_PARTICIPATION_NPC_ID;
+ public static int[] DM_EVENT_PARTICIPATION_NPC_COORDINATES = new int[4];
+ public static int[] DM_EVENT_PARTICIPATION_FEE = new int[2];
+ public static int DM_EVENT_MIN_PLAYERS;
+ public static int DM_EVENT_MAX_PLAYERS;
+ public static int DM_EVENT_RESPAWN_TELEPORT_DELAY;
+ public static int DM_EVENT_START_LEAVE_TELEPORT_DELAY;
+ public static List<int[]> DM_EVENT_PLAYER_COORDINATES;
+ public static Map<Integer, List<int[]>> DM_EVENT_REWARDS;
+ public static int DM_EVENT_REWARD_FIRST_PLAYERS;
+ public static boolean DM_EVENT_SCROLL_ALLOWED;
+ public static boolean DM_EVENT_POTIONS_ALLOWED;
+ public static boolean DM_EVENT_SUMMON_BY_ITEM_ALLOWED;
+ public static List<Integer> DM_DOORS_IDS_TO_OPEN;
+ public static List<Integer> DM_DOORS_IDS_TO_CLOSE;
+ public static boolean DM_EVENT_SHOW_TOP_RANK;
+ public static int DM_EVENT_LIST_TOP_RANK;
+ public static boolean DM_REWARD_TEAM_TIE;
+ public static byte DM_EVENT_MIN_LVL;
+ public static byte DM_EVENT_MAX_LVL;
+ public static int DM_EVENT_EFFECTS_REMOVAL;
+ public static Map<Integer, Integer> DM_EVENT_FIGHTER_BUFFS;
+ public static Map<Integer, Integer> DM_EVENT_MAGE_BUFFS;
+ public static int DM_EVENT_MAX_PARTICIPANTS_PER_IP;
+ public static boolean DM_ALLOW_VOICED_COMMAND;
+
public static boolean L2JMOD_ALLOW_WEDDING;
public static int L2JMOD_WEDDING_PRICE;
public static boolean L2JMOD_WEDDING_PUNISH_INFIDELITY;
@@ -2168,6 +2247,7 @@
L2JMOD_CHAMPION_ENABLE_VITALITY = L2JModSettings.getBoolean("ChampionEnableVitality", false);
L2JMOD_CHAMPION_ENABLE_IN_INSTANCES = L2JModSettings.getBoolean("ChampionEnableInInstances", false);
+ // TODO: TvT Event
TVT_EVENT_ENABLED = L2JModSettings.getBoolean("TvTEventEnabled", false);
TVT_EVENT_IN_INSTANCE = L2JModSettings.getBoolean("TvTEventInInstance", false);
TVT_EVENT_INSTANCE_FILE = L2JModSettings.getString("TvTEventInstanceFile", "coliseum.xml");
@@ -2176,6 +2256,30 @@
TVT_EVENT_RUNNING_TIME = L2JModSettings.getInt("TvTEventRunningTime", 1800);
TVT_EVENT_PARTICIPATION_NPC_ID = L2JModSettings.getInt("TvTEventParticipationNpcId", 0);
+ // TODO: CTF Event
+ CTF_EVENT_ENABLED = L2JModSettings.getBoolean("CTFEventEnabled", false);
+ CTF_EVENT_IN_INSTANCE = L2JModSettings.getBoolean("CTFEventInInstance", false);
+ CTF_EVENT_INSTANCE_FILE = L2JModSettings.getString("CTFEventInstanceFile", "coliseum.xml");
+ CTF_EVENT_INTERVAL = L2JModSettings.getString("CTFEventInterval", "20:00").split(",");
+ CTF_EVENT_PARTICIPATION_TIME = L2JModSettings.getInt("CTFEventParticipationTime", 3600);
+ CTF_EVENT_RUNNING_TIME = L2JModSettings.getInt("CTFEventRunningTime", 1800);
+ CTF_EVENT_PARTICIPATION_NPC_ID = L2JModSettings.getInt("CTFEventParticipationNpcId", 0);
+
+ CTF_EVENT_TEAM_1_HEADQUARTERS = L2JModSettings.getInt("CTFEventFirstTeamHeadquarters", 0);
+ CTF_EVENT_TEAM_2_HEADQUARTERS = L2JModSettings.getInt("CTFEventSecondTeamHeadquarters", 0);
+ CTF_EVENT_TEAM_1_FLAG = L2JModSettings.getInt("CTFEventFirstTeamFlag", 0);
+ CTF_EVENT_TEAM_2_FLAG = L2JModSettings.getInt("CTFEventSecondTeamFlag", 0);
+ CTF_EVENT_CAPTURE_SKILL = L2JModSettings.getInt("CTFEventCaptureSkillId", 0);
+
+ // TODO: DM Event
+ DM_EVENT_ENABLED = L2JModSettings.getBoolean("DMEventEnabled", false);
+ DM_EVENT_IN_INSTANCE = L2JModSettings.getBoolean("DMEventInInstance", false);
+ DM_EVENT_INSTANCE_FILE = L2JModSettings.getString("DMEventInstanceFile", "coliseum.xml");
+ DM_EVENT_INTERVAL = L2JModSettings.getString("DMEventInterval", "12:00").split(",");
+ DM_EVENT_PARTICIPATION_TIME = L2JModSettings.getInt("DMEventParticipationTime", 3600);
+ DM_EVENT_RUNNING_TIME = L2JModSettings.getInt("DMEventRunningTime", 1800);
+ DM_EVENT_PARTICIPATION_NPC_ID = L2JModSettings.getInt("DMEventParticipationNpcId", 70030);
+
L2JMOD_ALLOW_WEDDING = L2JModSettings.getBoolean("AllowWedding", false);
L2JMOD_WEDDING_PRICE = L2JModSettings.getInt("WeddingPrice", 250000000);
L2JMOD_WEDDING_PUNISH_INFIDELITY = L2JModSettings.getBoolean("WeddingPunishInfidelity", true);
@@ -2191,6 +2295,7 @@
L2JMOD_OLD_DROP_BEHAVIOR = L2JModSettings.getBoolean("OldDropBehavior", false);
+ // TODO: TvT Event
if (TVT_EVENT_PARTICIPATION_NPC_ID == 0)
{
TVT_EVENT_ENABLED = false;
@@ -2390,6 +2495,484 @@
}
}
+ // TODO: CTF Event
+ if (CTF_EVENT_PARTICIPATION_NPC_ID == 0)
+ {
+ CTF_EVENT_ENABLED = false;
+ _log.warning("CTFEventEngine[Config.load()]: invalid config property -> CTFEventParticipationNpcId");
+ }
+ else
+ {
+ String[] ctfNpcCoords = L2JModSettings.getString("CTFEventParticipationNpcCoordinates", "0,0,0").split(",");
+ if (ctfNpcCoords.length < 3)
+ {
+ CTF_EVENT_ENABLED = false;
+ _log.warning("CTFEventEngine[Config.load()]: invalid config property -> CTFEventParticipationNpcCoordinates");
+ }
+ else
+ {
+ CTF_EVENT_REWARDS = new ArrayList<>();
+ CTF_DOORS_IDS_TO_OPEN = new ArrayList<>();
+ CTF_DOORS_IDS_TO_CLOSE = new ArrayList<>();
+ CTF_EVENT_PARTICIPATION_NPC_COORDINATES = new int[4];
+ CTF_EVENT_TEAM_1_COORDINATES = new int[3];
+ CTF_EVENT_TEAM_2_COORDINATES = new int[3];
+ CTF_EVENT_PARTICIPATION_NPC_COORDINATES[0] = Integer.parseInt(ctfNpcCoords[0]);
+ CTF_EVENT_PARTICIPATION_NPC_COORDINATES[1] = Integer.parseInt(ctfNpcCoords[1]);
+ CTF_EVENT_PARTICIPATION_NPC_COORDINATES[2] = Integer.parseInt(ctfNpcCoords[2]);
+ if (ctfNpcCoords.length == 4)
+ {
+ CTF_EVENT_PARTICIPATION_NPC_COORDINATES[3] = Integer.parseInt(ctfNpcCoords[3]);
+ }
+ CTF_EVENT_MIN_PLAYERS_IN_TEAMS = L2JModSettings.getInt("CTFEventMinPlayersInTeams", 1);
+ CTF_EVENT_MAX_PLAYERS_IN_TEAMS = L2JModSettings.getInt("CTFEventMaxPlayersInTeams", 20);
+ CTF_EVENT_MIN_LVL = L2JModSettings.getByte("CTFEventMinPlayerLevel", (byte) 1);
+ CTF_EVENT_MAX_LVL = L2JModSettings.getByte("CTFEventMaxPlayerLevel", (byte) 80);
+ CTF_EVENT_RESPAWN_TELEPORT_DELAY = L2JModSettings.getInt("CTFEventRespawnTeleportDelay", 20);
+ CTF_EVENT_START_LEAVE_TELEPORT_DELAY = L2JModSettings.getInt("CTFEventStartLeaveTeleportDelay", 20);
+ CTF_EVENT_EFFECTS_REMOVAL = L2JModSettings.getInt("CTFEventEffectsRemoval", 0);
+ CTF_EVENT_MAX_PARTICIPANTS_PER_IP = L2JModSettings.getInt("CTFEventMaxParticipantsPerIP", 0);
+ CTF_ALLOW_VOICED_COMMAND = L2JModSettings.getBoolean("CTFAllowVoicedInfoCommand", false);
+ String[] CTFEventRestrictedSkills = L2JModSettings.getString("CTFEventRestrictedSkills", "840,841,842,5982,5983").split(",");
+ CTF_EVENT_RESTRICTED_SKILLS = new ArrayList<>(CTFEventRestrictedSkills.length);
+ for (String id : CTFEventRestrictedSkills)
+ {
+ CTF_EVENT_RESTRICTED_SKILLS.add(new SkillHolder(Integer.parseInt(id), 1));
+ }
+ CTF_EVENT_TEAM_1_NAME = L2JModSettings.getString("CTFEventTeam1Name", "Team1");
+ ctfNpcCoords = L2JModSettings.getString("CTFEventTeam1Coordinates", "0,0,0").split(",");
+ if (ctfNpcCoords.length < 3)
+ {
+ CTF_EVENT_ENABLED = false;
+ _log.warning("CTFEventEngine[Config.load()]: invalid config property -> CTFEventTeam1Coordinates");
+ }
+ else
+ {
+ CTF_EVENT_TEAM_1_COORDINATES[0] = Integer.parseInt(ctfNpcCoords[0]);
+ CTF_EVENT_TEAM_1_COORDINATES[1] = Integer.parseInt(ctfNpcCoords[1]);
+ CTF_EVENT_TEAM_1_COORDINATES[2] = Integer.parseInt(ctfNpcCoords[2]);
+ CTF_EVENT_TEAM_2_NAME = L2JModSettings.getString("CTFEventTeam2Name", "Team2");
+ ctfNpcCoords = L2JModSettings.getString("CTFEventTeam2Coordinates", "0,0,0").split(",");
+ if (ctfNpcCoords.length < 3)
+ {
+ CTF_EVENT_ENABLED = false;
+ _log.warning("CTFEventEngine[Config.load()]: invalid config property -> CTFEventTeam2Coordinates");
+ }
+ else
+ {
+ CTF_EVENT_TEAM_2_COORDINATES[0] = Integer.parseInt(ctfNpcCoords[0]);
+ CTF_EVENT_TEAM_2_COORDINATES[1] = Integer.parseInt(ctfNpcCoords[1]);
+ CTF_EVENT_TEAM_2_COORDINATES[2] = Integer.parseInt(ctfNpcCoords[2]);
+ ctfNpcCoords = L2JModSettings.getString("CTFEventTeam1FlagCoordinates", "0,0,0").split(",");
+ if (ctfNpcCoords.length < 3)
+ {
+ CTF_EVENT_ENABLED = false;
+ _log.warning("CTFEventEngine[Config.load()]: invalid config property -> CTFEventTeam1FlagCoordinates");
+ }
+ else
+ {
+ CTF_EVENT_TEAM_1_FLAG_COORDINATES[0] = Integer.parseInt(ctfNpcCoords[0]);
+ CTF_EVENT_TEAM_1_FLAG_COORDINATES[1] = Integer.parseInt(ctfNpcCoords[1]);
+ CTF_EVENT_TEAM_1_FLAG_COORDINATES[2] = Integer.parseInt(ctfNpcCoords[2]);
+ ctfNpcCoords = L2JModSettings.getString("CTFEventTeam2FlagCoordinates", "0,0,0").split(",");
+ if (ctfNpcCoords.length < 3)
+ {
+ CTF_EVENT_ENABLED = false;
+ _log.warning("CTFEventEngine[Config.load()]: invalid config property -> CTFEventTeam2FlagCoordinates");
+ }
+ else
+ {
+ CTF_EVENT_TEAM_2_FLAG_COORDINATES[0] = Integer.parseInt(ctfNpcCoords[0]);
+ CTF_EVENT_TEAM_2_FLAG_COORDINATES[1] = Integer.parseInt(ctfNpcCoords[1]);
+ CTF_EVENT_TEAM_2_FLAG_COORDINATES[2] = Integer.parseInt(ctfNpcCoords[2]);
+ ctfNpcCoords = L2JModSettings.getString("CTFEventParticipationFee", "0,0").split(",");
+ try
+ {
+ CTF_EVENT_PARTICIPATION_FEE[0] = Integer.parseInt(ctfNpcCoords[0]);
+ CTF_EVENT_PARTICIPATION_FEE[1] = Integer.parseInt(ctfNpcCoords[1]);
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (ctfNpcCoords.length > 0)
+ {
+ _log.warning("CTFEventEngine[Config.load()]: invalid config property -> CTFEventParticipationFee");
+ }
+ }
+ ctfNpcCoords = L2JModSettings.getString("CTFEventReward", "57,100000").split(";");
+ for (String reward : ctfNpcCoords)
+ {
+ String[] rewardSplit = reward.split(",");
+ if (rewardSplit.length != 2)
+ {
+ _log.warning(StringUtil.concat("CTFEventEngine[Config.load()]: invalid config property -> CTFEventReward \"", reward, "\""));
+ }
+ else
+ {
+ try
+ {
+ CTF_EVENT_REWARDS.add(new int[]
+ {
+ Integer.parseInt(rewardSplit[0]),
+ Integer.parseInt(rewardSplit[1])
+ });
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!reward.isEmpty())
+ {
+ _log.warning(StringUtil.concat("CTFEventEngine[Config.load()]: invalid config property -> CTFEventReward \"", reward, "\""));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ CTF_EVENT_TARGET_TEAM_MEMBERS_ALLOWED = L2JModSettings.getBoolean("CTFEventTargetTeamMembersAllowed", true);
+ CTF_EVENT_SCROLL_ALLOWED = L2JModSettings.getBoolean("CTFEventScrollsAllowed", false);
+ CTF_EVENT_POTIONS_ALLOWED = L2JModSettings.getBoolean("CTFEventPotionsAllowed", false);
+ CTF_EVENT_SUMMON_BY_ITEM_ALLOWED = L2JModSettings.getBoolean("CTFEventSummonByItemAllowed", false);
+ CTF_REWARD_TEAM_TIE = L2JModSettings.getBoolean("CTFRewardTeamTie", false);
+ ctfNpcCoords = L2JModSettings.getString("CTFDoorsToOpen", "").split(";");
+ for (String door : ctfNpcCoords)
+ {
+ try
+ {
+ CTF_DOORS_IDS_TO_OPEN.add(Integer.parseInt(door));
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!door.isEmpty())
+ {
+ _log.warning(StringUtil.concat("CTFEventEngine[Config.load()]: invalid config property -> CTFDoorsToOpen \"", door, "\""));
+ }
+ }
+ }
+
+ ctfNpcCoords = L2JModSettings.getString("CTFDoorsToClose", "").split(";");
+ for (String door : ctfNpcCoords)
+ {
+ try
+ {
+ CTF_DOORS_IDS_TO_CLOSE.add(Integer.parseInt(door));
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!door.isEmpty())
+ {
+ _log.warning(StringUtil.concat("CTFEventEngine[Config.load()]: invalid config property -> CTFDoorsToClose \"", door, "\""));
+ }
+ }
+ }
+
+ ctfNpcCoords = L2JModSettings.getString("CTFEventFighterBuffs", "").split(";");
+ if (!ctfNpcCoords[0].isEmpty())
+ {
+ CTF_EVENT_FIGHTER_BUFFS = new HashMap<>(ctfNpcCoords.length);
+ for (String skill : ctfNpcCoords)
+ {
+ String[] skillSplit = skill.split(",");
+ if (skillSplit.length != 2)
+ {
+ _log.warning(StringUtil.concat("CTFEventEngine[Config.load()]: invalid config property -> CTFEventFighterBuffs \"", skill, "\""));
+ }
+ else
+ {
+ try
+ {
+ CTF_EVENT_FIGHTER_BUFFS.put(Integer.parseInt(skillSplit[0]), Integer.parseInt(skillSplit[1]));
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!skill.isEmpty())
+ {
+ _log.warning(StringUtil.concat("CTFEventEngine[Config.load()]: invalid config property -> CTFEventFighterBuffs \"", skill, "\""));
+ }
+ }
+ }
+ }
+ }
+
+ ctfNpcCoords = L2JModSettings.getString("CTFEventMageBuffs", "").split(";");
+ if (!ctfNpcCoords[0].isEmpty())
+ {
+ CTF_EVENT_MAGE_BUFFS = new HashMap<>(ctfNpcCoords.length);
+ for (String skill : ctfNpcCoords)
+ {
+ String[] skillSplit = skill.split(",");
+ if (skillSplit.length != 2)
+ {
+ _log.warning(StringUtil.concat("CTFEventEngine[Config.load()]: invalid config property -> CTFEventMageBuffs \"", skill, "\""));
+ }
+ else
+ {
+ try
+ {
+ CTF_EVENT_MAGE_BUFFS.put(Integer.parseInt(skillSplit[0]), Integer.parseInt(skillSplit[1]));
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!skill.isEmpty())
+ {
+ _log.warning(StringUtil.concat("CTFEventEngine[Config.load()]: invalid config property -> CTFEventMageBuffs \"", skill, "\""));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // TODO: DM Event
+ if (DM_EVENT_PARTICIPATION_NPC_ID == 0)
+ {
+ DM_EVENT_ENABLED = false;
+ _log.warning("DMEventEngine[Config.load()]: invalid config property -> DMEventParticipationNpcId");
+ }
+ else
+ {
+ String[] dmNpcCoords = L2JModSettings.getString("DMEventParticipationNpcCoordinates", "0,0,0").split(",");
+ if (dmNpcCoords.length < 3)
+ {
+ DM_EVENT_ENABLED = false;
+ _log.warning("DMEventEngine[Config.load()]: invalid config property -> DMEventParticipationNpcCoordinates");
+ }
+ else
+ {
+ DM_EVENT_REWARDS = new HashMap<>();
+ DM_DOORS_IDS_TO_OPEN = new ArrayList<>();
+ DM_DOORS_IDS_TO_CLOSE = new ArrayList<>();
+ DM_EVENT_PLAYER_COORDINATES = new ArrayList<>();
+ DM_EVENT_PARTICIPATION_NPC_COORDINATES = new int[4];
+ DM_EVENT_PARTICIPATION_NPC_COORDINATES[0] = Integer.parseInt(dmNpcCoords[0]);
+ DM_EVENT_PARTICIPATION_NPC_COORDINATES[1] = Integer.parseInt(dmNpcCoords[1]);
+ DM_EVENT_PARTICIPATION_NPC_COORDINATES[2] = Integer.parseInt(dmNpcCoords[2]);
+ if (dmNpcCoords.length == 4)
+ {
+ DM_EVENT_PARTICIPATION_NPC_COORDINATES[3] = Integer.parseInt(dmNpcCoords[3]);
+ }
+ DM_EVENT_MIN_PLAYERS = L2JModSettings.getInt("DMEventMinPlayers", 2);
+ DM_EVENT_MAX_PLAYERS = L2JModSettings.getInt("DMEventMaxPlayers", 20);
+ DM_EVENT_MIN_LVL = L2JModSettings.getByte("DMEventMinPlayerLevel", (byte) 1);
+ DM_EVENT_MAX_LVL = L2JModSettings.getByte("DMEventMaxPlayerLevel", (byte) 80);
+ DM_EVENT_RESPAWN_TELEPORT_DELAY = L2JModSettings.getInt("DMEventRespawnTeleportDelay", 20);
+ DM_EVENT_START_LEAVE_TELEPORT_DELAY = L2JModSettings.getInt("DMEventStartLeaveTeleportDelay", 20);
+ DM_EVENT_EFFECTS_REMOVAL = L2JModSettings.getInt("DMEventEffectsRemoval", 0);
+ DM_EVENT_MAX_PARTICIPANTS_PER_IP = L2JModSettings.getInt("DMEventMaxParticipantsPerIP", 0);
+ DM_ALLOW_VOICED_COMMAND = L2JModSettings.getBoolean("DMAllowVoicedInfoCommand", false);
+ DM_EVENT_REWARD_FIRST_PLAYERS = L2JModSettings.getInt("DMEventRewardFirstPlayers", 3);
+ dmNpcCoords = L2JModSettings.getString("DMEventReward", "57,100000").split(",");
+ if (dmNpcCoords.length > DM_EVENT_REWARD_FIRST_PLAYERS)
+ {
+ DM_EVENT_ENABLED = false;
+ _log.warning("DMEventEngine[Config.load()]: invalid config property -> DMEventReward");
+ }
+ else
+ {
+ int i = 1;
+ for (String pos : propertySplit)
+ {
+ List<int[]> value = new ArrayList<>();
+ String[] rewardSplit = pos.split("\\;");
+ for (String rewards : rewardSplit)
+ {
+ String[] reward = rewards.split("\\,");
+ if (reward.length != 2)
+ {
+ _log.warning(StringUtil.concat("DMEventEngine[Config.load()]: invalid config property -> DMEventReward \"", pos, "\""));
+ }
+ else
+ {
+ try
+ {
+ value.add(new int[]
+ {
+ Integer.parseInt(reward[0]),
+ Integer.parseInt(reward[1])
+ });
+ }
+ catch (NumberFormatException nfe)
+ {
+ _log.warning(StringUtil.concat("DMEventEngine[Config.load()]: invalid config property -> DMEventReward \"", pos, "\""));
+ }
+ }
+
+ try
+ {
+ if (value.isEmpty())
+ {
+ DM_EVENT_REWARDS.put(i, DM_EVENT_REWARDS.get(i - 1));
+ }
+ else
+ {
+ DM_EVENT_REWARDS.put(i, value);
+ }
+ }
+ catch (Exception e)
+ {
+ _log.warning("DMEventEngine[Config.load()]: invalid config property -> DMEventReward array index out of bounds (1)");
+ e.printStackTrace();
+ }
+ i++;
+ }
+ }
+
+ int countPosRewards = DM_EVENT_REWARDS.size();
+ if (countPosRewards < DM_EVENT_REWARD_FIRST_PLAYERS)
+ {
+ for (i = countPosRewards + 1; i <= DM_EVENT_REWARD_FIRST_PLAYERS; i++)
+ {
+ try
+ {
+ DM_EVENT_REWARDS.put(i, DM_EVENT_REWARDS.get(i - 1));
+ }
+ catch (Exception e)
+ {
+ _log.warning("DMEventEngine[Config.load()]: invalid config property -> DMEventReward array index out of bounds (2)");
+ e.printStackTrace();
+ }
+ }
+ }
+
+ dmNpcCoords = L2JModSettings.getString("DMEventPlayerCoordinates", "0,0,0").split(";");
+ if (dmNpcCoords.length != 3)
+ {
+ DM_EVENT_ENABLED = false;
+ _log.warning("DMEventEngine[Config.load()]: invalid config property -> DMEventPlayerCoordinates");
+ }
+ else
+ {
+ try
+ {
+ DM_EVENT_PLAYER_COORDINATES.add(new int[]
+ {
+ Integer.parseInt(dmNpcCoords[0]),
+ Integer.parseInt(dmNpcCoords[1]),
+ Integer.parseInt(dmNpcCoords[2])
+ });
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (dmNpcCoords.length > 0)
+ {
+ _log.warning("DMEventEngine[Config.load()]: invalid config property -> DMEventPlayerCoordinates");
+ }
+ }
+
+ dmNpcCoords = L2JModSettings.getString("DMEventParticipationFee", "0,0").split(",");
+ try
+ {
+ DM_EVENT_PARTICIPATION_FEE[0] = Integer.parseInt(dmNpcCoords[0]);
+ DM_EVENT_PARTICIPATION_FEE[1] = Integer.parseInt(dmNpcCoords[1]);
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (dmNpcCoords.length > 0)
+ {
+ _log.warning("DMEventEngine[Config.load()]: invalid config property -> DMEventParticipationFee");
+ }
+ }
+
+ DM_EVENT_SCROLL_ALLOWED = L2JModSettings.getBoolean("DMEventScrollsAllowed", false);
+ DM_EVENT_POTIONS_ALLOWED = L2JModSettings.getBoolean("DMEventPotionsAllowed", false);
+ DM_EVENT_SUMMON_BY_ITEM_ALLOWED = L2JModSettings.getBoolean("DMEventSummonByItemAllowed", false);
+ DM_EVENT_SHOW_TOP_RANK = L2JModSettings.getBoolean("DMEventShowTopRank", false);
+ DM_EVENT_LIST_TOP_RANK = L2JModSettings.getInt("DMEventListTopRank", 10);
+ DM_REWARD_TEAM_TIE = L2JModSettings.getBoolean("DMRewardPlayerTie", false);
+ dmNpcCoords = L2JModSettings.getString("DMDoorsToOpen", "").split(";");
+ for (String door : dmNpcCoords)
+ {
+ try
+ {
+ DM_DOORS_IDS_TO_OPEN.add(Integer.parseInt(door));
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!door.isEmpty())
+ {
+ _log.warning(StringUtil.concat("DMEventEngine[Config.load()]: invalid config property -> DMDoorsToOpen \"", door, "\""));
+ }
+ }
+ }
+
+ dmNpcCoords = L2JModSettings.getString("DMDoorsToClose", "").split(";");
+ for (String door : dmNpcCoords)
+ {
+ try
+ {
+ DM_DOORS_IDS_TO_CLOSE.add(Integer.parseInt(door));
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!door.isEmpty())
+ {
+ _log.warning(StringUtil.concat("DMEventEngine[Config.load()]: invalid config property -> DMDoorsToClose \"", door, "\""));
+ }
+ }
+ }
+
+ dmNpcCoords = L2JModSettings.getString("DMEventFighterBuffs", "").split(";");
+ if (!dmNpcCoords[0].isEmpty())
+ {
+ DM_EVENT_FIGHTER_BUFFS = new HashMap<>(dmNpcCoords.length);
+ for (String skill : dmNpcCoords)
+ {
+ String[] skillSplit = skill.split(",");
+ if (skillSplit.length != 2)
+ {
+ _log.warning(StringUtil.concat("DMEventEngine[Config.load()]: invalid config property -> DMEventFighterBuffs \"", skill, "\""));
+ }
+ else
+ {
+ try
+ {
+ DM_EVENT_FIGHTER_BUFFS.put(Integer.parseInt(skillSplit[0]), Integer.parseInt(skillSplit[1]));
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!skill.isEmpty())
+ {
+ _log.warning(StringUtil.concat("DMEventEngine[Config.load()]: invalid config property -> DMEventFighterBuffs \"", skill, "\""));
+ }
+ }
+ }
+ }
+ }
+
+ dmNpcCoords = L2JModSettings.getString("DMEventMageBuffs", "").split(";");
+ if (!dmNpcCoords[0].isEmpty())
+ {
+ DM_EVENT_MAGE_BUFFS = new HashMap<>(dmNpcCoords.length);
+ for (String skill : dmNpcCoords)
+ {
+ String[] skillSplit = skill.split(",");
+ if (skillSplit.length != 2)
+ {
+ _log.warning(StringUtil.concat("DMEventEngine[Config.load()]: invalid config property -> DMEventMageBuffs \"", skill, "\""));
+ }
+ else
+ {
+ try
+ {
+ DM_EVENT_MAGE_BUFFS.put(Integer.parseInt(skillSplit[0]), Integer.parseInt(skillSplit[1]));
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!skill.isEmpty())
+ {
+ _log.warning(StringUtil.concat("DMEventEngine[Config.load()]: invalid config property -> DMEventMageBuffs \"", skill, "\""));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
BANKING_SYSTEM_ENABLED = L2JModSettings.getBoolean("BankingEnabled", false);
BANKING_SYSTEM_GOLDBARS = L2JModSettings.getInt("BankingGoldbarCount", 1);
BANKING_SYSTEM_ADENA = L2JModSettings.getInt("BankingAdenaCount", 500000000);
@@ -3489,6 +4072,7 @@
case "weddingdivorcecosts":
L2JMOD_WEDDING_DIVORCE_COSTS = Integer.parseInt(pValue);
break;
+ // TODO: TvT Event
case "tvteventenabled":
TVT_EVENT_ENABLED = Boolean.parseBoolean(pValue);
break;
@@ -3504,6 +4088,39 @@
case "tvteventparticipationnpcid":
TVT_EVENT_PARTICIPATION_NPC_ID = Integer.parseInt(pValue);
break;
+ // TODO: CTF Event
+ case "ctfeventenabled":
+ CTF_EVENT_ENABLED = Boolean.parseBoolean(pValue);
+ break;
+ case "ctfeventinterval":
+ CTF_EVENT_INTERVAL = pValue.split(",");
+ break;
+ case "ctfeventparticipationtime":
+ CTF_EVENT_PARTICIPATION_TIME = Integer.parseInt(pValue);
+ break;
+ case "ctfeventrunningtime":
+ CTF_EVENT_RUNNING_TIME = Integer.parseInt(pValue);
+ break;
+ case "ctfeventparticipationnpcid":
+ CTF_EVENT_PARTICIPATION_NPC_ID = Integer.parseInt(pValue);
+ break;
+ // TODO: DM Event
+ case "dmeventenabled":
+ DM_EVENT_ENABLED = Boolean.parseBoolean(pValue);
+ break;
+ case "dmeventinterval":
+ DM_EVENT_INTERVAL = pValue.split(",");
+ break;
+ case "dmeventparticipationtime":
+ DM_EVENT_PARTICIPATION_TIME = Integer.parseInt(pValue);
+ break;
+ case "dmeventrunningtime":
+ DM_EVENT_RUNNING_TIME = Integer.parseInt(pValue);
+ break;
+ case "dmeventparticipationnpcid":
+ DM_EVENT_PARTICIPATION_NPC_ID = Integer.parseInt(pValue);
+ break;
+ // Others
case "enablewarehousesortingclan":
L2JMOD_ENABLE_WAREHOUSESORTING_CLAN = Boolean.parseBoolean(pValue);
break;
Index: java/com/l2jserver/gameserver/engines/DocumentBase.java
===================================================================
--- java/com/l2jserver/gameserver/engines/DocumentBase.java (revision 10485)
+++ java/com/l2jserver/gameserver/engines/DocumentBase.java (working copy)
@@ -55,6 +55,7 @@
import com.l2jserver.gameserver.model.conditions.ConditionPlayerActiveEffectId;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerActiveSkillId;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerAgathionId;
+import com.l2jserver.gameserver.model.conditions.ConditionPlayerCTFEvent;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerCallPc;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanCreateBase;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanCreateOutpost;
@@ -73,6 +74,7 @@
import com.l2jserver.gameserver.model.conditions.ConditionPlayerClassIdRestriction;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerCloakStatus;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerCp;
+import com.l2jserver.gameserver.model.conditions.ConditionPlayerDMEvent;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerFlyMounted;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerGrade;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerHasCastle;
@@ -642,6 +644,7 @@
cond = joinAnd(cond, new ConditionPlayerIsClanLeader(val));
break;
}
+ // TODO: TvT Event
case "ontvtevent":
{
boolean val = Boolean.parseBoolean(a.getNodeValue());
@@ -648,6 +651,20 @@
cond = joinAnd(cond, new ConditionPlayerTvTEvent(val));
break;
}
+ // TODO: CTF Event
+ case "onctfevent":
+ {
+ boolean val = Boolean.parseBoolean(a.getNodeValue());
+ cond = joinAnd(cond, new ConditionPlayerCTFEvent(val));
+ break;
+ }
+ // TODO: DM Event
+ case "ondmevent":
+ {
+ boolean val = Boolean.parseBoolean(a.getNodeValue());
+ cond = joinAnd(cond, new ConditionPlayerDMEvent(val));
+ break;
+ }
case "pledgeclass":
{
int pledgeClass = Integer.decode(getValue(a.getNodeValue(), null));
Index: java/com/l2jserver/gameserver/GameServer.java
===================================================================
--- java/com/l2jserver/gameserver/GameServer.java (revision 10485)
+++ java/com/l2jserver/gameserver/GameServer.java (working copy)
@@ -128,7 +128,9 @@
import com.l2jserver.gameserver.model.PartyMatchRoomList;
import com.l2jserver.gameserver.model.PartyMatchWaitingList;
import com.l2jserver.gameserver.model.entity.Hero;
-import com.l2jserver.gameserver.model.entity.TvTManager;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFManager;
+import com.l2jserver.gameserver.model.entity.events.dm.DMManager;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTManager;
import com.l2jserver.gameserver.model.events.EventDispatcher;
import com.l2jserver.gameserver.model.olympiad.Olympiad;
import com.l2jserver.gameserver.network.L2GameClient;
@@ -374,7 +376,13 @@
_log.info("IdFactory: Free ObjectID's remaining: " + IdFactory.getInstance().size());
+ // TODO: TvT Event
TvTManager.getInstance();
+ // TODO: CTF Event
+ CTFManager.getInstance();
+ // TODO: DM Event
+ DMManager.getInstance();
+
KnownListUpdateTaskManager.getInstance();
if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.RESTORE_OFFLINERS)
Index: java/com/l2jserver/gameserver/instancemanager/AntiFeedManager.java
===================================================================
--- java/com/l2jserver/gameserver/instancemanager/AntiFeedManager.java (revision 10485)
+++ java/com/l2jserver/gameserver/instancemanager/AntiFeedManager.java (working copy)
@@ -32,7 +32,9 @@
public static final int GAME_ID = 0;
public static final int OLYMPIAD_ID = 1;
public static final int TVT_ID = 2;
- public static final int L2EVENT_ID = 3;
+ public static final int CTF_ID = 3;
+ public static final int DM_ID = 4;
+ public static final int L2EVENT_ID = 5;
private final Map<Integer, Long> _lastDeathTimes = new ConcurrentHashMap<>();
private final Map<Integer, Map<Integer, AtomicInteger>> _eventIPs = new ConcurrentHashMap<>();
Index: java/com/l2jserver/gameserver/model/actor/instance/L2CubicInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2CubicInstance.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2CubicInstance.java (working copy)
@@ -38,8 +38,11 @@
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicDisappear;
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicHeal;
import com.l2jserver.gameserver.model.effects.L2EffectType;
-import com.l2jserver.gameserver.model.entity.TvTEvent;
-import com.l2jserver.gameserver.model.entity.TvTEventTeam;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEvent;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEventTeam;
+import com.l2jserver.gameserver.model.entity.events.dm.DMEvent;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEvent;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEventTeam;
import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.stats.Formulas;
@@ -258,7 +261,8 @@
{
return;
}
- // TvT event targeting
+
+ // TODO: TvT Event - targeting
if (TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(_owner.getObjectId()))
{
TvTEventTeam enemyTeam = TvTEvent.getParticipantEnemyTeam(_owner.getObjectId());
@@ -273,6 +277,37 @@
}
return;
}
+
+ // TODO: CTF Event - targeting
+ if (CTFEvent.isStarted() && CTFEvent.isPlayerParticipant(_owner.getObjectId()))
+ {
+ CTFEventTeam enemyTeam = CTFEvent.getParticipantEnemyTeam(_owner.getObjectId());
+
+ if (ownerTarget.getActingPlayer() != null)
+ {
+ L2PcInstance target = ownerTarget.getActingPlayer();
+ if (enemyTeam.containsPlayer(target.getObjectId()) && !(target.isDead()))
+ {
+ _target = (L2Character) ownerTarget;
+ }
+ }
+ return;
+ }
+
+ // TODO: DM Event - targeting
+ if (DMEvent.isStarted() && DMEvent.isPlayerParticipant(_owner.getObjectId()))
+ {
+ if (ownerTarget.getActingPlayer() != null)
+ {
+ L2PcInstance target = ownerTarget.getActingPlayer();
+ if (!target.isDead())
+ {
+ _target = (L2Character) ownerTarget;
+ }
+ }
+ return;
+ }
+
// Duel targeting
if (_owner.isInDuel())
{
Index: java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java (working copy)
@@ -195,7 +195,9 @@
import com.l2jserver.gameserver.model.entity.Instance;
import com.l2jserver.gameserver.model.entity.L2Event;
import com.l2jserver.gameserver.model.entity.Siege;
-import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEvent;
+import com.l2jserver.gameserver.model.entity.events.dm.DMEvent;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEvent;
import com.l2jserver.gameserver.model.events.EventDispatcher;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerEquipItem;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerFameChanged;
@@ -5133,7 +5135,12 @@
{
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerPvPKill(pk, this), this);
+ // TODO: TvT Event
TvTEvent.onKill(killer, this);
+ // TODO: CTF Event
+ CTFEvent.onKill(killer, this);
+ // TODO: DM Event
+ DMEvent.onKill(killer, this);
if (L2Event.isParticipant(pk))
{
@@ -8278,7 +8285,7 @@
return false;
}
- // Check if the attacker is in TvT and TvT is started
+ // Check if the attacker is in event and event is started
if (isOnEvent())
{
return true;
@@ -10769,7 +10776,12 @@
summon.updateAndBroadcastStatus(0);
}
+ // TODO: TvT Event
TvTEvent.onTeleported(this);
+ // TODO: CTF Event
+ CTFEvent.onTeleported(this);
+ // TODO: DM Event
+ DMEvent.onTeleported(this);
}
@Override
@@ -11436,7 +11448,7 @@
_log.log(Level.SEVERE, "deleteMe()", e);
}
- // TvT Event removal
+ // TODO: TvT Event - removal
try
{
TvTEvent.onLogout(this);
@@ -11446,6 +11458,26 @@
_log.log(Level.SEVERE, "deleteMe()", e);
}
+ // TODO: CTF Event - removal
+ try
+ {
+ CTFEvent.onLogout(this);
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.SEVERE, "deleteMe()", e);
+ }
+
+ // TODO: DM Event - removal
+ try
+ {
+ DMEvent.onLogout(this);
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.SEVERE, "deleteMe()", e);
+ }
+
// Update database with items in its inventory and remove them from the world
try
{
Index: java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCallPc.java
===================================================================
--- java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCallPc.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCallPc.java (working copy)
@@ -20,7 +20,9 @@
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEvent;
+import com.l2jserver.gameserver.model.entity.events.dm.DMEvent;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEvent;
import com.l2jserver.gameserver.model.items.L2Item;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.zone.ZoneId;
@@ -57,11 +59,24 @@
{
canCallPlayer = false;
}
+ // TODO: TvT Event
else if (!TvTEvent.onEscapeUse(player.getObjectId()))
{
player.sendPacket(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING);
canCallPlayer = false;
}
+ // TODO: CTF Event
+ else if (!CTFEvent.onEscapeUse(player.getObjectId()))
+ {
+ player.sendPacket(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING);
+ canCallPlayer = false;
+ }
+ // TODO: DM Event
+ else if (!DMEvent.onEscapeUse(player.getObjectId()))
+ {
+ player.sendPacket(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING);
+ canCallPlayer = false;
+ }
else if (player.isInsideZone(ZoneId.NO_SUMMON_FRIEND) || player.isInsideZone(ZoneId.JAIL) || player.isFlyingMounted())
{
player.sendPacket(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING);
Index: java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCanEscape.java
===================================================================
--- java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCanEscape.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCanEscape.java (working copy)
@@ -22,7 +22,9 @@
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEvent;
+import com.l2jserver.gameserver.model.entity.events.dm.DMEvent;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEvent;
import com.l2jserver.gameserver.model.items.L2Item;
import com.l2jserver.gameserver.model.skills.Skill;
@@ -48,10 +50,21 @@
{
canTeleport = false;
}
+ // TODO: TvT Event
else if (!TvTEvent.onEscapeUse(player.getObjectId()))
{
canTeleport = false;
}
+ // TODO: CTF Event
+ else if (!CTFEvent.onEscapeUse(player.getObjectId()))
+ {
+ canTeleport = false;
+ }
+ // TODO: DM Event
+ else if (!DMEvent.onEscapeUse(player.getObjectId()))
+ {
+ canTeleport = false;
+ }
else if (player.isInDuel())
{
canTeleport = false;
Index: java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCTFEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCTFEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCTFEvent.java (working copy)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.conditions;
+
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEvent;
+import com.l2jserver.gameserver.model.items.L2Item;
+import com.l2jserver.gameserver.model.skills.Skill;
+
+/**
+ * The Class ConditionPlayerCTFEvent.
+ */
+public class ConditionPlayerCTFEvent extends Condition
+{
+ private final boolean _val;
+
+ /**
+ * Instantiates a new condition player tv t event.
+ * @param val the val
+ */
+ public ConditionPlayerCTFEvent(boolean val)
+ {
+ _val = val;
+ }
+
+ @Override
+ public boolean testImpl(L2Character effector, L2Character effected, Skill skill, L2Item item)
+ {
+ final L2PcInstance player = effector.getActingPlayer();
+ if ((player == null) || !CTFEvent.isStarted())
+ {
+ return !_val;
+ }
+ return (CTFEvent.isPlayerParticipant(player.getObjectId()) == _val);
+ }
+}
Index: java/com/l2jserver/gameserver/model/conditions/ConditionPlayerDMEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/conditions/ConditionPlayerDMEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/conditions/ConditionPlayerDMEvent.java (working copy)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.conditions;
+
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.events.dm.DMEvent;
+import com.l2jserver.gameserver.model.items.L2Item;
+import com.l2jserver.gameserver.model.skills.Skill;
+
+/**
+ * The Class ConditionPlayerDMEvent.
+ */
+public class ConditionPlayerDMEvent extends Condition
+{
+ private final boolean _val;
+
+ /**
+ * Instantiates a new condition player tv t event.
+ * @param val the val
+ */
+ public ConditionPlayerDMEvent(boolean val)
+ {
+ _val = val;
+ }
+
+ @Override
+ public boolean testImpl(L2Character effector, L2Character effected, Skill skill, L2Item item)
+ {
+ final L2PcInstance player = effector.getActingPlayer();
+ if ((player == null) || !DMEvent.isStarted())
+ {
+ return !_val;
+ }
+ return (DMEvent.isPlayerParticipant(player.getObjectId()) == _val);
+ }
+}
Index: java/com/l2jserver/gameserver/model/conditions/ConditionPlayerTvTEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/conditions/ConditionPlayerTvTEvent.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/conditions/ConditionPlayerTvTEvent.java (working copy)
@@ -20,7 +20,7 @@
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEvent;
import com.l2jserver.gameserver.model.items.L2Item;
import com.l2jserver.gameserver.model.skills.Skill;
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEvent.java (working copy)
@@ -0,0 +1,1478 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.data.xml.impl.DoorData;
+import com.l2jserver.gameserver.data.xml.impl.NpcData;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.SkillData;
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.Location;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
+import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventStart;
+import com.l2jserver.gameserver.model.holders.SkillHolder;
+import com.l2jserver.gameserver.model.itemcontainer.Inventory;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.model.skills.CommonSkill;
+import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.network.NpcStringId;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
+import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.util.Util;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author HorridoJoho
+ */
+public class CTFEvent
+{
+ enum EventState
+ {
+ INACTIVE,
+ INACTIVATING,
+ PARTICIPATING,
+ STARTING,
+ STARTED,
+ REWARDING
+ }
+
+ protected static final Logger _log = Logger.getLogger(CTFEvent.class.getName());
+ /** html path **/
+ private static final String htmlPath = "data/scripts/custom/events/CTF/CTFManager/";
+ /** The teams of the CTFEvent<br> */
+ private static CTFEventTeam[] _teams = new CTFEventTeam[2];
+ /** The state of the CTFEvent<br> */
+ private static EventState _state = EventState.INACTIVE;
+ /** The spawn of the participation npc<br> */
+ private static L2Spawn _npcSpawn = null;
+ /** the npc instance of the participation npc<br> */
+ private static L2Npc _lastNpcSpawn = null;
+ /** The spawn of Team1 flag<br> */
+ private static L2Spawn _flag1Spawn = null;
+ /** the npc instance Team1 flag<br> */
+ private static L2Npc _lastFlag1Spawn = null;
+ /** The spawn of Team2 flag<br> */
+ private static L2Spawn _flag2Spawn = null;
+ /** the npc instance of Team2 flag<br> */
+ private static L2Npc _lastFlag2Spawn = null;
+ /** the Team 1 flag carrier L2PcInstance<br> */
+ private static L2PcInstance _team1Carrier = null;
+ /** the Team 2 flag carrier L2PcInstance<br> */
+ private static L2PcInstance _team2Carrier = null;
+ /** the Team 1 flag carrier right hand item<br> */
+ private static L2ItemInstance _team1CarrierRHand = null;
+ /** the Team 2 flag carrier right hand item<br> */
+ private static L2ItemInstance _team2CarrierRHand = null;
+ /** the Team 1 flag carrier left hand item<br> */
+ private static L2ItemInstance _team1CarrierLHand = null;
+ /** the Team 2 flag carrier left hand item<br> */
+ private static L2ItemInstance _team2CarrierLHand = null;
+ /** Instance id<br> */
+ private static int _CTFEventInstance = 0;
+
+ /**
+ * No instance of this class!<br>
+ */
+ private CTFEvent()
+ {
+ }
+
+ /**
+ * Teams initializing<br>
+ */
+ public static void init()
+ {
+ AntiFeedManager.getInstance().registerEvent(AntiFeedManager.CTF_ID);
+ _teams[0] = new CTFEventTeam(Config.CTF_EVENT_TEAM_1_NAME, Config.CTF_EVENT_TEAM_1_COORDINATES);
+ _teams[1] = new CTFEventTeam(Config.CTF_EVENT_TEAM_2_NAME, Config.CTF_EVENT_TEAM_2_COORDINATES);
+ }
+
+ /**
+ * Starts the participation of the CTFEvent<br>
+ * 1. Get L2NpcTemplate by Config.CTF_EVENT_PARTICIPATION_NPC_ID<br>
+ * 2. Try to spawn a new npc of it<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startParticipation()
+ {
+ try
+ {
+ _npcSpawn = new L2Spawn(Config.CTF_EVENT_PARTICIPATION_NPC_ID);
+
+ _npcSpawn.setX(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[0]);
+ _npcSpawn.setY(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[1]);
+ _npcSpawn.setZ(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ _npcSpawn.setAmount(1);
+ _npcSpawn.setHeading(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[3]);
+ _npcSpawn.setRespawnDelay(1);
+ // later no need to delete spawn from db, we don't store it (false)
+ SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
+ _npcSpawn.init();
+ _lastNpcSpawn = _npcSpawn.getLastSpawn();
+ _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
+ _lastNpcSpawn.setTitle("CTF Event Participation");
+ _lastNpcSpawn.isAggressive();
+ _lastNpcSpawn.decayMe();
+ _lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
+ _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "CTFEventEngine[CTFEvent.startParticipation()]: exception: " + e.getMessage(), e);
+ return false;
+ }
+
+ setState(EventState.PARTICIPATING);
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventRegistrationStart());
+ return true;
+ }
+
+ private static int highestLevelPcInstanceOf(Map<Integer, L2PcInstance> players)
+ {
+ int maxLevel = Integer.MIN_VALUE, maxLevelId = -1;
+ for (L2PcInstance player : players.values())
+ {
+ if (player.getLevel() >= maxLevel)
+ {
+ maxLevel = player.getLevel();
+ maxLevelId = player.getObjectId();
+ }
+ }
+ return maxLevelId;
+ }
+
+ /**
+ * Starts the CTFEvent fight<br>
+ * 1. Set state EventState.STARTING<br>
+ * 2. Close doors specified in configs<br>
+ * 3. Abort if not enought participants(return false)<br>
+ * 4. Set state EventState.STARTED<br>
+ * 5. Teleport all participants to team spot<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startFight()
+ {
+ // Set state to STARTING
+ setState(EventState.STARTING);
+
+ // Randomize and balance team distribution
+ Map<Integer, L2PcInstance> allParticipants = new FastMap<>();
+ allParticipants.putAll(_teams[0].getParticipatedPlayers());
+ allParticipants.putAll(_teams[1].getParticipatedPlayers());
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+
+ L2PcInstance player;
+ Iterator<L2PcInstance> iter;
+ if (needParticipationFee())
+ {
+ iter = allParticipants.values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!hasParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ int balance[] =
+ {
+ 0,
+ 0
+ }, priority = 0, highestLevelPlayerId;
+ L2PcInstance highestLevelPlayer;
+ // TODO: allParticipants should be sorted by level instead of using highestLevelPcInstanceOf for every fetch
+ while (!allParticipants.isEmpty())
+ {
+ // Priority team gets one player
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Exiting if no more players
+ if (allParticipants.isEmpty())
+ {
+ break;
+ }
+ // The other team gets one player
+ // TODO: Code not dry
+ priority = 1 - priority;
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Recalculating priority
+ priority = balance[0] > balance[1] ? 1 : 0;
+ }
+
+ // Check for enought participants
+ if ((_teams[0].getParticipatedPlayerCount() < Config.CTF_EVENT_MIN_PLAYERS_IN_TEAMS) || (_teams[1].getParticipatedPlayerCount() < Config.CTF_EVENT_MIN_PLAYERS_IN_TEAMS))
+ {
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Unspawn the event NPC
+ unSpawnNpc();
+ AntiFeedManager.getInstance().clear(AntiFeedManager.CTF_ID);
+ return false;
+ }
+
+ if (needParticipationFee())
+ {
+ iter = _teams[0].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ iter = _teams[1].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ if (Config.CTF_EVENT_IN_INSTANCE)
+ {
+ try
+ {
+ _CTFEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.CTF_EVENT_INSTANCE_FILE);
+ InstanceManager.getInstance().getInstance(_CTFEventInstance).setAllowSummon(false);
+ InstanceManager.getInstance().getInstance(_CTFEventInstance).setPvPInstance(true);
+ InstanceManager.getInstance().getInstance(_CTFEventInstance).setEmptyDestroyTime((Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L);
+ }
+ catch (Exception e)
+ {
+ _CTFEventInstance = 0;
+ _log.log(Level.WARNING, "CTFEventEngine[CTFEvent.createDynamicInstance]: exception: " + e.getMessage(), e);
+ }
+ }
+
+ // Spawn the flags
+ try
+ {
+ L2NpcTemplate tmpl = NpcData.getInstance().getTemplate(Config.CTF_EVENT_TEAM_1_HEADQUARTERS);
+ _flag1Spawn = new L2Spawn(tmpl);
+ _flag1Spawn.setX(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[0]);
+ _flag1Spawn.setY(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[1]);
+ _flag1Spawn.setZ(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[2]);
+ _flag1Spawn.setHeading(Util.calculateHeadingFrom(new Location(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[2]), new Location(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[2])));
+ _flag1Spawn.setInstanceId(_CTFEventInstance);
+ _flag1Spawn.setRespawnDelay(1);
+ _flag1Spawn.setAmount(1);
+ SpawnTable.getInstance().addNewSpawn(_flag1Spawn, false);
+ _flag1Spawn.init();
+ _lastFlag1Spawn = _flag1Spawn.getLastSpawn();
+ _lastFlag1Spawn.setCurrentHp(_lastFlag1Spawn.getMaxHp());
+ _lastFlag1Spawn.setTitle(Config.CTF_EVENT_TEAM_1_NAME);
+ _lastFlag1Spawn.isAggressive();
+ _lastFlag1Spawn.decayMe();
+ _lastFlag1Spawn.spawnMe(_flag1Spawn.getLastSpawn().getX(), _flag1Spawn.getLastSpawn().getY(), _flag1Spawn.getLastSpawn().getZ());
+ _lastFlag1Spawn.setIsInvul(true);
+ L2NpcTemplate tmpl2 = NpcData.getInstance().getTemplate(Config.CTF_EVENT_TEAM_2_HEADQUARTERS);
+ _flag2Spawn = new L2Spawn(tmpl2);
+ _flag2Spawn.setX(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[0]);
+ _flag2Spawn.setY(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[1]);
+ _flag2Spawn.setZ(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[2]);
+ _flag2Spawn.setHeading(Util.calculateHeadingFrom(new Location(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[2]), new Location(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[2])));
+ _flag2Spawn.setInstanceId(_CTFEventInstance);
+ _flag2Spawn.setRespawnDelay(1);
+ _flag2Spawn.setAmount(1);
+ SpawnTable.getInstance().addNewSpawn(_flag2Spawn, false);
+ _flag2Spawn.init();
+ _lastFlag2Spawn = _flag2Spawn.getLastSpawn();
+ _lastFlag2Spawn.setCurrentHp(_lastFlag2Spawn.getMaxHp());
+ _lastFlag2Spawn.setTitle(Config.CTF_EVENT_TEAM_2_NAME);
+ _lastFlag2Spawn.isAggressive();
+ _lastFlag2Spawn.decayMe();
+ _lastFlag2Spawn.spawnMe(_flag2Spawn.getLastSpawn().getX(), _flag2Spawn.getLastSpawn().getY(), _flag2Spawn.getLastSpawn().getZ());
+ _lastFlag2Spawn.setIsInvul(true);
+ _lastFlag2Spawn.setTarget(_lastFlag2Spawn);
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "CTFEventEngine[CTFEvent.spanwnFlags]: exception: " + e.getMessage(), e);
+ }
+
+ // Opens all doors specified in configs for CTF
+ openDoors(Config.CTF_DOORS_IDS_TO_OPEN);
+ // Closes all doors specified in configs for CTF
+ closeDoors(Config.CTF_DOORS_IDS_TO_CLOSE);
+ // Set state STARTED
+ setState(EventState.STARTED);
+
+ // Iterate over all teams
+ for (CTFEventTeam team : _teams)
+ {
+ // Iterate over all participated player instances in this team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ // Disable player revival.
+ playerInstance.setCanRevive(false);
+
+ // Disabled skills by config.
+ if (!Config.CTF_EVENT_RESTRICTED_SKILLS.isEmpty())
+ {
+ for (SkillHolder skill : Config.CTF_EVENT_RESTRICTED_SKILLS)
+ {
+ if (playerInstance.getSkills().values().contains(skill.getSkill()))
+ {
+ playerInstance.disableSkill(skill.getSkill(), ((Config.CTF_EVENT_RUNNING_TIME * 60) + Config.CTF_EVENT_RESPAWN_TELEPORT_DELAY) * 1000);
+ }
+ }
+ }
+
+ // Teleporter implements Runnable and starts itself
+ new CTFEventTeleporter(playerInstance, team.getCoordinates(), false, false);
+ }
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventStart());
+ return true;
+ }
+
+ /**
+ * Calculates the CTFEvent reward<br>
+ * 1. If both teams are at a tie(points equals), send it as system message to all participants, if one of the teams have 0 participants left online abort rewarding<br>
+ * 2. Wait till teams are not at a tie anymore<br>
+ * 3. Set state EvcentState.REWARDING<br>
+ * 4. Reward team with more points<br>
+ * 5. Show win html to wining team participants<br>
+ * <br>
+ * @return String: winning team name<br>
+ */
+ public static String calculateRewards()
+ {
+ if (_teams[0].getPoints() == _teams[1].getPoints())
+ {
+ // Check if one of the teams have no more players left
+ if ((_teams[0].getParticipatedPlayerCount() == 0) || (_teams[1].getParticipatedPlayerCount() == 0))
+ {
+ // set state to rewarding
+ setState(EventState.REWARDING);
+ // return here, the fight can't be completed
+ broadcastScreenMessage("CTF Event: No team won due to inactivity!", 8);
+ return "CTF Event: Event has ended. No team won due to inactivity!";
+ }
+
+ // Both teams have equals points
+ broadcastScreenMessage("CTF Event: Both teams have tied!", 8);
+ sysMsgToAllParticipants("CTF Event: Event has ended, both teams have tied.");
+ if (Config.CTF_REWARD_TEAM_TIE)
+ {
+ rewardTeam(_teams[0]);
+ rewardTeam(_teams[1]);
+ return "CTF Event: Event has ended with both teams tying.";
+ }
+ return "CTF Event: Event has ended with both teams tying.";
+ }
+
+ // Set state REWARDING so nobody can point anymore
+ setState(EventState.REWARDING);
+
+ // Get team which has more points
+ CTFEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1];
+ rewardTeam(team);
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventFinish());
+
+ broadcastScreenMessage("CTF Event: Team " + team.getName() + " wins!", 8);
+ return "CTF Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills.";
+ }
+
+ private static void rewardTeam(CTFEventTeam team)
+ {
+ // Iterate over all participated player instances of the winning team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance == null)
+ {
+ continue;
+ }
+
+ // Fireworks for rewarded player
+ playerInstance.broadcastPacket(new MagicSkillUse(playerInstance, playerInstance, CommonSkill.FIREWORK.getSkill().getId(), 1, 1, 1));
+
+ SystemMessage systemMessage = null;
+
+ // Iterate over all CTF event rewards
+ for (int[] reward : Config.CTF_EVENT_REWARDS)
+ {
+ PcInventory inv = playerInstance.getInventory();
+
+ // Check for stackable item, non stackabe items need to be added one by one
+ if (ItemTable.getInstance().getTemplate(reward[0]).isStackable())
+ {
+ inv.addItem("CTF Event", reward[0], reward[1], playerInstance, playerInstance);
+
+ if (reward[1] > 1)
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+ systemMessage.addItemName(reward[0]);
+ systemMessage.addLong(reward[1]);
+ }
+ else
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ }
+
+ playerInstance.sendPacket(systemMessage);
+ }
+ else
+ {
+ for (int i = 0; i < reward[1]; ++i)
+ {
+ inv.addItem("CTF Event", reward[0], 1, playerInstance, playerInstance);
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ playerInstance.sendPacket(systemMessage);
+ }
+ }
+ }
+
+ StatusUpdate statusUpdate = new StatusUpdate(playerInstance);
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, playerInstance.getCurrentLoad());
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Reward.html"));
+ playerInstance.sendPacket(statusUpdate);
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+
+ /**
+ * Stops the CTFEvent fight<br>
+ * 1. Set state EventState.INACTIVATING<br>
+ * 2. Remove CTF npc from world<br>
+ * 3. Open doors specified in configs<br>
+ * 4. Teleport all participants back to participation npc location<br>
+ * 5. Teams cleaning<br>
+ * 6. Set state EventState.INACTIVE<br>
+ */
+ public static void stopFight()
+ {
+ // Set state INACTIVATING
+ setState(EventState.INACTIVATING);
+ // Unspawn event npc
+ unSpawnNpc();
+ // Opens all doors specified in configs for CTF
+ openDoors(Config.CTF_DOORS_IDS_TO_CLOSE);
+ // Closes all doors specified in Configs for CTF
+ closeDoors(Config.CTF_DOORS_IDS_TO_OPEN);
+
+ // Reset flag carriers
+ if (_team1Carrier != null)
+ {
+ removeFlagCarrier(_team1Carrier);
+ }
+
+ if (_team2Carrier != null)
+ {
+ removeFlagCarrier(_team2Carrier);
+ }
+
+ // Iterate over all teams
+ for (CTFEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance != null)
+ {
+ // Enable player revival.
+ playerInstance.setCanRevive(true);
+
+ // Untransform player.
+ if (playerInstance.isTransformed())
+ {
+ playerInstance.untransform();
+ }
+
+ // Teleport back.
+ new CTFEventTeleporter(playerInstance, Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+ }
+
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.CTF_ID);
+ }
+
+ /**
+ * Adds a player to a CTFEvent team<br>
+ * 1. Calculate the id of the team in which the player should be added<br>
+ * 2. Add the player to the calculated team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static synchronized boolean addParticipant(L2PcInstance playerInstance)
+ {
+ // Check for nullpoitner
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ byte teamId = 0;
+
+ // Check to which team the player should be added
+ if (_teams[0].getParticipatedPlayerCount() == _teams[1].getParticipatedPlayerCount())
+ {
+ teamId = (byte) (Rnd.get(2));
+ }
+ else
+ {
+ teamId = (byte) (_teams[0].getParticipatedPlayerCount() > _teams[1].getParticipatedPlayerCount() ? 1 : 0);
+ }
+ playerInstance.addEventListener(new CTFEventListener(playerInstance));
+ return _teams[teamId].addPlayer(playerInstance);
+ }
+
+ /**
+ * Removes a CTFEvent player from it's team<br>
+ * 1. Get team id of the player<br>
+ * 2. Remove player from it's team<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if success, otherwise false
+ */
+ public static boolean removeParticipant(int playerObjectId)
+ {
+ // Get the teamId of the player
+ byte teamId = getParticipantTeamId(playerObjectId);
+
+ // Check if the player is participant
+ if (teamId != -1)
+ {
+ // Remove the player from team
+ _teams[teamId].removePlayer(playerObjectId);
+
+ final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
+ if (player != null)
+ {
+ player.removeEventListener(CTFEventListener.class);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean needParticipationFee()
+ {
+ return (Config.CTF_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.CTF_EVENT_PARTICIPATION_FEE[1] != 0);
+ }
+
+ public static boolean hasParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.getInventory().getInventoryItemCount(Config.CTF_EVENT_PARTICIPATION_FEE[0], -1) >= Config.CTF_EVENT_PARTICIPATION_FEE[1];
+ }
+
+ public static boolean payParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.destroyItemByItemId("CTF Participation Fee", Config.CTF_EVENT_PARTICIPATION_FEE[0], Config.CTF_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
+ }
+
+ public static String getParticipationFee()
+ {
+ int itemId = Config.CTF_EVENT_PARTICIPATION_FEE[0];
+ int itemNum = Config.CTF_EVENT_PARTICIPATION_FEE[1];
+
+ if ((itemId == 0) || (itemNum == 0))
+ {
+ return "-";
+ }
+
+ return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
+ }
+
+ /**
+ * Send a SystemMessage to all participated players<br>
+ * 1. Send the message to all players of team number one<br>
+ * 2. Send the message to all players of team number two<br>
+ * <br>
+ * @param message as String<br>
+ */
+ public static void sysMsgToAllParticipants(String message)
+ {
+ for (L2PcInstance playerInstance : _teams[0].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+
+ for (L2PcInstance playerInstance : _teams[1].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+ }
+
+ private static L2DoorInstance getDoor(int doorId)
+ {
+ L2DoorInstance door = null;
+ if (_CTFEventInstance <= 0)
+ {
+ door = DoorData.getInstance().getDoor(doorId);
+ }
+ else
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(_CTFEventInstance);
+ if (inst != null)
+ {
+ door = inst.getDoor(doorId);
+ }
+ }
+ return door;
+ }
+
+ /**
+ * Close doors specified in configs
+ * @param doors
+ */
+ private static void closeDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.closeMe();
+ }
+ }
+ }
+
+ /**
+ * Open doors specified in configs
+ * @param doors
+ */
+ private static void openDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.openMe();
+ }
+ }
+ }
+
+ /**
+ * UnSpawns the CTFEvent npc
+ */
+ private static void unSpawnNpc()
+ {
+ // Delete the npc
+ _lastNpcSpawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
+
+ // Stop respawning of the npc
+ _npcSpawn.stopRespawn();
+ _npcSpawn = null;
+ _lastNpcSpawn = null;
+
+ // Remove flags
+ if (_lastFlag1Spawn != null)
+ {
+ _lastFlag1Spawn.deleteMe();
+ _lastFlag2Spawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastFlag1Spawn.getSpawn(), false);
+ SpawnTable.getInstance().deleteSpawn(_lastFlag2Spawn.getSpawn(), false);
+ _flag1Spawn.stopRespawn();
+ _flag2Spawn.stopRespawn();
+ _flag1Spawn = null;
+ _flag2Spawn = null;
+ _lastFlag1Spawn = null;
+ _lastFlag2Spawn = null;
+ }
+ }
+
+ /**
+ * Called when a player logs in<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogin(L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || (!isStarting() && !isStarted()))
+ {
+ return;
+ }
+
+ byte teamId = getParticipantTeamId(playerInstance.getObjectId());
+
+ if (teamId == -1)
+ {
+ return;
+ }
+
+ _teams[teamId].addPlayer(playerInstance);
+ new CTFEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
+ }
+
+ /**
+ * Called when a player logs out<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogout(L2PcInstance playerInstance)
+ {
+ if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
+ {
+ if (removeParticipant(playerInstance.getObjectId()))
+ {
+ playerInstance.setXYZInvisible((Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[0] + Rnd.get(101)) - 50, (Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[1] + Rnd.get(101)) - 50, Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ }
+ }
+ }
+
+ /**
+ * Called on every onAction in L2PcIstance<br>
+ * <br>
+ * @param playerInstance
+ * @param targetedPlayerObjectId
+ * @return boolean: true if player is allowed to target, otherwise false
+ */
+ public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
+ {
+ if ((playerInstance == null) || !isStarted())
+ {
+ return true;
+ }
+
+ if (playerInstance.isGM())
+ {
+ return true;
+ }
+
+ byte playerTeamId = getParticipantTeamId(playerInstance.getObjectId());
+ byte targetedPlayerTeamId = getParticipantTeamId(targetedPlayerObjectId);
+
+ if (((playerTeamId != -1) && (targetedPlayerTeamId == -1)) || ((playerTeamId == -1) && (targetedPlayerTeamId != -1)))
+ {
+ return false;
+ }
+
+ if ((playerTeamId != -1) && (targetedPlayerTeamId != -1) && (playerTeamId == targetedPlayerTeamId) && (playerInstance.getObjectId() != targetedPlayerObjectId) && !Config.CTF_EVENT_TARGET_TEAM_MEMBERS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every scroll use<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use scroll, otherwise false
+ */
+ public static boolean onScrollUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.CTF_EVENT_SCROLL_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every potion use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use potions, otherwise false
+ */
+ public static boolean onPotionUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.CTF_EVENT_POTIONS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every escape use(thanks to nbd)
+ * @param playerObjectId
+ * @return boolean: true if player is not in CTF event, otherwise false
+ */
+ public static boolean onEscapeUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every summon item use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to summon by item, otherwise false
+ */
+ public static boolean onItemSummon(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.CTF_EVENT_SUMMON_BY_ITEM_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is called when a player is killed<br>
+ * <br>
+ * @param killerCharacter as L2Character<br>
+ * @param killedPlayerInstance as L2PcInstance<br>
+ */
+ public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
+ {
+ if ((killedPlayerInstance == null) || !isStarted())
+ {
+ return;
+ }
+
+ byte killedTeamId = getParticipantTeamId(killedPlayerInstance.getObjectId());
+
+ if (killedTeamId == -1)
+ {
+ return;
+ }
+
+ new CTFEventTeleporter(killedPlayerInstance, _teams[killedTeamId].getCoordinates(), false, false);
+
+ if (killerCharacter == null)
+ {
+ return;
+ }
+
+ L2PcInstance killerPlayerInstance = null;
+
+ if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
+ {
+ killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
+
+ if (killerPlayerInstance == null)
+ {
+ return;
+ }
+ }
+ else if (killerCharacter instanceof L2PcInstance)
+ {
+ killerPlayerInstance = (L2PcInstance) killerCharacter;
+ }
+ else
+ {
+ return;
+ }
+
+ byte killerTeamId = getParticipantTeamId(killerPlayerInstance.getObjectId());
+
+ if ((killerTeamId != -1) && (killedTeamId != -1) && (killerTeamId != killedTeamId))
+ {
+ CTFEventTeam killerTeam = _teams[killerTeamId];
+
+ CreatureSay cs = new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!");
+
+ for (L2PcInstance playerInstance : _teams[killerTeamId].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendPacket(cs);
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventKill(killerPlayerInstance, killedPlayerInstance, killerTeam));
+ }
+
+ if (playerIsCarrier(killedPlayerInstance))
+ {
+ broadcastScreenMessage(killerCharacter.getName() + " has killed " + killedPlayerInstance.getName() + "!", 7);
+ }
+ }
+
+ /**
+ * Called on Appearing packet received (player finished teleporting)
+ * @param playerInstance
+ */
+ public static void onTeleported(L2PcInstance playerInstance)
+ {
+ if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
+ {
+ return;
+ }
+
+ if (playerInstance.isMageClass())
+ {
+ if ((Config.CTF_EVENT_MAGE_BUFFS != null) && !Config.CTF_EVENT_MAGE_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.CTF_EVENT_MAGE_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((Config.CTF_EVENT_FIGHTER_BUFFS != null) && !Config.CTF_EVENT_FIGHTER_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.CTF_EVENT_FIGHTER_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param source
+ * @param target
+ * @param skill
+ * @return true if player valid for skill
+ */
+ public static final boolean checkForCTFSkill(L2PcInstance source, L2PcInstance target, Skill skill)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ // CTF is started
+ final int sourcePlayerId = source.getObjectId();
+ final int targetPlayerId = target.getObjectId();
+ final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
+ final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
+
+ // both players not participating
+ if (!isSourceParticipant && !isTargetParticipant)
+ {
+ return true;
+ }
+ // one player not participating
+ if (!(isSourceParticipant && isTargetParticipant))
+ {
+ return false;
+ }
+ // players in the different teams ?
+ if (getParticipantTeamId(sourcePlayerId) != getParticipantTeamId(targetPlayerId))
+ {
+ if (!skill.isBad())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Sets the CTFEvent state<br>
+ * <br>
+ * @param state as EventState<br>
+ */
+ private static void setState(EventState state)
+ {
+ synchronized (_state)
+ {
+ _state = state;
+ }
+ }
+
+ /**
+ * Is CTFEvent inactive?<br>
+ * <br>
+ * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
+ */
+ public static boolean isInactive()
+ {
+ boolean isInactive;
+
+ synchronized (_state)
+ {
+ isInactive = _state == EventState.INACTIVE;
+ }
+
+ return isInactive;
+ }
+
+ /**
+ * Is CTFEvent in inactivating?<br>
+ * <br>
+ * @return boolean: true if event is in inactivating progress, otherwise false<br>
+ */
+ public static boolean isInactivating()
+ {
+ boolean isInactivating;
+
+ synchronized (_state)
+ {
+ isInactivating = _state == EventState.INACTIVATING;
+ }
+
+ return isInactivating;
+ }
+
+ /**
+ * Is CTFEvent in participation?<br>
+ * <br>
+ * @return boolean: true if event is in participation progress, otherwise false<br>
+ */
+ public static boolean isParticipating()
+ {
+ boolean isParticipating;
+
+ synchronized (_state)
+ {
+ isParticipating = _state == EventState.PARTICIPATING;
+ }
+
+ return isParticipating;
+ }
+
+ /**
+ * Is CTFEvent starting?<br>
+ * <br>
+ * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
+ */
+ public static boolean isStarting()
+ {
+ boolean isStarting;
+
+ synchronized (_state)
+ {
+ isStarting = _state == EventState.STARTING;
+ }
+
+ return isStarting;
+ }
+
+ /**
+ * Is CTFEvent started?<br>
+ * <br>
+ * @return boolean: true if event is started, otherwise false<br>
+ */
+ public static boolean isStarted()
+ {
+ boolean isStarted;
+
+ synchronized (_state)
+ {
+ isStarted = _state == EventState.STARTED;
+ }
+
+ return isStarted;
+ }
+
+ /**
+ * Is CTFEvent rewarding?<br>
+ * <br>
+ * @return boolean: true if event is currently rewarding, otherwise false<br>
+ */
+ public static boolean isRewarding()
+ {
+ boolean isRewarding;
+
+ synchronized (_state)
+ {
+ isRewarding = _state == EventState.REWARDING;
+ }
+
+ return isRewarding;
+ }
+
+ /**
+ * Returns the team id of a player, if player is not participant it returns -1
+ * @param playerObjectId
+ * @return byte: team name of the given playerName, if not in event -1
+ */
+ public static byte getParticipantTeamId(int playerObjectId)
+ {
+ return (byte) (_teams[0].containsPlayer(playerObjectId) ? 0 : (_teams[1].containsPlayer(playerObjectId) ? 1 : -1));
+ }
+
+ /**
+ * Returns the team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return CTFEventTeam: team of the given playerObjectId, if not in event null
+ */
+ public static CTFEventTeam getParticipantTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[0] : (_teams[1].containsPlayer(playerObjectId) ? _teams[1] : null));
+ }
+
+ /**
+ * Returns the enemy team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return CTFEventTeam: enemy team of the given playerObjectId, if not in event null
+ */
+ public static CTFEventTeam getParticipantEnemyTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[1] : (_teams[1].containsPlayer(playerObjectId) ? _teams[0] : null));
+ }
+
+ /**
+ * Returns the team coordinates in which the player is in, if player is not in a team return null
+ * @param playerObjectId
+ * @return int[]: coordinates of teams, 2 elements, index 0 for team 1 and index 1 for team 2
+ */
+ public static int[] getParticipantTeamCoordinates(int playerObjectId)
+ {
+ return _teams[0].containsPlayer(playerObjectId) ? _teams[0].getCoordinates() : (_teams[1].containsPlayer(playerObjectId) ? _teams[1].getCoordinates() : null);
+ }
+
+ /**
+ * Is given player participant of the event?
+ * @param playerObjectId
+ * @return boolean: true if player is participant, ohterwise false
+ */
+ public static boolean isPlayerParticipant(int playerObjectId)
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return false;
+ }
+
+ return _teams[0].containsPlayer(playerObjectId) || _teams[1].containsPlayer(playerObjectId);
+ }
+
+ /**
+ * Returns participated player count<br>
+ * <br>
+ * @return int: amount of players registered in the event<br>
+ */
+ public static int getParticipatedPlayersCount()
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return 0;
+ }
+
+ return _teams[0].getParticipatedPlayerCount() + _teams[1].getParticipatedPlayerCount();
+ }
+
+ /**
+ * Returns teams names<br>
+ * <br>
+ * @return String[]: names of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static String[] getTeamNames()
+ {
+ return new String[]
+ {
+ _teams[0].getName(),
+ _teams[1].getName()
+ };
+ }
+
+ /**
+ * Returns player count of both teams<br>
+ * <br>
+ * @return int[]: player count of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPlayerCounts()
+ {
+ return new int[]
+ {
+ _teams[0].getParticipatedPlayerCount(),
+ _teams[1].getParticipatedPlayerCount()
+ };
+ }
+
+ /**
+ * Returns points count of both teams
+ * @return int[]: points of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPoints()
+ {
+ return new int[]
+ {
+ _teams[0].getPoints(),
+ _teams[1].getPoints()
+ };
+ }
+
+ /**
+ * Used when carrier scores, dies or game ends
+ * @param player L2PcInstance
+ */
+ public static void removeFlagCarrier(L2PcInstance player)
+ {
+ // un-equip - destroy flag
+ player.getInventory().unEquipItemInSlot(Inventory.PAPERDOLL_RHAND);
+ player.destroyItemByItemId("ctf", getEnemyTeamFlagId(player), 1, player, false);
+
+ // unblock inventory
+ player.getInventory().unblock();
+
+ // re-equip player items
+ final L2ItemInstance carrierRHand = _teams[0].containsPlayer(player.getObjectId()) ? _team1CarrierRHand : _team2CarrierRHand;
+ final L2ItemInstance carrierLHand = _teams[0].containsPlayer(player.getObjectId()) ? _team1CarrierLHand : _team2CarrierLHand;
+ if ((carrierRHand != null) && (player.getInventory().getItemByItemId(carrierRHand.getId()) != null))
+ {
+ player.getInventory().equipItem(carrierRHand);
+ }
+ if ((carrierLHand != null) && (player.getInventory().getItemByItemId(carrierLHand.getId()) != null))
+ {
+ player.getInventory().equipItem(carrierLHand);
+ }
+ setCarrierUnequippedWeapons(player, null, null);
+
+ // flag carrier removal
+ if (_teams[0].containsPlayer(player.getObjectId()))
+ {
+ _team1Carrier = null;
+ }
+ else
+ {
+ _team2Carrier = null;
+ }
+
+ // show re-equipped weapons
+ player.broadcastUserInfo();
+ }
+
+ /**
+ * Assign the Ctf team flag carrier
+ * @param player L2PcInstance
+ */
+ public static void setTeamCarrier(L2PcInstance player)
+ {
+ if (_teams[0].containsPlayer(player.getObjectId()))
+ {
+ _team1Carrier = player;
+ }
+ else
+ {
+ _team2Carrier = player;
+ }
+ }
+
+ /**
+ * @param player L2PcInstance
+ * @return the team carrier L2PcInstance
+ */
+ public static L2PcInstance getTeamCarrier(L2PcInstance player)
+ {
+ // check if team carrier has disconnected
+ if (((_teams[0].containsPlayer(player.getObjectId()) == true) && (_team1Carrier != null) && (!_team1Carrier.isOnline() || (_team1Carrier.getInstanceId() != _CTFEventInstance))) || ((_teams[1].containsPlayer(player.getObjectId()) == true) && (_team2Carrier != null) && (!_team2Carrier.isOnline() || (_team2Carrier.getInstanceId() != _CTFEventInstance))))
+ {
+ player.destroyItemByItemId("ctf", getEnemyTeamFlagId(player), 1, player, false);
+ return null;
+ }
+
+ // return team carrier
+ return (_teams[0].containsPlayer(player.getObjectId()) ? _team1Carrier : _team2Carrier);
+ }
+
+ /**
+ * @param player L2PcInstance
+ * @return the enemy team carrier L2PcInstance
+ */
+ public static L2PcInstance getEnemyCarrier(L2PcInstance player)
+ {
+ // check if enemy carrier has disconnected
+ if (((_teams[0].containsPlayer(player.getObjectId()) == true) && (_team2Carrier != null) && (!_team2Carrier.isOnline() || (_team2Carrier.getInstanceId() != _CTFEventInstance))) || ((_teams[1].containsPlayer(player.getObjectId()) == true) && (_team1Carrier != null) && (!_team1Carrier.isOnline() || (_team1Carrier.getInstanceId() != _CTFEventInstance))))
+ {
+ player.destroyItemByItemId("ctf", getEnemyTeamFlagId(player), 1, player, false);
+ return null;
+ }
+
+ // return enemy carrier
+ return (_teams[0].containsPlayer(player.getObjectId()) ? _team2Carrier : _team1Carrier);
+ }
+
+ /**
+ * @param player L2PcInstance
+ * @return true if player is the carrier
+ */
+ public static boolean playerIsCarrier(L2PcInstance player)
+ {
+ return ((player == _team1Carrier) || (player == _team2Carrier)) ? true : false;
+ }
+
+ /**
+ * @param player L2ItemInstance
+ * @return int The enemy flag id
+ */
+ public static int getEnemyTeamFlagId(L2PcInstance player)
+ {
+ return (_teams[0].containsPlayer(player.getObjectId()) ? Config.CTF_EVENT_TEAM_2_FLAG : Config.CTF_EVENT_TEAM_1_FLAG);
+ }
+
+ /**
+ * Stores the carrier equipped weapons
+ * @param player L2PcInstance
+ * @param itemRight L2ItemInstance
+ * @param itemLeft L2ItemInstance
+ */
+ public static void setCarrierUnequippedWeapons(L2PcInstance player, L2ItemInstance itemRight, L2ItemInstance itemLeft)
+ {
+ if (_teams[0].containsPlayer(player.getObjectId()))
+ {
+ _team1CarrierRHand = itemRight;
+ _team1CarrierLHand = itemLeft;
+ }
+ else
+ {
+ _team2CarrierRHand = itemRight;
+ _team2CarrierLHand = itemLeft;
+ }
+ }
+
+ /**
+ * Broadcast a message to all participant screens
+ * @param message String
+ * @param duration int (in seconds)
+ */
+ public static void broadcastScreenMessage(String message, int duration)
+ {
+ for (CTFEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if ((playerInstance != null) && (playerInstance.getInstanceId() == _CTFEventInstance))
+ {
+ playerInstance.sendPacket(new ExShowScreenMessage(message, duration * 1000));
+ }
+ }
+ }
+ }
+
+ /**
+ * Broadcast score to all participants
+ */
+ public static void broadcastScoreMessage()
+ {
+ final String score = Config.CTF_EVENT_TEAM_1_NAME + ": " + _teams[0].getPoints() + " - " + Config.CTF_EVENT_TEAM_2_NAME + ": " + _teams[1].getPoints();
+
+ for (CTFEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if ((playerInstance != null) && (playerInstance.getInstanceId() == _CTFEventInstance))
+ {
+ playerInstance.sendPacket(new ExShowScreenMessage(1, -1, 8, 0, 1, 0, 0, false, 15000, true, score, NpcStringId.NONE, null));
+ }
+ }
+ }
+ }
+
+ public static int getCTFEventInstance()
+ {
+ return _CTFEventInstance;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventListener.java (working copy)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class CTFEventListener implements IEventListener
+{
+ private final L2PcInstance _player;
+
+ protected CTFEventListener(L2PcInstance player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return CTFEvent.isStarted() && CTFEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ @Override
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventPlayer.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventPlayer.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventPlayer.java (working copy)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class CTFEventPlayer
+{
+ private final L2PcInstance _player;
+
+ protected CTFEventPlayer(L2PcInstance player)
+ {
+ _player = player;
+
+ }
+
+ public boolean isOnEvent()
+ {
+ return CTFEvent.isStarted() && CTFEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author HorridoJoho
+ */
+public class CTFEventTeam
+{
+ /** The name of the team<br> */
+ private final String _name;
+ /** The team spot coordinated<br> */
+ private int[] _coordinates = new int[3];
+ /** The points of the team<br> */
+ private short _points;
+ /** Name and instance of all participated players in FastMap<br> */
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ /**
+ * C'tor initialize the team<br>
+ * <br>
+ * @param name as String<br>
+ * @param coordinates as int[]<br>
+ */
+ public CTFEventTeam(String name, int[] coordinates)
+ {
+ _name = name;
+ _coordinates = coordinates;
+ _points = 0;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes a player from the team
+ * @param playerObjectId
+ */
+ public void removePlayer(int playerObjectId)
+ {
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.remove(playerObjectId);
+ }
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * Returns the name of the team<br>
+ * <br>
+ * @return String: name of the team<br>
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the coordinates of the team spot<br>
+ * <br>
+ * @return int[]: team coordinates<br>
+ */
+ public int[] getCoordinates()
+ {
+ return _coordinates;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeleporter.java (working copy)
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.Team;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Duel;
+import com.l2jserver.util.Rnd;
+
+public class CTFEventTeleporter implements Runnable
+{
+ /** The instance of the player to teleport */
+ private L2PcInstance _playerInstance = null;
+ /** Coordinates of the spot to teleport to */
+ private int[] _coordinates = new int[3];
+ /** Admin removed this player from event */
+ private boolean _adminRemove = false;
+
+ /**
+ * Initialize the teleporter and start the delayed task.
+ * @param playerInstance
+ * @param coordinates
+ * @param fastSchedule
+ * @param adminRemove
+ */
+ public CTFEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
+ {
+ _playerInstance = playerInstance;
+ _coordinates = coordinates;
+ _adminRemove = adminRemove;
+
+ long delay = (CTFEvent.isStarted() ? Config.CTF_EVENT_RESPAWN_TELEPORT_DELAY : Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
+
+ ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
+ }
+
+ /**
+ * The task method to teleport the player<br>
+ * 1. Unsummon pet if there is one<br>
+ * 2. Remove all effects<br>
+ * 3. Revive and full heal the player<br>
+ * 4. Teleport the player<br>
+ * 5. Broadcast status and user info
+ */
+ @Override
+ public void run()
+ {
+ if (_playerInstance == null)
+ {
+ return;
+ }
+
+ L2Summon summon = _playerInstance.getSummon();
+
+ if (summon != null)
+ {
+ summon.unSummon(_playerInstance);
+ }
+
+ if ((Config.CTF_EVENT_EFFECTS_REMOVAL == 0) || ((Config.CTF_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
+ {
+ _playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
+ }
+
+ if (_playerInstance.isInDuel())
+ {
+ _playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
+ }
+
+ int CTFInstance = CTFEvent.getCTFEventInstance();
+ if (CTFInstance != 0)
+ {
+ if (CTFEvent.isStarted() && !_adminRemove)
+ {
+ _playerInstance.setInstanceId(CTFInstance);
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+
+ _playerInstance.doRevive();
+
+ _playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
+
+ // Reset flag carrier
+ if (CTFEvent.playerIsCarrier(_playerInstance))
+ {
+ CTFEvent.removeFlagCarrier(_playerInstance);
+ CTFEvent.broadcastScreenMessage("The " + CTFEvent.getParticipantEnemyTeam(_playerInstance.getObjectId()).getName() + " flag has been returned!", 5);
+ }
+
+ if (CTFEvent.isStarted() && !_adminRemove)
+ {
+ int teamId = CTFEvent.getParticipantTeamId(_playerInstance.getObjectId()) + 1;
+ switch (teamId)
+ {
+ case 0:
+ _playerInstance.setTeam(Team.NONE);
+ break;
+ case 1:
+ _playerInstance.setTeam(Team.BLUE);
+ break;
+ case 2:
+ _playerInstance.setTeam(Team.RED);
+ break;
+ }
+ }
+ else
+ {
+ _playerInstance.setTeam(Team.NONE);
+ }
+
+ _playerInstance.setCurrentCp(_playerInstance.getMaxCp());
+ _playerInstance.setCurrentHp(_playerInstance.getMaxHp());
+ _playerInstance.setCurrentMp(_playerInstance.getMaxMp());
+
+ _playerInstance.broadcastStatusUpdate();
+ _playerInstance.broadcastUserInfo();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFManager.java (working copy)
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author HorridoJoho
+ */
+public class CTFManager
+{
+ protected static final Logger _log = Logger.getLogger(CTFManager.class.getName());
+
+ /** Task for event cycles<br> */
+ private CTFStartTask _task;
+
+ /**
+ * New instance only by getInstance()<br>
+ */
+ protected CTFManager()
+ {
+ if (Config.CTF_EVENT_ENABLED)
+ {
+ // Cannot start if both teams have same name
+ if (Config.CTF_EVENT_TEAM_1_NAME != Config.CTF_EVENT_TEAM_2_NAME)
+ {
+ CTFEvent.init();
+
+ scheduleEventStart();
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Started.");
+ }
+ else
+ {
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Engine uninitiated. Cannot start if both teams have same name!");
+ }
+ }
+ else
+ {
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Engine is disabled.");
+ }
+ }
+
+ /**
+ * Initialize new/Returns the one and only instance<br>
+ * <br>
+ * @return CTFManager<br>
+ */
+ public static CTFManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ /**
+ * Starts CTFStartTask
+ */
+ public void scheduleEventStart()
+ {
+ try
+ {
+ Calendar currentTime = Calendar.getInstance();
+ Calendar nextStartTime = null;
+ Calendar testStartTime = null;
+ for (String timeOfDay : Config.CTF_EVENT_INTERVAL)
+ {
+ // Creating a Calendar object from the specified interval value
+ testStartTime = Calendar.getInstance();
+ testStartTime.setLenient(true);
+ String[] splitTimeOfDay = timeOfDay.split(":");
+ testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+ testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+ // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
+ if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+ {
+ testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ // Check for the test date to be the minimum (smallest in the specified list)
+ if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
+ {
+ nextStartTime = testStartTime;
+ }
+ }
+ if (nextStartTime != null)
+ {
+ _task = new CTFStartTask(nextStartTime.getTimeInMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+ catch (Exception e)
+ {
+ _log.warning("CTFEventEngine[CTFManager.scheduleEventStart()]: Error figuring out a start time. Check CTFEventInterval in config file.");
+ }
+ }
+
+ /**
+ * Method to start participation
+ */
+ public void startReg()
+ {
+ if (!CTFEvent.startParticipation())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: Event was cancelled.");
+ _log.warning("CTFEventEngine[CTFManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: Registration opened for " + Config.CTF_EVENT_PARTICIPATION_TIME + " minute(s).");
+
+ // schedule registration end
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.CTF_EVENT_PARTICIPATION_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to start the fight
+ */
+ public void startEvent()
+ {
+ if (!CTFEvent.startFight())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: Event cancelled due to lack of Participation.");
+ _log.info("CTFEventEngine[CTFManager.run()]: Lack of registration, abort event.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: Teleporting participants to an arena in " + Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.CTF_EVENT_RUNNING_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to end the event and reward
+ */
+ public void endEvent()
+ {
+ Broadcast.toAllOnlinePlayers(CTFEvent.calculateRewards());
+ CTFEvent.sysMsgToAllParticipants("CTF Event: Teleporting back to the registration npc in " + Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ CTFEvent.stopFight();
+
+ scheduleEventStart();
+ }
+
+ public void skipDelay()
+ {
+ if (_task.nextRun.cancel(false))
+ {
+ _task.setStartTime(System.currentTimeMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Class for CTF cycles
+ */
+ class CTFStartTask implements Runnable
+ {
+ private long _startTime;
+ public ScheduledFuture<?> nextRun;
+
+ public CTFStartTask(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ public void setStartTime(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ @Override
+ public void run()
+ {
+ int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+
+ if (delay > 0)
+ {
+ announce(delay);
+ }
+
+ int nextMsg = 0;
+ if (delay > 3600)
+ {
+ nextMsg = delay - 3600;
+ }
+ else if (delay > 1800)
+ {
+ nextMsg = delay - 1800;
+ }
+ else if (delay > 900)
+ {
+ nextMsg = delay - 900;
+ }
+ else if (delay > 600)
+ {
+ nextMsg = delay - 600;
+ }
+ else if (delay > 300)
+ {
+ nextMsg = delay - 300;
+ }
+ else if (delay > 60)
+ {
+ nextMsg = delay - 60;
+ }
+ else if (delay > 5)
+ {
+ nextMsg = delay - 5;
+ }
+ else if (delay > 0)
+ {
+ nextMsg = delay;
+ }
+ else
+ {
+ // start
+ if (CTFEvent.isInactive())
+ {
+ startReg();
+ }
+ else if (CTFEvent.isParticipating())
+ {
+ startEvent();
+ }
+ else
+ {
+ endEvent();
+ }
+ }
+
+ if (delay > 0)
+ {
+ nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+ }
+ }
+
+ private void announce(long time)
+ {
+ if ((time >= 3600) && ((time % 3600) == 0))
+ {
+ if (CTFEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
+ }
+ else if (CTFEvent.isStarted())
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
+ }
+ }
+ else if (time >= 60)
+ {
+ if (CTFEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: " + (time / 60) + " minute(s) until registration is closed!");
+ }
+ else if (CTFEvent.isStarted())
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: " + (time / 60) + " minute(s) until the event is finished!");
+ }
+ }
+ else
+ {
+ if (CTFEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: " + time + " second(s) until registration is closed!");
+ }
+ else if (CTFEvent.isStarted())
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: " + time + " second(s) until the event is finished!");
+ }
+ }
+ }
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final CTFManager _instance = new CTFManager();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEvent.java (working copy)
@@ -0,0 +1,1091 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.data.xml.impl.DoorData;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.SkillData;
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
+import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventStart;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.skills.CommonSkill;
+import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author HorridoJoho
+ */
+public class DMEvent
+{
+ enum EventState
+ {
+ INACTIVE,
+ INACTIVATING,
+ PARTICIPATING,
+ STARTING,
+ STARTED,
+ REWARDING
+ }
+
+ protected static final Logger _log = Logger.getLogger(DMEvent.class.getName());
+ /** html path **/
+ private static final String htmlPath = "data/scripts/custom/events/DM/DMManager/";
+ /** The state of the DMEvent<br> */
+ private static EventState _state = EventState.INACTIVE;
+ /** The spawn of the participation npc<br> */
+ private static L2Spawn _npcSpawn = null;
+ /** the npc instance of the participation npc<br> */
+ private static L2Npc _lastNpcSpawn = null;
+ /** Instance id<br> */
+ private static int _DMEventInstance = 0;
+ /** Players of the DMEvent<br> */
+ private static Map<Integer, DMEventPlayer> _participants = new FastMap<>();
+
+ /**
+ * No instance of this class!<br>
+ */
+ private DMEvent()
+ {
+ }
+
+ /**
+ * Teams initializing<br>
+ */
+ public static void init()
+ {
+ AntiFeedManager.getInstance().registerEvent(AntiFeedManager.DM_ID);
+ }
+
+ /**
+ * Starts the participation of the DMEvent<br>
+ * 1. Get L2NpcTemplate by Config.DM_EVENT_PARTICIPATION_NPC_ID<br>
+ * 2. Try to spawn a new npc of it<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startParticipation()
+ {
+ try
+ {
+ _npcSpawn = new L2Spawn(Config.DM_EVENT_PARTICIPATION_NPC_ID);
+
+ _npcSpawn.setX(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[0]);
+ _npcSpawn.setY(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[1]);
+ _npcSpawn.setZ(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ _npcSpawn.setAmount(1);
+ _npcSpawn.setHeading(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[3]);
+ _npcSpawn.setRespawnDelay(1);
+ // later no need to delete spawn from db, we don't store it (false)
+ SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
+ _npcSpawn.init();
+ _lastNpcSpawn = _npcSpawn.getLastSpawn();
+ _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
+ _lastNpcSpawn.setTitle("DM Event Participation");
+ _lastNpcSpawn.isAggressive();
+ _lastNpcSpawn.decayMe();
+ _lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
+ _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "DMEventEngine[DMEvent.startParticipation()]: exception: " + e.getMessage(), e);
+ return false;
+ }
+
+ setState(EventState.PARTICIPATING);
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventRegistrationStart());
+ return true;
+ }
+
+ /**
+ * Starts the DMEvent fight<br>
+ * 1. Set state EventState.STARTING<br>
+ * 2. Close doors specified in configs<br>
+ * 3. Abort if not enought participants(return false)<br>
+ * 4. Set state EventState.STARTED<br>
+ * 5. Teleport all participants to team spot<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startFight()
+ {
+ // Set state to STARTING
+ setState(EventState.STARTING);
+
+ // Check for enought participants
+ if (_participants.size() < Config.DM_EVENT_MIN_PLAYERS)
+ {
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ // Cleanup of participants
+ _participants.clear();
+ // Unspawn the event NPC
+ unSpawnNpc();
+ AntiFeedManager.getInstance().clear(AntiFeedManager.DM_ID);
+ return false;
+ }
+
+ if (Config.DM_EVENT_IN_INSTANCE)
+ {
+ try
+ {
+ _DMEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.DM_EVENT_INSTANCE_FILE);
+ InstanceManager.getInstance().getInstance(_DMEventInstance).setAllowSummon(false);
+ InstanceManager.getInstance().getInstance(_DMEventInstance).setPvPInstance(true);
+ InstanceManager.getInstance().getInstance(_DMEventInstance).setEmptyDestroyTime((Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L);
+ }
+ catch (Exception e)
+ {
+ _DMEventInstance = 0;
+ _log.log(Level.WARNING, "DMEventEngine[DMEvent.createDynamicInstance]: exception: " + e.getMessage(), e);
+ }
+ }
+
+ // Opens all doors specified in configs for DM
+ openDoors(Config.DM_DOORS_IDS_TO_OPEN);
+ // Closes all doors specified in configs for DM
+ closeDoors(Config.DM_DOORS_IDS_TO_CLOSE);
+ // Set state STARTED
+ setState(EventState.STARTED);
+
+ // Iterate over all teams
+ for (DMEventPlayer player : _participants.values())
+ {
+ if (player != null)
+ {
+ // Disable player revival.
+ player.setCanRevive(false);
+ // Teleporter implements Runnable and starts itself
+ new DMEventTeleporter(player.getPlayer(), Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventStart());
+ return true;
+ }
+
+ /**
+ * Calculates the DMEvent reward<br>
+ * 1. If both teams are at a tie(points equals), send it as system message to all participants, if one of the teams have 0 participants left online abort rewarding<br>
+ * 2. Wait till teams are not at a tie anymore<br>
+ * 3. Set state EvcentState.REWARDING<br>
+ * 4. Reward team with more points<br>
+ * 5. Show win html to wining team participants<br>
+ * <br>
+ * @return String: winning team name<br>
+ */
+ public static String calculateRewards()
+ {
+ TreeSet<DMEventPlayer> players = orderPosition(_participants.values());
+ for (int j = 0; j < Config.DM_EVENT_REWARD_FIRST_PLAYERS; j++)
+ {
+ if (players.isEmpty())
+ {
+ break;
+ }
+
+ DMEventPlayer player = players.first();
+
+ if (player.getPoints() == 0)
+ {
+ break;
+ }
+
+ rewardPlayer(player, j + 1);
+ players.remove(player);
+ int playerPointPrev = player.getPoints();
+
+ if (!Config.DM_REWARD_TEAM_TIE)
+ {
+ continue;
+ }
+
+ while (!players.isEmpty())
+ {
+ player = players.first();
+ if (player.getPoints() != playerPointPrev)
+ {
+ break;
+ }
+
+ rewardPlayer(player, j + 1);
+ players.remove(player);
+ }
+ }
+
+ // Set state REWARDING so nobody can point anymore
+ setState(EventState.REWARDING);
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventFinish());
+
+ return "DM Event ended, thanks to everyone who participated!";
+ }
+
+ /**
+ * @param listPlayer
+ * @return
+ */
+ private static TreeSet<DMEventPlayer> orderPosition(Collection<DMEventPlayer> listPlayer)
+ {
+ TreeSet<DMEventPlayer> players = new TreeSet<>((p1, p2) ->
+ {
+ Integer c1 = Integer.valueOf(p2.getPoints() - p1.getPoints());
+ Integer c2 = Integer.valueOf(p1.getDeath() - p2.getDeath());
+ Integer c3 = p1.getHexCode().compareTo(p2.getHexCode());
+
+ if (c1 == 0)
+ {
+ if (c2 == 0)
+ {
+ return c3;
+ }
+
+ return c2;
+ }
+
+ return c1;
+ });
+
+ players.addAll(listPlayer);
+ return players;
+ }
+
+ private static void rewardPlayer(DMEventPlayer p, int pos)
+ {
+ L2PcInstance activeChar = p.getPlayer();
+
+ // Check for nullpointer
+ if (activeChar == null)
+ {
+ return;
+ }
+
+ // Add Fireworks for rewarded player
+ activeChar.broadcastPacket(new MagicSkillUse(activeChar, activeChar, CommonSkill.FIREWORK.getSkill().getId(), 1, 1, 1));
+
+ SystemMessage systemMessage = null;
+
+ // Iterate over all DM event rewards
+ List<int[]> rewards = Config.DM_EVENT_REWARDS.get(pos);
+ for (int[] reward : rewards)
+ {
+ PcInventory inv = activeChar.getInventory();
+
+ // Check for stackable item, non stackabe items need to be added one by one
+ if (ItemTable.getInstance().getTemplate(reward[0]).isStackable())
+ {
+ inv.addItem("DM Event", reward[0], reward[1], activeChar, activeChar);
+
+ if (reward[1] > 1)
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+ systemMessage.addItemName(reward[0]);
+ systemMessage.addLong(reward[1]);
+ }
+ else
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ }
+
+ activeChar.sendPacket(systemMessage);
+ }
+ else
+ {
+ for (int i = 0; i < reward[1]; ++i)
+ {
+ inv.addItem("DM Event", reward[0], 1, activeChar, activeChar);
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ activeChar.sendPacket(systemMessage);
+ }
+ }
+ }
+
+ StatusUpdate statusUpdate = new StatusUpdate(activeChar);
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, activeChar.getCurrentLoad());
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), htmlPath + "Reward.html"));
+ activeChar.sendPacket(statusUpdate);
+ activeChar.sendPacket(npcHtmlMessage);
+ }
+
+ /**
+ * Stops the DMEvent fight<br>
+ * 1. Set state EventState.INACTIVATING<br>
+ * 2. Remove DM npc from world<br>
+ * 3. Open doors specified in configs<br>
+ * 4. Teleport all participants back to participation npc location<br>
+ * 5. Teams cleaning<br>
+ * 6. Set state EventState.INACTIVE<br>
+ */
+ public static void stopFight()
+ {
+ // Set state INACTIVATING
+ setState(EventState.INACTIVATING);
+ // Unspawn event npc
+ unSpawnNpc();
+ // Opens all doors specified in configs for DM
+ openDoors(Config.DM_DOORS_IDS_TO_CLOSE);
+ // Closes all doors specified in Configs for DM
+ closeDoors(Config.DM_DOORS_IDS_TO_OPEN);
+
+ String[] topPositions;
+ String htmltext = "";
+ if (Config.DM_EVENT_SHOW_TOP_RANK)
+ {
+ topPositions = getFirstPosition(Config.DM_EVENT_LIST_TOP_RANK);
+ Boolean c = true;
+ String c1 = "D9CC46";
+ String c2 = "FFFFFF";
+ if (topPositions != null)
+ {
+ for (int i = 0; i < topPositions.length; i++)
+ {
+ String color = (c ? c1 : c2);
+ String[] row = topPositions[i].split("\\,");
+ htmltext += "<tr>";
+ htmltext += "<td width=\"35\" align=\"center\"><font color=\"" + color + "\">" + String.valueOf(i + 1) + "</font></td>";
+ htmltext += "<td width=\"100\" align=\"left\"><font color=\"" + color + "\">" + row[0] + "</font></td>";
+ htmltext += "<td width=\"125\" align=\"right\"><font color=\"" + color + "\">" + row[1] + "</font></td>";
+ htmltext += "</tr>";
+ c = !c;
+ }
+ }
+ }
+
+ // Iterate over all teams
+ for (DMEventPlayer player : _participants.values())
+ {
+ // Check for nullpointer
+ if (player != null)
+ {
+ // Top Rank
+ if (Config.DM_EVENT_SHOW_TOP_RANK)
+ {
+ NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage(0);
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(player.getPlayer().getHtmlPrefix(), htmlPath + "TopRank.htm"));
+ npcHtmlMessage.replace("%toprank%", htmltext);
+ player.getPlayer().sendPacket(npcHtmlMessage);
+ }
+
+ player.setCanRevive(true);
+ new DMEventTeleporter(player.getPlayer(), Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+
+ // Cleanup list
+ _participants = new FastMap<>();
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.DM_ID);
+ }
+
+ public static String[] getFirstPosition(int countPos)
+ {
+ TreeSet<DMEventPlayer> players = orderPosition(_participants.values());
+ String text = "";
+ for (int j = 0; j < countPos; j++)
+ {
+ if (players.isEmpty())
+ {
+ break;
+ }
+
+ DMEventPlayer player = players.first();
+ if (player.getPoints() == 0)
+ {
+ break;
+ }
+
+ text += player.getPlayer().getName() + "," + String.valueOf(player.getPoints()) + ";";
+ players.remove(player);
+
+ int playerPointPrev = player.getPoints();
+
+ if (!Config.DM_REWARD_TEAM_TIE)
+ {
+ continue;
+ }
+
+ while (!players.isEmpty())
+ {
+ player = players.first();
+ if (player.getPoints() != playerPointPrev)
+ {
+ break;
+ }
+
+ text += player.getPlayer().getName() + "," + String.valueOf(player.getPoints()) + ";";
+ players.remove(player);
+ }
+ }
+
+ if (text != "")
+ {
+ return text.split("\\;");
+ }
+
+ return null;
+ }
+
+ /**
+ * Adds a player to a DMEvent team<br>
+ * 1. Calculate the id of the team in which the player should be added<br>
+ * 2. Add the player to the calculated team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static synchronized boolean addParticipant(L2PcInstance playerInstance)
+ {
+ // Check for nullpoitner
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ if (isPlayerParticipant(playerInstance))
+ {
+ return false;
+ }
+
+ String hexCode = hexToString(generateHex(16));
+ _participants.put(playerInstance.getObjectId(), new DMEventPlayer(playerInstance, null, hexCode));
+ playerInstance.addEventListener(new DMEventListener(playerInstance));
+ return true;
+ }
+
+ /**
+ * Removes a DMEvent player from it's team<br>
+ * 1. Get team id of the player<br>
+ * 2. Remove player from it's team<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if success, otherwise false
+ */
+ public static boolean removeParticipant(int playerObjectId)
+ {
+ // Check if the player is participant
+ final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
+ if (player != null)
+ {
+ player.removeEventListener(DMEventListener.class);
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean needParticipationFee()
+ {
+ return (Config.DM_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.DM_EVENT_PARTICIPATION_FEE[1] != 0);
+ }
+
+ public static boolean hasParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.getInventory().getInventoryItemCount(Config.DM_EVENT_PARTICIPATION_FEE[0], -1) >= Config.DM_EVENT_PARTICIPATION_FEE[1];
+ }
+
+ public static boolean payParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.destroyItemByItemId("DM Participation Fee", Config.DM_EVENT_PARTICIPATION_FEE[0], Config.DM_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
+ }
+
+ public static String getParticipationFee()
+ {
+ int itemId = Config.DM_EVENT_PARTICIPATION_FEE[0];
+ int itemNum = Config.DM_EVENT_PARTICIPATION_FEE[1];
+
+ if ((itemId == 0) || (itemNum == 0))
+ {
+ return "-";
+ }
+
+ return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
+ }
+
+ /**
+ * Send a SystemMessage to all participated players<br>
+ * 1. Send the message to all players of team number one<br>
+ * 2. Send the message to all players of team number two<br>
+ * <br>
+ * @param message as String<br>
+ */
+ public static void sysMsgToAllParticipants(String message)
+ {
+ for (DMEventPlayer player : _participants.values())
+ {
+ if (player != null)
+ {
+ player.getPlayer().sendMessage(message);
+ }
+ }
+ }
+
+ private static L2DoorInstance getDoor(int doorId)
+ {
+ L2DoorInstance door = null;
+ if (_DMEventInstance <= 0)
+ {
+ door = DoorData.getInstance().getDoor(doorId);
+ }
+ else
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(_DMEventInstance);
+ if (inst != null)
+ {
+ door = inst.getDoor(doorId);
+ }
+ }
+ return door;
+ }
+
+ /**
+ * Close doors specified in configs
+ * @param doors
+ */
+ private static void closeDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.closeMe();
+ }
+ }
+ }
+
+ /**
+ * Open doors specified in configs
+ * @param doors
+ */
+ private static void openDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.openMe();
+ }
+ }
+ }
+
+ /**
+ * UnSpawns the DMEvent npc
+ */
+ private static void unSpawnNpc()
+ {
+ // Delete the npc
+ _lastNpcSpawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
+ // Stop respawning of the npc
+ _npcSpawn.stopRespawn();
+ _npcSpawn = null;
+ _lastNpcSpawn = null;
+ }
+
+ /**
+ * Called when a player logs in<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogin(L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || (!isStarting() && !isStarted()))
+ {
+ return;
+ }
+
+ if (!isPlayerParticipant(playerInstance))
+ {
+ return;
+ }
+
+ new DMEventTeleporter(playerInstance.getActingPlayer(), Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, true, false);
+ // new DMEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
+ }
+
+ /**
+ * Called when a player logs out<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogout(L2PcInstance playerInstance)
+ {
+ if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
+ {
+ if (removeParticipant(playerInstance.getObjectId()))
+ {
+ playerInstance.setXYZInvisible((Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[0] + Rnd.get(101)) - 50, (Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[1] + Rnd.get(101)) - 50, Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ }
+ }
+ }
+
+ /**
+ * Called on every onAction in L2PcIstance<br>
+ * <br>
+ * @param playerInstance
+ * @param targetedPlayerObjectId
+ * @return boolean: true if player is allowed to target, otherwise false
+ */
+ public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
+ {
+ if ((playerInstance == null) || !isStarted())
+ {
+ return true;
+ }
+
+ if (playerInstance.isGM())
+ {
+ return true;
+ }
+
+ if (!isPlayerParticipant(playerInstance) && isPlayerParticipant(targetedPlayerObjectId))
+ {
+ return false;
+ }
+
+ if (isPlayerParticipant(playerInstance) && !isPlayerParticipant(targetedPlayerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every scroll use<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use scroll, otherwise false
+ */
+ public static boolean onScrollUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.DM_EVENT_SCROLL_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every potion use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use potions, otherwise false
+ */
+ public static boolean onPotionUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.DM_EVENT_POTIONS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every escape use(thanks to nbd)
+ * @param playerObjectId
+ * @return boolean: true if player is not in DM event, otherwise false
+ */
+ public static boolean onEscapeUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every summon item use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to summon by item, otherwise false
+ */
+ public static boolean onItemSummon(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.DM_EVENT_SUMMON_BY_ITEM_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is called when a player is killed<br>
+ * <br>
+ * @param killerCharacter as L2Character<br>
+ * @param killedPlayerInstance as L2PcInstance<br>
+ */
+ public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
+ {
+ if ((killedPlayerInstance == null) || !isStarted())
+ {
+ return;
+ }
+
+ new DMEventTeleporter(killedPlayerInstance, Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+
+ if (killerCharacter == null)
+ {
+ return;
+ }
+
+ L2PcInstance killerPlayerInstance = null;
+
+ if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
+ {
+ killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
+
+ if (killerPlayerInstance == null)
+ {
+ return;
+ }
+ }
+ else if (killerCharacter instanceof L2PcInstance)
+ {
+ killerPlayerInstance = (L2PcInstance) killerCharacter;
+ }
+ else
+ {
+ return;
+ }
+
+ if (isPlayerParticipant(killerPlayerInstance))
+ {
+ _participants.get(killerPlayerInstance.getObjectId()).increasePoints();
+ killerPlayerInstance.sendPacket(new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!"));
+
+ _participants.get(killedPlayerInstance.getObjectId()).increaseDeath();
+ killedPlayerInstance.sendPacket(new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I killed you!"));
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventKill(killerPlayerInstance, killedPlayerInstance, null));
+ }
+ }
+
+ /**
+ * Called on Appearing packet received (player finished teleporting)
+ * @param playerInstance
+ */
+ public static void onTeleported(L2PcInstance playerInstance)
+ {
+ if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
+ {
+ return;
+ }
+
+ if (playerInstance.isMageClass())
+ {
+ if ((Config.DM_EVENT_MAGE_BUFFS != null) && !Config.DM_EVENT_MAGE_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.DM_EVENT_MAGE_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((Config.DM_EVENT_FIGHTER_BUFFS != null) && !Config.DM_EVENT_FIGHTER_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.DM_EVENT_FIGHTER_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param source
+ * @param target
+ * @param skill
+ * @return true if player valid for skill
+ */
+ public static final boolean checkForDMSkill(L2PcInstance source, L2PcInstance target, Skill skill)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+ // DM is started
+ final int sourcePlayerId = source.getObjectId();
+ final int targetPlayerId = target.getObjectId();
+ final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
+ final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
+
+ // both players not participating
+ if (!isSourceParticipant && !isTargetParticipant)
+ {
+ return true;
+ }
+ // one player not participating
+ if (!(isSourceParticipant && isTargetParticipant))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets the DMEvent state<br>
+ * <br>
+ * @param state as EventState<br>
+ */
+ private static void setState(EventState state)
+ {
+ synchronized (_state)
+ {
+ _state = state;
+ }
+ }
+
+ /**
+ * Is DMEvent inactive?<br>
+ * <br>
+ * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
+ */
+ public static boolean isInactive()
+ {
+ boolean isInactive;
+
+ synchronized (_state)
+ {
+ isInactive = _state == EventState.INACTIVE;
+ }
+
+ return isInactive;
+ }
+
+ /**
+ * Is DMEvent in inactivating?<br>
+ * <br>
+ * @return boolean: true if event is in inactivating progress, otherwise false<br>
+ */
+ public static boolean isInactivating()
+ {
+ boolean isInactivating;
+
+ synchronized (_state)
+ {
+ isInactivating = _state == EventState.INACTIVATING;
+ }
+
+ return isInactivating;
+ }
+
+ /**
+ * Is DMEvent in participation?<br>
+ * <br>
+ * @return boolean: true if event is in participation progress, otherwise false<br>
+ */
+ public static boolean isParticipating()
+ {
+ boolean isParticipating;
+
+ synchronized (_state)
+ {
+ isParticipating = _state == EventState.PARTICIPATING;
+ }
+
+ return isParticipating;
+ }
+
+ /**
+ * Is DMEvent starting?<br>
+ * <br>
+ * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
+ */
+ public static boolean isStarting()
+ {
+ boolean isStarting;
+
+ synchronized (_state)
+ {
+ isStarting = _state == EventState.STARTING;
+ }
+
+ return isStarting;
+ }
+
+ /**
+ * Is DMEvent started?<br>
+ * <br>
+ * @return boolean: true if event is started, otherwise false<br>
+ */
+ public static boolean isStarted()
+ {
+ boolean isStarted;
+
+ synchronized (_state)
+ {
+ isStarted = _state == EventState.STARTED;
+ }
+
+ return isStarted;
+ }
+
+ /**
+ * Is DMEvent rewarding?<br>
+ * <br>
+ * @return boolean: true if event is currently rewarding, otherwise false<br>
+ */
+ public static boolean isRewarding()
+ {
+ boolean isRewarding;
+
+ synchronized (_state)
+ {
+ isRewarding = _state == EventState.REWARDING;
+ }
+
+ return isRewarding;
+ }
+
+ public static boolean isPlayerParticipant(L2PcInstance activeChar)
+ {
+ if (activeChar == null)
+ {
+ return false;
+ }
+
+ try
+ {
+ if (_participants.containsKey(activeChar.getObjectId()))
+ {
+ return true;
+ }
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+
+ return false;
+ }
+
+ /**
+ * Is given player participant of the event?
+ * @param objectId
+ * @return boolean: true if player is participant, ohterwise false
+ */
+ public static boolean isPlayerParticipant(int objectId)
+ {
+ L2PcInstance activeChar = L2World.getInstance().getPlayer(objectId);
+ if (activeChar == null)
+ {
+ return false;
+ }
+
+ return isPlayerParticipant(activeChar);
+ }
+
+ public static byte[] generateHex(int size)
+ {
+ byte[] array = new byte[size];
+ Rnd.nextBytes(array);
+ return array;
+ }
+
+ public static String hexToString(byte[] hex)
+ {
+ return new BigInteger(hex).toString(16);
+ }
+
+ public static int getDMEventInstance()
+ {
+ return _DMEventInstance;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventListener.java (working copy)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class DMEventListener implements IEventListener
+{
+ private final L2PcInstance _player;
+
+ protected DMEventListener(L2PcInstance player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return DMEvent.isStarted() && DMEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ @Override
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventPlayer.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventPlayer.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventPlayer.java (working copy)
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class DMEventPlayer
+{
+ private final L2PcInstance _player;
+ private short _points;
+ private short _death;
+ private final String _hexCode;
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ public DMEventPlayer(L2PcInstance player, int[] coordinates, String hexCode)
+ {
+ _player = player;
+ _points = 0;
+ _death = 0;
+ _hexCode = hexCode;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ public boolean isOnEvent()
+ {
+ return DMEvent.isStarted() && DMEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ /**
+ * This method can prevent from displaying 'To Village' button upon death.
+ * @param val
+ */
+ public void setCanRevive(boolean val)
+ {
+ }
+
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ _death = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * @return the _death
+ */
+ public short getDeath()
+ {
+ return _death;
+ }
+
+ /**
+ * @param death the _death to set
+ */
+ public void setDeath(short death)
+ {
+ _death = death;
+ }
+
+ /**
+ * Increases the death of the player<br>
+ */
+ public void increaseDeath()
+ {
+ ++_death;
+ }
+
+ /**
+ * @return the _hexCode
+ */
+ public String getHexCode()
+ {
+ return _hexCode;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author HorridoJoho
+ */
+public class DMEventTeam
+{
+ /** The name of the team<br> */
+ private final String _name;
+ /** The team spot coordinated<br> */
+ private int[] _coordinates = new int[3];
+ /** The points of the team<br> */
+ private short _points;
+ /** Name and instance of all participated players in FastMap<br> */
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ /**
+ * C'tor initialize the team<br>
+ * <br>
+ * @param name as String<br>
+ * @param coordinates as int[]<br>
+ */
+ public DMEventTeam(String name, int[] coordinates)
+ {
+ _name = name;
+ _coordinates = coordinates;
+ _points = 0;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes a player from the team
+ * @param playerObjectId
+ */
+ public void removePlayer(int playerObjectId)
+ {
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.remove(playerObjectId);
+ }
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * Returns the name of the team<br>
+ * <br>
+ * @return String: name of the team<br>
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the coordinates of the team spot<br>
+ * <br>
+ * @return int[]: team coordinates<br>
+ */
+ public int[] getCoordinates()
+ {
+ return _coordinates;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeleporter.java (working copy)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.Team;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Duel;
+import com.l2jserver.util.Rnd;
+
+public class DMEventTeleporter implements Runnable
+{
+ /** The instance of the player to teleport */
+ private L2PcInstance _playerInstance = null;
+ /** Coordinates of the spot to teleport to */
+ private int[] _coordinates = new int[3];
+ /** Admin removed this player from event */
+ private boolean _adminRemove = false;
+
+ /**
+ * Initialize the teleporter and start the delayed task.
+ * @param playerInstance
+ * @param coordinates
+ * @param fastSchedule
+ * @param adminRemove
+ */
+ public DMEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
+ {
+ _playerInstance = playerInstance;
+ _coordinates = coordinates;
+ _adminRemove = adminRemove;
+
+ long delay = (DMEvent.isStarted() ? Config.DM_EVENT_RESPAWN_TELEPORT_DELAY : Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
+
+ ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
+ }
+
+ /**
+ * The task method to teleport the player<br>
+ * 1. Unsummon pet if there is one<br>
+ * 2. Remove all effects<br>
+ * 3. Revive and full heal the player<br>
+ * 4. Teleport the player<br>
+ * 5. Broadcast status and user info
+ */
+ @Override
+ public void run()
+ {
+ if (_playerInstance == null)
+ {
+ return;
+ }
+
+ L2Summon summon = _playerInstance.getSummon();
+
+ if (summon != null)
+ {
+ summon.unSummon(_playerInstance);
+ }
+
+ if ((Config.DM_EVENT_EFFECTS_REMOVAL == 0) || ((Config.DM_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
+ {
+ _playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
+ }
+
+ if (_playerInstance.isInDuel())
+ {
+ _playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
+ }
+
+ int DMInstance = DMEvent.getDMEventInstance();
+ if (DMInstance != 0)
+ {
+ if (DMEvent.isStarted() && !_adminRemove)
+ {
+ _playerInstance.setInstanceId(DMInstance);
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+
+ _playerInstance.doRevive();
+
+ _playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
+
+ _playerInstance.setCurrentCp(_playerInstance.getMaxCp());
+ _playerInstance.setCurrentHp(_playerInstance.getMaxHp());
+ _playerInstance.setCurrentMp(_playerInstance.getMaxMp());
+
+ _playerInstance.broadcastStatusUpdate();
+ _playerInstance.broadcastUserInfo();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMManager.java (working copy)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author HorridoJoho
+ */
+public class DMManager
+{
+ protected static final Logger _log = Logger.getLogger(DMManager.class.getName());
+
+ /** Task for event cycles<br> */
+ private DMStartTask _task;
+
+ /**
+ * New instance only by getInstance()<br>
+ */
+ protected DMManager()
+ {
+ if (Config.DM_EVENT_ENABLED)
+ {
+ DMEvent.init();
+
+ scheduleEventStart();
+ _log.info("DMEventEngine[DMManager.DMManager()]: Started.");
+ }
+ else
+ {
+ _log.info("DMEventEngine[DMManager.DMManager()]: Engine is disabled.");
+ }
+ }
+
+ /**
+ * Initialize new/Returns the one and only instance<br>
+ * <br>
+ * @return DMManager<br>
+ */
+ public static DMManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ /**
+ * Starts DMStartTask
+ */
+ public void scheduleEventStart()
+ {
+ try
+ {
+ Calendar currentTime = Calendar.getInstance();
+ Calendar nextStartTime = null;
+ Calendar testStartTime = null;
+ for (String timeOfDay : Config.DM_EVENT_INTERVAL)
+ {
+ // Creating a Calendar object from the specified interval value
+ testStartTime = Calendar.getInstance();
+ testStartTime.setLenient(true);
+ String[] splitTimeOfDay = timeOfDay.split(":");
+ testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+ testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+ // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
+ if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+ {
+ testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ // Check for the test date to be the minimum (smallest in the specified list)
+ if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
+ {
+ nextStartTime = testStartTime;
+ }
+ }
+ if (nextStartTime != null)
+ {
+ _task = new DMStartTask(nextStartTime.getTimeInMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+ catch (Exception e)
+ {
+ _log.warning("DMEventEngine[DMManager.scheduleEventStart()]: Error figuring out a start time. Check DMEventInterval in config file.");
+ }
+ }
+
+ /**
+ * Method to start participation
+ */
+ public void startReg()
+ {
+ if (!DMEvent.startParticipation())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: Event was cancelled.");
+ _log.warning("DMEventEngine[DMManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: Registration opened for " + Config.DM_EVENT_PARTICIPATION_TIME + " minute(s).");
+
+ // schedule registration end
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.DM_EVENT_PARTICIPATION_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to start the fight
+ */
+ public void startEvent()
+ {
+ if (!DMEvent.startFight())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: Event cancelled due to lack of Participation.");
+ _log.info("DMEventEngine[DMManager.run()]: Lack of registration, abort event.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: Teleporting participants to an arena in " + Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.DM_EVENT_RUNNING_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to end the event and reward
+ */
+ public void endEvent()
+ {
+ Broadcast.toAllOnlinePlayers(DMEvent.calculateRewards());
+ DMEvent.sysMsgToAllParticipants("DM Event: Teleporting back to the registration npc in " + Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ DMEvent.stopFight();
+
+ scheduleEventStart();
+ }
+
+ public void skipDelay()
+ {
+ if (_task.nextRun.cancel(false))
+ {
+ _task.setStartTime(System.currentTimeMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Class for DM cycles
+ */
+ class DMStartTask implements Runnable
+ {
+ private long _startTime;
+ public ScheduledFuture<?> nextRun;
+
+ public DMStartTask(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ public void setStartTime(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ @Override
+ public void run()
+ {
+ int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+
+ if (delay > 0)
+ {
+ announce(delay);
+ }
+
+ int nextMsg = 0;
+ if (delay > 3600)
+ {
+ nextMsg = delay - 3600;
+ }
+ else if (delay > 1800)
+ {
+ nextMsg = delay - 1800;
+ }
+ else if (delay > 900)
+ {
+ nextMsg = delay - 900;
+ }
+ else if (delay > 600)
+ {
+ nextMsg = delay - 600;
+ }
+ else if (delay > 300)
+ {
+ nextMsg = delay - 300;
+ }
+ else if (delay > 60)
+ {
+ nextMsg = delay - 60;
+ }
+ else if (delay > 5)
+ {
+ nextMsg = delay - 5;
+ }
+ else if (delay > 0)
+ {
+ nextMsg = delay;
+ }
+ else
+ {
+ // start
+ if (DMEvent.isInactive())
+ {
+ startReg();
+ }
+ else if (DMEvent.isParticipating())
+ {
+ startEvent();
+ }
+ else
+ {
+ endEvent();
+ }
+ }
+
+ if (delay > 0)
+ {
+ nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+ }
+ }
+
+ private void announce(long time)
+ {
+ if ((time >= 3600) && ((time % 3600) == 0))
+ {
+ if (DMEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
+ }
+ else if (DMEvent.isStarted())
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
+ }
+ }
+ else if (time >= 60)
+ {
+ if (DMEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: " + (time / 60) + " minute(s) until registration is closed!");
+ }
+ else if (DMEvent.isStarted())
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: " + (time / 60) + " minute(s) until the event is finished!");
+ }
+ }
+ else
+ {
+ if (DMEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: " + time + " second(s) until registration is closed!");
+ }
+ else if (DMEvent.isStarted())
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: " + time + " second(s) until the event is finished!");
+ }
+ }
+ }
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final DMManager _instance = new DMManager();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEvent.java (working copy)
@@ -0,0 +1,1204 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.data.xml.impl.DoorData;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.SkillData;
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
+import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventStart;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.skills.CommonSkill;
+import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.network.NpcStringId;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
+import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author HorridoJoho
+ */
+public class TvTEvent
+{
+ enum EventState
+ {
+ INACTIVE,
+ INACTIVATING,
+ PARTICIPATING,
+ STARTING,
+ STARTED,
+ REWARDING
+ }
+
+ protected static final Logger _log = Logger.getLogger(TvTEvent.class.getName());
+ /** html path **/
+ private static final String htmlPath = "data/scripts/custom/events/TvT/TvTManager/";
+ /** The teams of the TvTEvent<br> */
+ private static TvTEventTeam[] _teams = new TvTEventTeam[2];
+ /** The state of the TvTEvent<br> */
+ private static EventState _state = EventState.INACTIVE;
+ /** The spawn of the participation npc<br> */
+ private static L2Spawn _npcSpawn = null;
+ /** the npc instance of the participation npc<br> */
+ private static L2Npc _lastNpcSpawn = null;
+ /** Instance id<br> */
+ private static int _TvTEventInstance = 0;
+
+ /**
+ * No instance of this class!<br>
+ */
+ private TvTEvent()
+ {
+ }
+
+ /**
+ * Teams initializing<br>
+ */
+ public static void init()
+ {
+ AntiFeedManager.getInstance().registerEvent(AntiFeedManager.TVT_ID);
+ _teams[0] = new TvTEventTeam(Config.TVT_EVENT_TEAM_1_NAME, Config.TVT_EVENT_TEAM_1_COORDINATES);
+ _teams[1] = new TvTEventTeam(Config.TVT_EVENT_TEAM_2_NAME, Config.TVT_EVENT_TEAM_2_COORDINATES);
+ }
+
+ /**
+ * Starts the participation of the TvTEvent<br>
+ * 1. Get L2NpcTemplate by Config.TVT_EVENT_PARTICIPATION_NPC_ID<br>
+ * 2. Try to spawn a new npc of it<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startParticipation()
+ {
+ try
+ {
+ _npcSpawn = new L2Spawn(Config.TVT_EVENT_PARTICIPATION_NPC_ID);
+
+ _npcSpawn.setX(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[0]);
+ _npcSpawn.setY(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[1]);
+ _npcSpawn.setZ(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ _npcSpawn.setAmount(1);
+ _npcSpawn.setHeading(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[3]);
+ _npcSpawn.setRespawnDelay(1);
+ // later no need to delete spawn from db, we don't store it (false)
+ SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
+ _npcSpawn.init();
+ _lastNpcSpawn = _npcSpawn.getLastSpawn();
+ _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
+ _lastNpcSpawn.setTitle("TvT Event Participation");
+ _lastNpcSpawn.isAggressive();
+ _lastNpcSpawn.decayMe();
+ _lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
+ _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "TvTEventEngine[TvTEvent.startParticipation()]: exception: " + e.getMessage(), e);
+ return false;
+ }
+
+ setState(EventState.PARTICIPATING);
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventRegistrationStart());
+ return true;
+ }
+
+ private static int highestLevelPcInstanceOf(Map<Integer, L2PcInstance> players)
+ {
+ int maxLevel = Integer.MIN_VALUE, maxLevelId = -1;
+ for (L2PcInstance player : players.values())
+ {
+ if (player.getLevel() >= maxLevel)
+ {
+ maxLevel = player.getLevel();
+ maxLevelId = player.getObjectId();
+ }
+ }
+ return maxLevelId;
+ }
+
+ /**
+ * Starts the TvTEvent fight<br>
+ * 1. Set state EventState.STARTING<br>
+ * 2. Close doors specified in configs<br>
+ * 3. Abort if not enought participants(return false)<br>
+ * 4. Set state EventState.STARTED<br>
+ * 5. Teleport all participants to team spot<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startFight()
+ {
+ // Set state to STARTING
+ setState(EventState.STARTING);
+
+ // Randomize and balance team distribution
+ Map<Integer, L2PcInstance> allParticipants = new FastMap<>();
+ allParticipants.putAll(_teams[0].getParticipatedPlayers());
+ allParticipants.putAll(_teams[1].getParticipatedPlayers());
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+
+ L2PcInstance player;
+ Iterator<L2PcInstance> iter;
+ if (needParticipationFee())
+ {
+ iter = allParticipants.values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!hasParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ int balance[] =
+ {
+ 0,
+ 0
+ }, priority = 0, highestLevelPlayerId;
+ L2PcInstance highestLevelPlayer;
+ // TODO: allParticipants should be sorted by level instead of using highestLevelPcInstanceOf for every fetch
+ while (!allParticipants.isEmpty())
+ {
+ // Priority team gets one player
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Exiting if no more players
+ if (allParticipants.isEmpty())
+ {
+ break;
+ }
+ // The other team gets one player
+ // TODO: Code not dry
+ priority = 1 - priority;
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Recalculating priority
+ priority = balance[0] > balance[1] ? 1 : 0;
+ }
+
+ // Check for enought participants
+ if ((_teams[0].getParticipatedPlayerCount() < Config.TVT_EVENT_MIN_PLAYERS_IN_TEAMS) || (_teams[1].getParticipatedPlayerCount() < Config.TVT_EVENT_MIN_PLAYERS_IN_TEAMS))
+ {
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Unspawn the event NPC
+ unSpawnNpc();
+ AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
+ return false;
+ }
+
+ if (needParticipationFee())
+ {
+ iter = _teams[0].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ iter = _teams[1].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ if (Config.TVT_EVENT_IN_INSTANCE)
+ {
+ try
+ {
+ _TvTEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.TVT_EVENT_INSTANCE_FILE);
+ InstanceManager.getInstance().getInstance(_TvTEventInstance).setAllowSummon(false);
+ InstanceManager.getInstance().getInstance(_TvTEventInstance).setPvPInstance(true);
+ InstanceManager.getInstance().getInstance(_TvTEventInstance).setEmptyDestroyTime((Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L);
+ }
+ catch (Exception e)
+ {
+ _TvTEventInstance = 0;
+ _log.log(Level.WARNING, "TvTEventEngine[TvTEvent.createDynamicInstance]: exception: " + e.getMessage(), e);
+ }
+ }
+
+ // Opens all doors specified in configs for tvt
+ openDoors(Config.TVT_DOORS_IDS_TO_OPEN);
+ // Closes all doors specified in configs for tvt
+ closeDoors(Config.TVT_DOORS_IDS_TO_CLOSE);
+ // Set state STARTED
+ setState(EventState.STARTED);
+
+ // Iterate over all teams
+ for (TvTEventTeam team : _teams)
+ {
+ // Iterate over all participated player instances in this team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ // Disable player revival.
+ playerInstance.setCanRevive(false);
+ // Teleporter implements Runnable and starts itself
+ new TvTEventTeleporter(playerInstance, team.getCoordinates(), false, false);
+ }
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventStart());
+ return true;
+ }
+
+ /**
+ * Calculates the TvTEvent reward<br>
+ * 1. If both teams are at a tie(points equals), send it as system message to all participants, if one of the teams have 0 participants left online abort rewarding<br>
+ * 2. Wait till teams are not at a tie anymore<br>
+ * 3. Set state EvcentState.REWARDING<br>
+ * 4. Reward team with more points<br>
+ * 5. Show win html to wining team participants<br>
+ * <br>
+ * @return String: winning team name<br>
+ */
+ public static String calculateRewards()
+ {
+ if (_teams[0].getPoints() == _teams[1].getPoints())
+ {
+ // Check if one of the teams have no more players left
+ if ((_teams[0].getParticipatedPlayerCount() == 0) || (_teams[1].getParticipatedPlayerCount() == 0))
+ {
+ // set state to rewarding
+ setState(EventState.REWARDING);
+ // return here, the fight can't be completed
+ return "TvT Event: Event has ended. No team won due to inactivity!";
+ }
+
+ // Both teams have equals points
+ sysMsgToAllParticipants("TvT Event: Event has ended, both teams have tied.");
+ if (Config.TVT_REWARD_TEAM_TIE)
+ {
+ rewardTeam(_teams[0]);
+ rewardTeam(_teams[1]);
+ return "TvT Event: Event has ended with both teams tying.";
+ }
+ return "TvT Event: Event has ended with both teams tying.";
+ }
+
+ // Set state REWARDING so nobody can point anymore
+ setState(EventState.REWARDING);
+
+ // Get team which has more points
+ TvTEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1];
+ rewardTeam(team);
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventFinish());
+ return "TvT Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills.";
+ }
+
+ private static void rewardTeam(TvTEventTeam team)
+ {
+ // Iterate over all participated player instances of the winning team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance == null)
+ {
+ continue;
+ }
+
+ // Add Fireworks for rewarded player
+ playerInstance.broadcastPacket(new MagicSkillUse(playerInstance, playerInstance, CommonSkill.FIREWORK.getSkill().getId(), 1, 1, 1));
+
+ SystemMessage systemMessage = null;
+
+ // Iterate over all tvt event rewards
+ for (int[] reward : Config.TVT_EVENT_REWARDS)
+ {
+ PcInventory inv = playerInstance.getInventory();
+
+ // Check for stackable item, non stackabe items need to be added one by one
+ if (ItemTable.getInstance().getTemplate(reward[0]).isStackable())
+ {
+ inv.addItem("TvT Event", reward[0], reward[1], playerInstance, playerInstance);
+
+ if (reward[1] > 1)
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+ systemMessage.addItemName(reward[0]);
+ systemMessage.addLong(reward[1]);
+ }
+ else
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ }
+
+ playerInstance.sendPacket(systemMessage);
+ }
+ else
+ {
+ for (int i = 0; i < reward[1]; ++i)
+ {
+ inv.addItem("TvT Event", reward[0], 1, playerInstance, playerInstance);
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ playerInstance.sendPacket(systemMessage);
+ }
+ }
+ }
+
+ StatusUpdate statusUpdate = new StatusUpdate(playerInstance);
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, playerInstance.getCurrentLoad());
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Reward.html"));
+ playerInstance.sendPacket(statusUpdate);
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+
+ /**
+ * Stops the TvTEvent fight<br>
+ * 1. Set state EventState.INACTIVATING<br>
+ * 2. Remove tvt npc from world<br>
+ * 3. Open doors specified in configs<br>
+ * 4. Teleport all participants back to participation npc location<br>
+ * 5. Teams cleaning<br>
+ * 6. Set state EventState.INACTIVE<br>
+ */
+ public static void stopFight()
+ {
+ // Set state INACTIVATING
+ setState(EventState.INACTIVATING);
+ // Unspawn event npc
+ unSpawnNpc();
+ // Opens all doors specified in configs for tvt
+ openDoors(Config.TVT_DOORS_IDS_TO_CLOSE);
+ // Closes all doors specified in Configs for tvt
+ closeDoors(Config.TVT_DOORS_IDS_TO_OPEN);
+
+ // Iterate over all teams
+ for (TvTEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance != null)
+ {
+ // Enable player revival.
+ playerInstance.setCanRevive(true);
+ // Teleport back.
+ new TvTEventTeleporter(playerInstance, Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+ }
+
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
+ }
+
+ /**
+ * Adds a player to a TvTEvent team<br>
+ * 1. Calculate the id of the team in which the player should be added<br>
+ * 2. Add the player to the calculated team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static synchronized boolean addParticipant(L2PcInstance playerInstance)
+ {
+ // Check for nullpoitner
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ byte teamId = 0;
+
+ // Check to which team the player should be added
+ if (_teams[0].getParticipatedPlayerCount() == _teams[1].getParticipatedPlayerCount())
+ {
+ teamId = (byte) (Rnd.get(2));
+ }
+ else
+ {
+ teamId = (byte) (_teams[0].getParticipatedPlayerCount() > _teams[1].getParticipatedPlayerCount() ? 1 : 0);
+ }
+ playerInstance.addEventListener(new TvTEventListener(playerInstance));
+ return _teams[teamId].addPlayer(playerInstance);
+ }
+
+ /**
+ * Removes a TvTEvent player from it's team<br>
+ * 1. Get team id of the player<br>
+ * 2. Remove player from it's team<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if success, otherwise false
+ */
+ public static boolean removeParticipant(int playerObjectId)
+ {
+ // Get the teamId of the player
+ byte teamId = getParticipantTeamId(playerObjectId);
+
+ // Check if the player is participant
+ if (teamId != -1)
+ {
+ // Remove the player from team
+ _teams[teamId].removePlayer(playerObjectId);
+
+ final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
+ if (player != null)
+ {
+ player.removeEventListener(TvTEventListener.class);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean needParticipationFee()
+ {
+ return (Config.TVT_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.TVT_EVENT_PARTICIPATION_FEE[1] != 0);
+ }
+
+ public static boolean hasParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.getInventory().getInventoryItemCount(Config.TVT_EVENT_PARTICIPATION_FEE[0], -1) >= Config.TVT_EVENT_PARTICIPATION_FEE[1];
+ }
+
+ public static boolean payParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.destroyItemByItemId("TvT Participation Fee", Config.TVT_EVENT_PARTICIPATION_FEE[0], Config.TVT_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
+ }
+
+ public static String getParticipationFee()
+ {
+ int itemId = Config.TVT_EVENT_PARTICIPATION_FEE[0];
+ int itemNum = Config.TVT_EVENT_PARTICIPATION_FEE[1];
+
+ if ((itemId == 0) || (itemNum == 0))
+ {
+ return "-";
+ }
+
+ return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
+ }
+
+ /**
+ * Send a SystemMessage to all participated players<br>
+ * 1. Send the message to all players of team number one<br>
+ * 2. Send the message to all players of team number two<br>
+ * <br>
+ * @param message as String<br>
+ */
+ public static void sysMsgToAllParticipants(String message)
+ {
+ for (L2PcInstance playerInstance : _teams[0].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+
+ for (L2PcInstance playerInstance : _teams[1].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+ }
+
+ private static L2DoorInstance getDoor(int doorId)
+ {
+ L2DoorInstance door = null;
+ if (_TvTEventInstance <= 0)
+ {
+ door = DoorData.getInstance().getDoor(doorId);
+ }
+ else
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(_TvTEventInstance);
+ if (inst != null)
+ {
+ door = inst.getDoor(doorId);
+ }
+ }
+ return door;
+ }
+
+ /**
+ * Close doors specified in configs
+ * @param doors
+ */
+ private static void closeDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.closeMe();
+ }
+ }
+ }
+
+ /**
+ * Open doors specified in configs
+ * @param doors
+ */
+ private static void openDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.openMe();
+ }
+ }
+ }
+
+ /**
+ * UnSpawns the TvTEvent npc
+ */
+ private static void unSpawnNpc()
+ {
+ // Delete the npc
+ _lastNpcSpawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
+ // Stop respawning of the npc
+ _npcSpawn.stopRespawn();
+ _npcSpawn = null;
+ _lastNpcSpawn = null;
+ }
+
+ /**
+ * Called when a player logs in<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogin(L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || (!isStarting() && !isStarted()))
+ {
+ return;
+ }
+
+ byte teamId = getParticipantTeamId(playerInstance.getObjectId());
+
+ if (teamId == -1)
+ {
+ return;
+ }
+
+ _teams[teamId].addPlayer(playerInstance);
+ new TvTEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
+ }
+
+ /**
+ * Called when a player logs out<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogout(L2PcInstance playerInstance)
+ {
+ if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
+ {
+ if (removeParticipant(playerInstance.getObjectId()))
+ {
+ playerInstance.setXYZInvisible((Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[0] + Rnd.get(101)) - 50, (Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[1] + Rnd.get(101)) - 50, Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ }
+ }
+ }
+
+ /**
+ * Called on every onAction in L2PcIstance<br>
+ * <br>
+ * @param playerInstance
+ * @param targetedPlayerObjectId
+ * @return boolean: true if player is allowed to target, otherwise false
+ */
+ public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
+ {
+ if ((playerInstance == null) || !isStarted())
+ {
+ return true;
+ }
+
+ if (playerInstance.isGM())
+ {
+ return true;
+ }
+
+ byte playerTeamId = getParticipantTeamId(playerInstance.getObjectId());
+ byte targetedPlayerTeamId = getParticipantTeamId(targetedPlayerObjectId);
+
+ if (((playerTeamId != -1) && (targetedPlayerTeamId == -1)) || ((playerTeamId == -1) && (targetedPlayerTeamId != -1)))
+ {
+ return false;
+ }
+
+ if ((playerTeamId != -1) && (targetedPlayerTeamId != -1) && (playerTeamId == targetedPlayerTeamId) && (playerInstance.getObjectId() != targetedPlayerObjectId) && !Config.TVT_EVENT_TARGET_TEAM_MEMBERS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every scroll use<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use scroll, otherwise false
+ */
+ public static boolean onScrollUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_SCROLL_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every potion use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use potions, otherwise false
+ */
+ public static boolean onPotionUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_POTIONS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every escape use(thanks to nbd)
+ * @param playerObjectId
+ * @return boolean: true if player is not in tvt event, otherwise false
+ */
+ public static boolean onEscapeUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every summon item use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to summon by item, otherwise false
+ */
+ public static boolean onItemSummon(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_SUMMON_BY_ITEM_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is called when a player is killed<br>
+ * <br>
+ * @param killerCharacter as L2Character<br>
+ * @param killedPlayerInstance as L2PcInstance<br>
+ */
+ public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
+ {
+ if ((killedPlayerInstance == null) || !isStarted())
+ {
+ return;
+ }
+
+ byte killedTeamId = getParticipantTeamId(killedPlayerInstance.getObjectId());
+
+ if (killedTeamId == -1)
+ {
+ return;
+ }
+
+ new TvTEventTeleporter(killedPlayerInstance, _teams[killedTeamId].getCoordinates(), false, false);
+
+ if (killerCharacter == null)
+ {
+ return;
+ }
+
+ L2PcInstance killerPlayerInstance = null;
+
+ if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
+ {
+ killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
+
+ if (killerPlayerInstance == null)
+ {
+ return;
+ }
+ }
+ else if (killerCharacter instanceof L2PcInstance)
+ {
+ killerPlayerInstance = (L2PcInstance) killerCharacter;
+ }
+ else
+ {
+ return;
+ }
+
+ byte killerTeamId = getParticipantTeamId(killerPlayerInstance.getObjectId());
+
+ if ((killerTeamId != -1) && (killedTeamId != -1) && (killerTeamId != killedTeamId))
+ {
+ TvTEventTeam killerTeam = _teams[killerTeamId];
+
+ killerTeam.increasePoints();
+
+ CreatureSay cs = new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!");
+
+ for (L2PcInstance playerInstance : _teams[killerTeamId].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendPacket(cs);
+ broadcastScoreMessage();
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventKill(killerPlayerInstance, killedPlayerInstance, killerTeam));
+ }
+ }
+
+ /**
+ * Called on Appearing packet received (player finished teleporting)
+ * @param playerInstance
+ */
+ public static void onTeleported(L2PcInstance playerInstance)
+ {
+ if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
+ {
+ return;
+ }
+
+ if (playerInstance.isMageClass())
+ {
+ if ((Config.TVT_EVENT_MAGE_BUFFS != null) && !Config.TVT_EVENT_MAGE_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.TVT_EVENT_MAGE_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((Config.TVT_EVENT_FIGHTER_BUFFS != null) && !Config.TVT_EVENT_FIGHTER_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.TVT_EVENT_FIGHTER_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param source
+ * @param target
+ * @param skill
+ * @return true if player valid for skill
+ */
+ public static final boolean checkForTvTSkill(L2PcInstance source, L2PcInstance target, Skill skill)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+ // TvT is started
+ final int sourcePlayerId = source.getObjectId();
+ final int targetPlayerId = target.getObjectId();
+ final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
+ final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
+
+ // both players not participating
+ if (!isSourceParticipant && !isTargetParticipant)
+ {
+ return true;
+ }
+ // one player not participating
+ if (!(isSourceParticipant && isTargetParticipant))
+ {
+ return false;
+ }
+ // players in the different teams ?
+ if (getParticipantTeamId(sourcePlayerId) != getParticipantTeamId(targetPlayerId))
+ {
+ if (!skill.isBad())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Sets the TvTEvent state<br>
+ * <br>
+ * @param state as EventState<br>
+ */
+ private static void setState(EventState state)
+ {
+ synchronized (_state)
+ {
+ _state = state;
+ }
+ }
+
+ /**
+ * Is TvTEvent inactive?<br>
+ * <br>
+ * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
+ */
+ public static boolean isInactive()
+ {
+ boolean isInactive;
+
+ synchronized (_state)
+ {
+ isInactive = _state == EventState.INACTIVE;
+ }
+
+ return isInactive;
+ }
+
+ /**
+ * Is TvTEvent in inactivating?<br>
+ * <br>
+ * @return boolean: true if event is in inactivating progress, otherwise false<br>
+ */
+ public static boolean isInactivating()
+ {
+ boolean isInactivating;
+
+ synchronized (_state)
+ {
+ isInactivating = _state == EventState.INACTIVATING;
+ }
+
+ return isInactivating;
+ }
+
+ /**
+ * Is TvTEvent in participation?<br>
+ * <br>
+ * @return boolean: true if event is in participation progress, otherwise false<br>
+ */
+ public static boolean isParticipating()
+ {
+ boolean isParticipating;
+
+ synchronized (_state)
+ {
+ isParticipating = _state == EventState.PARTICIPATING;
+ }
+
+ return isParticipating;
+ }
+
+ /**
+ * Is TvTEvent starting?<br>
+ * <br>
+ * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
+ */
+ public static boolean isStarting()
+ {
+ boolean isStarting;
+
+ synchronized (_state)
+ {
+ isStarting = _state == EventState.STARTING;
+ }
+
+ return isStarting;
+ }
+
+ /**
+ * Is TvTEvent started?<br>
+ * <br>
+ * @return boolean: true if event is started, otherwise false<br>
+ */
+ public static boolean isStarted()
+ {
+ boolean isStarted;
+
+ synchronized (_state)
+ {
+ isStarted = _state == EventState.STARTED;
+ }
+
+ return isStarted;
+ }
+
+ /**
+ * Is TvTEvent rewarding?<br>
+ * <br>
+ * @return boolean: true if event is currently rewarding, otherwise false<br>
+ */
+ public static boolean isRewarding()
+ {
+ boolean isRewarding;
+
+ synchronized (_state)
+ {
+ isRewarding = _state == EventState.REWARDING;
+ }
+
+ return isRewarding;
+ }
+
+ /**
+ * Returns the team id of a player, if player is not participant it returns -1
+ * @param playerObjectId
+ * @return byte: team name of the given playerName, if not in event -1
+ */
+ public static byte getParticipantTeamId(int playerObjectId)
+ {
+ return (byte) (_teams[0].containsPlayer(playerObjectId) ? 0 : (_teams[1].containsPlayer(playerObjectId) ? 1 : -1));
+ }
+
+ /**
+ * Returns the team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return TvTEventTeam: team of the given playerObjectId, if not in event null
+ */
+ public static TvTEventTeam getParticipantTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[0] : (_teams[1].containsPlayer(playerObjectId) ? _teams[1] : null));
+ }
+
+ /**
+ * Returns the enemy team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return TvTEventTeam: enemy team of the given playerObjectId, if not in event null
+ */
+ public static TvTEventTeam getParticipantEnemyTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[1] : (_teams[1].containsPlayer(playerObjectId) ? _teams[0] : null));
+ }
+
+ /**
+ * Returns the team coordinates in which the player is in, if player is not in a team return null
+ * @param playerObjectId
+ * @return int[]: coordinates of teams, 2 elements, index 0 for team 1 and index 1 for team 2
+ */
+ public static int[] getParticipantTeamCoordinates(int playerObjectId)
+ {
+ return _teams[0].containsPlayer(playerObjectId) ? _teams[0].getCoordinates() : (_teams[1].containsPlayer(playerObjectId) ? _teams[1].getCoordinates() : null);
+ }
+
+ /**
+ * Is given player participant of the event?
+ * @param playerObjectId
+ * @return boolean: true if player is participant, ohterwise false
+ */
+ public static boolean isPlayerParticipant(int playerObjectId)
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return false;
+ }
+
+ return _teams[0].containsPlayer(playerObjectId) || _teams[1].containsPlayer(playerObjectId);
+ }
+
+ /**
+ * Returns participated player count<br>
+ * <br>
+ * @return int: amount of players registered in the event<br>
+ */
+ public static int getParticipatedPlayersCount()
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return 0;
+ }
+
+ return _teams[0].getParticipatedPlayerCount() + _teams[1].getParticipatedPlayerCount();
+ }
+
+ /**
+ * Returns teams names<br>
+ * <br>
+ * @return String[]: names of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static String[] getTeamNames()
+ {
+ return new String[]
+ {
+ _teams[0].getName(),
+ _teams[1].getName()
+ };
+ }
+
+ /**
+ * Returns player count of both teams<br>
+ * <br>
+ * @return int[]: player count of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPlayerCounts()
+ {
+ return new int[]
+ {
+ _teams[0].getParticipatedPlayerCount(),
+ _teams[1].getParticipatedPlayerCount()
+ };
+ }
+
+ /**
+ * Returns points count of both teams
+ * @return int[]: points of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPoints()
+ {
+ return new int[]
+ {
+ _teams[0].getPoints(),
+ _teams[1].getPoints()
+ };
+ }
+
+ /**
+ * Broadcast score to all participants
+ */
+ public static void broadcastScoreMessage()
+ {
+ final String score = Config.TVT_EVENT_TEAM_1_NAME + ": " + _teams[0].getPoints() + " - " + Config.TVT_EVENT_TEAM_2_NAME + ": " + _teams[1].getPoints();
+
+ for (TvTEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if ((playerInstance != null) && (playerInstance.getInstanceId() == _TvTEventInstance))
+ {
+ playerInstance.sendPacket(new ExShowScreenMessage(1, -1, 8, 0, 1, 0, 0, false, 15000, true, score, NpcStringId.NONE, null));
+ }
+ }
+ }
+ }
+
+ public static int getTvTEventInstance()
+ {
+ return _TvTEventInstance;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventListener.java (working copy)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class TvTEventListener implements IEventListener
+{
+ private final L2PcInstance _player;
+
+ protected TvTEventListener(L2PcInstance player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ @Override
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventPlayer.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventPlayer.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventPlayer.java (working copy)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class TvTEventPlayer
+{
+ private final L2PcInstance _player;
+
+ protected TvTEventPlayer(L2PcInstance player)
+ {
+ _player = player;
+
+ }
+
+ public boolean isOnEvent()
+ {
+ return TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author HorridoJoho
+ */
+public class TvTEventTeam
+{
+ /** The name of the team<br> */
+ private final String _name;
+ /** The team spot coordinated<br> */
+ private int[] _coordinates = new int[3];
+ /** The points of the team<br> */
+ private short _points;
+ /** Name and instance of all participated players in FastMap<br> */
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ /**
+ * C'tor initialize the team<br>
+ * <br>
+ * @param name as String<br>
+ * @param coordinates as int[]<br>
+ */
+ public TvTEventTeam(String name, int[] coordinates)
+ {
+ _name = name;
+ _coordinates = coordinates;
+ _points = 0;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes a player from the team
+ * @param playerObjectId
+ */
+ public void removePlayer(int playerObjectId)
+ {
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.remove(playerObjectId);
+ }
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * Returns the name of the team<br>
+ * <br>
+ * @return String: name of the team<br>
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the coordinates of the team spot<br>
+ * <br>
+ * @return int[]: team coordinates<br>
+ */
+ public int[] getCoordinates()
+ {
+ return _coordinates;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeleporter.java (working copy)
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.Team;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Duel;
+import com.l2jserver.util.Rnd;
+
+public class TvTEventTeleporter implements Runnable
+{
+ /** The instance of the player to teleport */
+ private L2PcInstance _playerInstance = null;
+ /** Coordinates of the spot to teleport to */
+ private int[] _coordinates = new int[3];
+ /** Admin removed this player from event */
+ private boolean _adminRemove = false;
+
+ /**
+ * Initialize the teleporter and start the delayed task.
+ * @param playerInstance
+ * @param coordinates
+ * @param fastSchedule
+ * @param adminRemove
+ */
+ public TvTEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
+ {
+ _playerInstance = playerInstance;
+ _coordinates = coordinates;
+ _adminRemove = adminRemove;
+
+ long delay = (TvTEvent.isStarted() ? Config.TVT_EVENT_RESPAWN_TELEPORT_DELAY : Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
+
+ ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
+ }
+
+ /**
+ * The task method to teleport the player<br>
+ * 1. Unsummon pet if there is one<br>
+ * 2. Remove all effects<br>
+ * 3. Revive and full heal the player<br>
+ * 4. Teleport the player<br>
+ * 5. Broadcast status and user info
+ */
+ @Override
+ public void run()
+ {
+ if (_playerInstance == null)
+ {
+ return;
+ }
+
+ L2Summon summon = _playerInstance.getSummon();
+
+ if (summon != null)
+ {
+ summon.unSummon(_playerInstance);
+ }
+
+ if ((Config.TVT_EVENT_EFFECTS_REMOVAL == 0) || ((Config.TVT_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
+ {
+ _playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
+ }
+
+ if (_playerInstance.isInDuel())
+ {
+ _playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
+ }
+
+ int TvTInstance = TvTEvent.getTvTEventInstance();
+ if (TvTInstance != 0)
+ {
+ if (TvTEvent.isStarted() && !_adminRemove)
+ {
+ _playerInstance.setInstanceId(TvTInstance);
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+
+ _playerInstance.doRevive();
+
+ _playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
+
+ if (TvTEvent.isStarted() && !_adminRemove)
+ {
+ int teamId = TvTEvent.getParticipantTeamId(_playerInstance.getObjectId()) + 1;
+ switch (teamId)
+ {
+ case 0:
+ _playerInstance.setTeam(Team.NONE);
+ break;
+ case 1:
+ _playerInstance.setTeam(Team.BLUE);
+ break;
+ case 2:
+ _playerInstance.setTeam(Team.RED);
+ break;
+ }
+ }
+ else
+ {
+ _playerInstance.setTeam(Team.NONE);
+ }
+
+ _playerInstance.setCurrentCp(_playerInstance.getMaxCp());
+ _playerInstance.setCurrentHp(_playerInstance.getMaxHp());
+ _playerInstance.setCurrentMp(_playerInstance.getMaxMp());
+
+ _playerInstance.broadcastStatusUpdate();
+ _playerInstance.broadcastUserInfo();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTManager.java (working copy)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author HorridoJoho
+ */
+public class TvTManager
+{
+ protected static final Logger _log = Logger.getLogger(TvTManager.class.getName());
+
+ /** Task for event cycles<br> */
+ private TvTStartTask _task;
+
+ /**
+ * New instance only by getInstance()<br>
+ */
+ protected TvTManager()
+ {
+ if (Config.TVT_EVENT_ENABLED)
+ {
+ TvTEvent.init();
+
+ scheduleEventStart();
+ _log.info("TvTEventEngine[TvTManager.TvTManager()]: Started.");
+ }
+ else
+ {
+ _log.info("TvTEventEngine[TvTManager.TvTManager()]: Engine is disabled.");
+ }
+ }
+
+ /**
+ * Initialize new/Returns the one and only instance<br>
+ * <br>
+ * @return TvTManager<br>
+ */
+ public static TvTManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ /**
+ * Starts TvTStartTask
+ */
+ public void scheduleEventStart()
+ {
+ try
+ {
+ Calendar currentTime = Calendar.getInstance();
+ Calendar nextStartTime = null;
+ Calendar testStartTime = null;
+ for (String timeOfDay : Config.TVT_EVENT_INTERVAL)
+ {
+ // Creating a Calendar object from the specified interval value
+ testStartTime = Calendar.getInstance();
+ testStartTime.setLenient(true);
+ String[] splitTimeOfDay = timeOfDay.split(":");
+ testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+ testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+ // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
+ if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+ {
+ testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ // Check for the test date to be the minimum (smallest in the specified list)
+ if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
+ {
+ nextStartTime = testStartTime;
+ }
+ }
+ if (nextStartTime != null)
+ {
+ _task = new TvTStartTask(nextStartTime.getTimeInMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+ catch (Exception e)
+ {
+ _log.warning("TvTEventEngine[TvTManager.scheduleEventStart()]: Error figuring out a start time. Check TvTEventInterval in config file.");
+ }
+ }
+
+ /**
+ * Method to start participation
+ */
+ public void startReg()
+ {
+ if (!TvTEvent.startParticipation())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: Event was cancelled.");
+ _log.warning("TvTEventEngine[TvTManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: Registration opened for " + Config.TVT_EVENT_PARTICIPATION_TIME + " minute(s).");
+
+ // schedule registration end
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.TVT_EVENT_PARTICIPATION_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to start the fight
+ */
+ public void startEvent()
+ {
+ if (!TvTEvent.startFight())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: Event cancelled due to lack of Participation.");
+ _log.info("TvTEventEngine[TvTManager.run()]: Lack of registration, abort event.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: Teleporting participants to an arena in " + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.TVT_EVENT_RUNNING_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to end the event and reward
+ */
+ public void endEvent()
+ {
+ Broadcast.toAllOnlinePlayers(TvTEvent.calculateRewards());
+ TvTEvent.sysMsgToAllParticipants("TvT Event: Teleporting back to the registration npc in " + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ TvTEvent.stopFight();
+
+ scheduleEventStart();
+ }
+
+ public void skipDelay()
+ {
+ if (_task.nextRun.cancel(false))
+ {
+ _task.setStartTime(System.currentTimeMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Class for TvT cycles
+ */
+ class TvTStartTask implements Runnable
+ {
+ private long _startTime;
+ public ScheduledFuture<?> nextRun;
+
+ public TvTStartTask(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ public void setStartTime(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ @Override
+ public void run()
+ {
+ int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+
+ if (delay > 0)
+ {
+ announce(delay);
+ }
+
+ int nextMsg = 0;
+ if (delay > 3600)
+ {
+ nextMsg = delay - 3600;
+ }
+ else if (delay > 1800)
+ {
+ nextMsg = delay - 1800;
+ }
+ else if (delay > 900)
+ {
+ nextMsg = delay - 900;
+ }
+ else if (delay > 600)
+ {
+ nextMsg = delay - 600;
+ }
+ else if (delay > 300)
+ {
+ nextMsg = delay - 300;
+ }
+ else if (delay > 60)
+ {
+ nextMsg = delay - 60;
+ }
+ else if (delay > 5)
+ {
+ nextMsg = delay - 5;
+ }
+ else if (delay > 0)
+ {
+ nextMsg = delay;
+ }
+ else
+ {
+ // start
+ if (TvTEvent.isInactive())
+ {
+ startReg();
+ }
+ else if (TvTEvent.isParticipating())
+ {
+ startEvent();
+ }
+ else
+ {
+ endEvent();
+ }
+ }
+
+ if (delay > 0)
+ {
+ nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+ }
+ }
+
+ private void announce(long time)
+ {
+ if ((time >= 3600) && ((time % 3600) == 0))
+ {
+ if (TvTEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
+ }
+ else if (TvTEvent.isStarted())
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
+ }
+ }
+ else if (time >= 60)
+ {
+ if (TvTEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: " + (time / 60) + " minute(s) until registration is closed!");
+ }
+ else if (TvTEvent.isStarted())
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60) + " minute(s) until the event is finished!");
+ }
+ }
+ else
+ {
+ if (TvTEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: " + time + " second(s) until registration is closed!");
+ }
+ else if (TvTEvent.isStarted())
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: " + time + " second(s) until the event is finished!");
+ }
+ }
+ }
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final TvTManager _instance = new TvTManager();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEvent.java (working copy)
@@ -0,0 +1,1478 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.data.xml.impl.DoorData;
+import com.l2jserver.gameserver.data.xml.impl.NpcData;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.SkillData;
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.Location;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
+import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventStart;
+import com.l2jserver.gameserver.model.holders.SkillHolder;
+import com.l2jserver.gameserver.model.itemcontainer.Inventory;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.model.skills.CommonSkill;
+import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.network.NpcStringId;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
+import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.util.Util;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author HorridoJoho
+ */
+public class CTFEvent
+{
+ enum EventState
+ {
+ INACTIVE,
+ INACTIVATING,
+ PARTICIPATING,
+ STARTING,
+ STARTED,
+ REWARDING
+ }
+
+ protected static final Logger _log = Logger.getLogger(CTFEvent.class.getName());
+ /** html path **/
+ private static final String htmlPath = "data/scripts/custom/events/CTF/CTFManager/";
+ /** The teams of the CTFEvent<br> */
+ private static CTFEventTeam[] _teams = new CTFEventTeam[2];
+ /** The state of the CTFEvent<br> */
+ private static EventState _state = EventState.INACTIVE;
+ /** The spawn of the participation npc<br> */
+ private static L2Spawn _npcSpawn = null;
+ /** the npc instance of the participation npc<br> */
+ private static L2Npc _lastNpcSpawn = null;
+ /** The spawn of Team1 flag<br> */
+ private static L2Spawn _flag1Spawn = null;
+ /** the npc instance Team1 flag<br> */
+ private static L2Npc _lastFlag1Spawn = null;
+ /** The spawn of Team2 flag<br> */
+ private static L2Spawn _flag2Spawn = null;
+ /** the npc instance of Team2 flag<br> */
+ private static L2Npc _lastFlag2Spawn = null;
+ /** the Team 1 flag carrier L2PcInstance<br> */
+ private static L2PcInstance _team1Carrier = null;
+ /** the Team 2 flag carrier L2PcInstance<br> */
+ private static L2PcInstance _team2Carrier = null;
+ /** the Team 1 flag carrier right hand item<br> */
+ private static L2ItemInstance _team1CarrierRHand = null;
+ /** the Team 2 flag carrier right hand item<br> */
+ private static L2ItemInstance _team2CarrierRHand = null;
+ /** the Team 1 flag carrier left hand item<br> */
+ private static L2ItemInstance _team1CarrierLHand = null;
+ /** the Team 2 flag carrier left hand item<br> */
+ private static L2ItemInstance _team2CarrierLHand = null;
+ /** Instance id<br> */
+ private static int _CTFEventInstance = 0;
+
+ /**
+ * No instance of this class!<br>
+ */
+ private CTFEvent()
+ {
+ }
+
+ /**
+ * Teams initializing<br>
+ */
+ public static void init()
+ {
+ AntiFeedManager.getInstance().registerEvent(AntiFeedManager.CTF_ID);
+ _teams[0] = new CTFEventTeam(Config.CTF_EVENT_TEAM_1_NAME, Config.CTF_EVENT_TEAM_1_COORDINATES);
+ _teams[1] = new CTFEventTeam(Config.CTF_EVENT_TEAM_2_NAME, Config.CTF_EVENT_TEAM_2_COORDINATES);
+ }
+
+ /**
+ * Starts the participation of the CTFEvent<br>
+ * 1. Get L2NpcTemplate by Config.CTF_EVENT_PARTICIPATION_NPC_ID<br>
+ * 2. Try to spawn a new npc of it<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startParticipation()
+ {
+ try
+ {
+ _npcSpawn = new L2Spawn(Config.CTF_EVENT_PARTICIPATION_NPC_ID);
+
+ _npcSpawn.setX(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[0]);
+ _npcSpawn.setY(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[1]);
+ _npcSpawn.setZ(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ _npcSpawn.setAmount(1);
+ _npcSpawn.setHeading(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[3]);
+ _npcSpawn.setRespawnDelay(1);
+ // later no need to delete spawn from db, we don't store it (false)
+ SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
+ _npcSpawn.init();
+ _lastNpcSpawn = _npcSpawn.getLastSpawn();
+ _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
+ _lastNpcSpawn.setTitle("CTF Event Participation");
+ _lastNpcSpawn.isAggressive();
+ _lastNpcSpawn.decayMe();
+ _lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
+ _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "CTFEventEngine[CTFEvent.startParticipation()]: exception: " + e.getMessage(), e);
+ return false;
+ }
+
+ setState(EventState.PARTICIPATING);
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventRegistrationStart());
+ return true;
+ }
+
+ private static int highestLevelPcInstanceOf(Map<Integer, L2PcInstance> players)
+ {
+ int maxLevel = Integer.MIN_VALUE, maxLevelId = -1;
+ for (L2PcInstance player : players.values())
+ {
+ if (player.getLevel() >= maxLevel)
+ {
+ maxLevel = player.getLevel();
+ maxLevelId = player.getObjectId();
+ }
+ }
+ return maxLevelId;
+ }
+
+ /**
+ * Starts the CTFEvent fight<br>
+ * 1. Set state EventState.STARTING<br>
+ * 2. Close doors specified in configs<br>
+ * 3. Abort if not enought participants(return false)<br>
+ * 4. Set state EventState.STARTED<br>
+ * 5. Teleport all participants to team spot<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startFight()
+ {
+ // Set state to STARTING
+ setState(EventState.STARTING);
+
+ // Randomize and balance team distribution
+ Map<Integer, L2PcInstance> allParticipants = new FastMap<>();
+ allParticipants.putAll(_teams[0].getParticipatedPlayers());
+ allParticipants.putAll(_teams[1].getParticipatedPlayers());
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+
+ L2PcInstance player;
+ Iterator<L2PcInstance> iter;
+ if (needParticipationFee())
+ {
+ iter = allParticipants.values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!hasParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ int balance[] =
+ {
+ 0,
+ 0
+ }, priority = 0, highestLevelPlayerId;
+ L2PcInstance highestLevelPlayer;
+ // TODO: allParticipants should be sorted by level instead of using highestLevelPcInstanceOf for every fetch
+ while (!allParticipants.isEmpty())
+ {
+ // Priority team gets one player
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Exiting if no more players
+ if (allParticipants.isEmpty())
+ {
+ break;
+ }
+ // The other team gets one player
+ // TODO: Code not dry
+ priority = 1 - priority;
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Recalculating priority
+ priority = balance[0] > balance[1] ? 1 : 0;
+ }
+
+ // Check for enought participants
+ if ((_teams[0].getParticipatedPlayerCount() < Config.CTF_EVENT_MIN_PLAYERS_IN_TEAMS) || (_teams[1].getParticipatedPlayerCount() < Config.CTF_EVENT_MIN_PLAYERS_IN_TEAMS))
+ {
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Unspawn the event NPC
+ unSpawnNpc();
+ AntiFeedManager.getInstance().clear(AntiFeedManager.CTF_ID);
+ return false;
+ }
+
+ if (needParticipationFee())
+ {
+ iter = _teams[0].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ iter = _teams[1].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ if (Config.CTF_EVENT_IN_INSTANCE)
+ {
+ try
+ {
+ _CTFEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.CTF_EVENT_INSTANCE_FILE);
+ InstanceManager.getInstance().getInstance(_CTFEventInstance).setAllowSummon(false);
+ InstanceManager.getInstance().getInstance(_CTFEventInstance).setPvPInstance(true);
+ InstanceManager.getInstance().getInstance(_CTFEventInstance).setEmptyDestroyTime((Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L);
+ }
+ catch (Exception e)
+ {
+ _CTFEventInstance = 0;
+ _log.log(Level.WARNING, "CTFEventEngine[CTFEvent.createDynamicInstance]: exception: " + e.getMessage(), e);
+ }
+ }
+
+ // Spawn the flags
+ try
+ {
+ L2NpcTemplate tmpl = NpcData.getInstance().getTemplate(Config.CTF_EVENT_TEAM_1_HEADQUARTERS);
+ _flag1Spawn = new L2Spawn(tmpl);
+ _flag1Spawn.setX(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[0]);
+ _flag1Spawn.setY(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[1]);
+ _flag1Spawn.setZ(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[2]);
+ _flag1Spawn.setHeading(Util.calculateHeadingFrom(new Location(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[2]), new Location(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[2])));
+ _flag1Spawn.setInstanceId(_CTFEventInstance);
+ _flag1Spawn.setRespawnDelay(1);
+ _flag1Spawn.setAmount(1);
+ SpawnTable.getInstance().addNewSpawn(_flag1Spawn, false);
+ _flag1Spawn.init();
+ _lastFlag1Spawn = _flag1Spawn.getLastSpawn();
+ _lastFlag1Spawn.setCurrentHp(_lastFlag1Spawn.getMaxHp());
+ _lastFlag1Spawn.setTitle(Config.CTF_EVENT_TEAM_1_NAME);
+ _lastFlag1Spawn.isAggressive();
+ _lastFlag1Spawn.decayMe();
+ _lastFlag1Spawn.spawnMe(_flag1Spawn.getLastSpawn().getX(), _flag1Spawn.getLastSpawn().getY(), _flag1Spawn.getLastSpawn().getZ());
+ _lastFlag1Spawn.setIsInvul(true);
+ L2NpcTemplate tmpl2 = NpcData.getInstance().getTemplate(Config.CTF_EVENT_TEAM_2_HEADQUARTERS);
+ _flag2Spawn = new L2Spawn(tmpl2);
+ _flag2Spawn.setX(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[0]);
+ _flag2Spawn.setY(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[1]);
+ _flag2Spawn.setZ(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[2]);
+ _flag2Spawn.setHeading(Util.calculateHeadingFrom(new Location(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[2]), new Location(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[2])));
+ _flag2Spawn.setInstanceId(_CTFEventInstance);
+ _flag2Spawn.setRespawnDelay(1);
+ _flag2Spawn.setAmount(1);
+ SpawnTable.getInstance().addNewSpawn(_flag2Spawn, false);
+ _flag2Spawn.init();
+ _lastFlag2Spawn = _flag2Spawn.getLastSpawn();
+ _lastFlag2Spawn.setCurrentHp(_lastFlag2Spawn.getMaxHp());
+ _lastFlag2Spawn.setTitle(Config.CTF_EVENT_TEAM_2_NAME);
+ _lastFlag2Spawn.isAggressive();
+ _lastFlag2Spawn.decayMe();
+ _lastFlag2Spawn.spawnMe(_flag2Spawn.getLastSpawn().getX(), _flag2Spawn.getLastSpawn().getY(), _flag2Spawn.getLastSpawn().getZ());
+ _lastFlag2Spawn.setIsInvul(true);
+ _lastFlag2Spawn.setTarget(_lastFlag2Spawn);
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "CTFEventEngine[CTFEvent.spanwnFlags]: exception: " + e.getMessage(), e);
+ }
+
+ // Opens all doors specified in configs for CTF
+ openDoors(Config.CTF_DOORS_IDS_TO_OPEN);
+ // Closes all doors specified in configs for CTF
+ closeDoors(Config.CTF_DOORS_IDS_TO_CLOSE);
+ // Set state STARTED
+ setState(EventState.STARTED);
+
+ // Iterate over all teams
+ for (CTFEventTeam team : _teams)
+ {
+ // Iterate over all participated player instances in this team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ // Disable player revival.
+ playerInstance.setCanRevive(false);
+
+ // Disabled skills by config.
+ if (!Config.CTF_EVENT_RESTRICTED_SKILLS.isEmpty())
+ {
+ for (SkillHolder skill : Config.CTF_EVENT_RESTRICTED_SKILLS)
+ {
+ if (playerInstance.getSkills().values().contains(skill.getSkill()))
+ {
+ playerInstance.disableSkill(skill.getSkill(), ((Config.CTF_EVENT_RUNNING_TIME * 60) + Config.CTF_EVENT_RESPAWN_TELEPORT_DELAY) * 1000);
+ }
+ }
+ }
+
+ // Teleporter implements Runnable and starts itself
+ new CTFEventTeleporter(playerInstance, team.getCoordinates(), false, false);
+ }
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventStart());
+ return true;
+ }
+
+ /**
+ * Calculates the CTFEvent reward<br>
+ * 1. If both teams are at a tie(points equals), send it as system message to all participants, if one of the teams have 0 participants left online abort rewarding<br>
+ * 2. Wait till teams are not at a tie anymore<br>
+ * 3. Set state EvcentState.REWARDING<br>
+ * 4. Reward team with more points<br>
+ * 5. Show win html to wining team participants<br>
+ * <br>
+ * @return String: winning team name<br>
+ */
+ public static String calculateRewards()
+ {
+ if (_teams[0].getPoints() == _teams[1].getPoints())
+ {
+ // Check if one of the teams have no more players left
+ if ((_teams[0].getParticipatedPlayerCount() == 0) || (_teams[1].getParticipatedPlayerCount() == 0))
+ {
+ // set state to rewarding
+ setState(EventState.REWARDING);
+ // return here, the fight can't be completed
+ broadcastScreenMessage("CTF Event: No team won due to inactivity!", 8);
+ return "CTF Event: Event has ended. No team won due to inactivity!";
+ }
+
+ // Both teams have equals points
+ broadcastScreenMessage("CTF Event: Both teams have tied!", 8);
+ sysMsgToAllParticipants("CTF Event: Event has ended, both teams have tied.");
+ if (Config.CTF_REWARD_TEAM_TIE)
+ {
+ rewardTeam(_teams[0]);
+ rewardTeam(_teams[1]);
+ return "CTF Event: Event has ended with both teams tying.";
+ }
+ return "CTF Event: Event has ended with both teams tying.";
+ }
+
+ // Set state REWARDING so nobody can point anymore
+ setState(EventState.REWARDING);
+
+ // Get team which has more points
+ CTFEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1];
+ rewardTeam(team);
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventFinish());
+
+ broadcastScreenMessage("CTF Event: Team " + team.getName() + " wins!", 8);
+ return "CTF Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills.";
+ }
+
+ private static void rewardTeam(CTFEventTeam team)
+ {
+ // Iterate over all participated player instances of the winning team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance == null)
+ {
+ continue;
+ }
+
+ // Fireworks for rewarded player
+ playerInstance.broadcastPacket(new MagicSkillUse(playerInstance, playerInstance, CommonSkill.FIREWORK.getSkill().getId(), 1, 1, 1));
+
+ SystemMessage systemMessage = null;
+
+ // Iterate over all CTF event rewards
+ for (int[] reward : Config.CTF_EVENT_REWARDS)
+ {
+ PcInventory inv = playerInstance.getInventory();
+
+ // Check for stackable item, non stackabe items need to be added one by one
+ if (ItemTable.getInstance().getTemplate(reward[0]).isStackable())
+ {
+ inv.addItem("CTF Event", reward[0], reward[1], playerInstance, playerInstance);
+
+ if (reward[1] > 1)
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+ systemMessage.addItemName(reward[0]);
+ systemMessage.addLong(reward[1]);
+ }
+ else
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ }
+
+ playerInstance.sendPacket(systemMessage);
+ }
+ else
+ {
+ for (int i = 0; i < reward[1]; ++i)
+ {
+ inv.addItem("CTF Event", reward[0], 1, playerInstance, playerInstance);
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ playerInstance.sendPacket(systemMessage);
+ }
+ }
+ }
+
+ StatusUpdate statusUpdate = new StatusUpdate(playerInstance);
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, playerInstance.getCurrentLoad());
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Reward.html"));
+ playerInstance.sendPacket(statusUpdate);
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+
+ /**
+ * Stops the CTFEvent fight<br>
+ * 1. Set state EventState.INACTIVATING<br>
+ * 2. Remove CTF npc from world<br>
+ * 3. Open doors specified in configs<br>
+ * 4. Teleport all participants back to participation npc location<br>
+ * 5. Teams cleaning<br>
+ * 6. Set state EventState.INACTIVE<br>
+ */
+ public static void stopFight()
+ {
+ // Set state INACTIVATING
+ setState(EventState.INACTIVATING);
+ // Unspawn event npc
+ unSpawnNpc();
+ // Opens all doors specified in configs for CTF
+ openDoors(Config.CTF_DOORS_IDS_TO_CLOSE);
+ // Closes all doors specified in Configs for CTF
+ closeDoors(Config.CTF_DOORS_IDS_TO_OPEN);
+
+ // Reset flag carriers
+ if (_team1Carrier != null)
+ {
+ removeFlagCarrier(_team1Carrier);
+ }
+
+ if (_team2Carrier != null)
+ {
+ removeFlagCarrier(_team2Carrier);
+ }
+
+ // Iterate over all teams
+ for (CTFEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance != null)
+ {
+ // Enable player revival.
+ playerInstance.setCanRevive(true);
+
+ // Untransform player.
+ if (playerInstance.isTransformed())
+ {
+ playerInstance.untransform();
+ }
+
+ // Teleport back.
+ new CTFEventTeleporter(playerInstance, Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+ }
+
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.CTF_ID);
+ }
+
+ /**
+ * Adds a player to a CTFEvent team<br>
+ * 1. Calculate the id of the team in which the player should be added<br>
+ * 2. Add the player to the calculated team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static synchronized boolean addParticipant(L2PcInstance playerInstance)
+ {
+ // Check for nullpoitner
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ byte teamId = 0;
+
+ // Check to which team the player should be added
+ if (_teams[0].getParticipatedPlayerCount() == _teams[1].getParticipatedPlayerCount())
+ {
+ teamId = (byte) (Rnd.get(2));
+ }
+ else
+ {
+ teamId = (byte) (_teams[0].getParticipatedPlayerCount() > _teams[1].getParticipatedPlayerCount() ? 1 : 0);
+ }
+ playerInstance.addEventListener(new CTFEventListener(playerInstance));
+ return _teams[teamId].addPlayer(playerInstance);
+ }
+
+ /**
+ * Removes a CTFEvent player from it's team<br>
+ * 1. Get team id of the player<br>
+ * 2. Remove player from it's team<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if success, otherwise false
+ */
+ public static boolean removeParticipant(int playerObjectId)
+ {
+ // Get the teamId of the player
+ byte teamId = getParticipantTeamId(playerObjectId);
+
+ // Check if the player is participant
+ if (teamId != -1)
+ {
+ // Remove the player from team
+ _teams[teamId].removePlayer(playerObjectId);
+
+ final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
+ if (player != null)
+ {
+ player.removeEventListener(CTFEventListener.class);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean needParticipationFee()
+ {
+ return (Config.CTF_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.CTF_EVENT_PARTICIPATION_FEE[1] != 0);
+ }
+
+ public static boolean hasParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.getInventory().getInventoryItemCount(Config.CTF_EVENT_PARTICIPATION_FEE[0], -1) >= Config.CTF_EVENT_PARTICIPATION_FEE[1];
+ }
+
+ public static boolean payParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.destroyItemByItemId("CTF Participation Fee", Config.CTF_EVENT_PARTICIPATION_FEE[0], Config.CTF_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
+ }
+
+ public static String getParticipationFee()
+ {
+ int itemId = Config.CTF_EVENT_PARTICIPATION_FEE[0];
+ int itemNum = Config.CTF_EVENT_PARTICIPATION_FEE[1];
+
+ if ((itemId == 0) || (itemNum == 0))
+ {
+ return "-";
+ }
+
+ return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
+ }
+
+ /**
+ * Send a SystemMessage to all participated players<br>
+ * 1. Send the message to all players of team number one<br>
+ * 2. Send the message to all players of team number two<br>
+ * <br>
+ * @param message as String<br>
+ */
+ public static void sysMsgToAllParticipants(String message)
+ {
+ for (L2PcInstance playerInstance : _teams[0].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+
+ for (L2PcInstance playerInstance : _teams[1].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+ }
+
+ private static L2DoorInstance getDoor(int doorId)
+ {
+ L2DoorInstance door = null;
+ if (_CTFEventInstance <= 0)
+ {
+ door = DoorData.getInstance().getDoor(doorId);
+ }
+ else
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(_CTFEventInstance);
+ if (inst != null)
+ {
+ door = inst.getDoor(doorId);
+ }
+ }
+ return door;
+ }
+
+ /**
+ * Close doors specified in configs
+ * @param doors
+ */
+ private static void closeDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.closeMe();
+ }
+ }
+ }
+
+ /**
+ * Open doors specified in configs
+ * @param doors
+ */
+ private static void openDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.openMe();
+ }
+ }
+ }
+
+ /**
+ * UnSpawns the CTFEvent npc
+ */
+ private static void unSpawnNpc()
+ {
+ // Delete the npc
+ _lastNpcSpawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
+
+ // Stop respawning of the npc
+ _npcSpawn.stopRespawn();
+ _npcSpawn = null;
+ _lastNpcSpawn = null;
+
+ // Remove flags
+ if (_lastFlag1Spawn != null)
+ {
+ _lastFlag1Spawn.deleteMe();
+ _lastFlag2Spawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastFlag1Spawn.getSpawn(), false);
+ SpawnTable.getInstance().deleteSpawn(_lastFlag2Spawn.getSpawn(), false);
+ _flag1Spawn.stopRespawn();
+ _flag2Spawn.stopRespawn();
+ _flag1Spawn = null;
+ _flag2Spawn = null;
+ _lastFlag1Spawn = null;
+ _lastFlag2Spawn = null;
+ }
+ }
+
+ /**
+ * Called when a player logs in<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogin(L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || (!isStarting() && !isStarted()))
+ {
+ return;
+ }
+
+ byte teamId = getParticipantTeamId(playerInstance.getObjectId());
+
+ if (teamId == -1)
+ {
+ return;
+ }
+
+ _teams[teamId].addPlayer(playerInstance);
+ new CTFEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
+ }
+
+ /**
+ * Called when a player logs out<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogout(L2PcInstance playerInstance)
+ {
+ if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
+ {
+ if (removeParticipant(playerInstance.getObjectId()))
+ {
+ playerInstance.setXYZInvisible((Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[0] + Rnd.get(101)) - 50, (Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[1] + Rnd.get(101)) - 50, Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ }
+ }
+ }
+
+ /**
+ * Called on every onAction in L2PcIstance<br>
+ * <br>
+ * @param playerInstance
+ * @param targetedPlayerObjectId
+ * @return boolean: true if player is allowed to target, otherwise false
+ */
+ public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
+ {
+ if ((playerInstance == null) || !isStarted())
+ {
+ return true;
+ }
+
+ if (playerInstance.isGM())
+ {
+ return true;
+ }
+
+ byte playerTeamId = getParticipantTeamId(playerInstance.getObjectId());
+ byte targetedPlayerTeamId = getParticipantTeamId(targetedPlayerObjectId);
+
+ if (((playerTeamId != -1) && (targetedPlayerTeamId == -1)) || ((playerTeamId == -1) && (targetedPlayerTeamId != -1)))
+ {
+ return false;
+ }
+
+ if ((playerTeamId != -1) && (targetedPlayerTeamId != -1) && (playerTeamId == targetedPlayerTeamId) && (playerInstance.getObjectId() != targetedPlayerObjectId) && !Config.CTF_EVENT_TARGET_TEAM_MEMBERS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every scroll use<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use scroll, otherwise false
+ */
+ public static boolean onScrollUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.CTF_EVENT_SCROLL_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every potion use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use potions, otherwise false
+ */
+ public static boolean onPotionUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.CTF_EVENT_POTIONS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every escape use(thanks to nbd)
+ * @param playerObjectId
+ * @return boolean: true if player is not in CTF event, otherwise false
+ */
+ public static boolean onEscapeUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every summon item use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to summon by item, otherwise false
+ */
+ public static boolean onItemSummon(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.CTF_EVENT_SUMMON_BY_ITEM_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is called when a player is killed<br>
+ * <br>
+ * @param killerCharacter as L2Character<br>
+ * @param killedPlayerInstance as L2PcInstance<br>
+ */
+ public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
+ {
+ if ((killedPlayerInstance == null) || !isStarted())
+ {
+ return;
+ }
+
+ byte killedTeamId = getParticipantTeamId(killedPlayerInstance.getObjectId());
+
+ if (killedTeamId == -1)
+ {
+ return;
+ }
+
+ new CTFEventTeleporter(killedPlayerInstance, _teams[killedTeamId].getCoordinates(), false, false);
+
+ if (killerCharacter == null)
+ {
+ return;
+ }
+
+ L2PcInstance killerPlayerInstance = null;
+
+ if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
+ {
+ killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
+
+ if (killerPlayerInstance == null)
+ {
+ return;
+ }
+ }
+ else if (killerCharacter instanceof L2PcInstance)
+ {
+ killerPlayerInstance = (L2PcInstance) killerCharacter;
+ }
+ else
+ {
+ return;
+ }
+
+ byte killerTeamId = getParticipantTeamId(killerPlayerInstance.getObjectId());
+
+ if ((killerTeamId != -1) && (killedTeamId != -1) && (killerTeamId != killedTeamId))
+ {
+ CTFEventTeam killerTeam = _teams[killerTeamId];
+
+ CreatureSay cs = new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!");
+
+ for (L2PcInstance playerInstance : _teams[killerTeamId].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendPacket(cs);
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventKill(killerPlayerInstance, killedPlayerInstance, killerTeam));
+ }
+
+ if (playerIsCarrier(killedPlayerInstance))
+ {
+ broadcastScreenMessage(killerCharacter.getName() + " has killed " + killedPlayerInstance.getName() + "!", 7);
+ }
+ }
+
+ /**
+ * Called on Appearing packet received (player finished teleporting)
+ * @param playerInstance
+ */
+ public static void onTeleported(L2PcInstance playerInstance)
+ {
+ if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
+ {
+ return;
+ }
+
+ if (playerInstance.isMageClass())
+ {
+ if ((Config.CTF_EVENT_MAGE_BUFFS != null) && !Config.CTF_EVENT_MAGE_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.CTF_EVENT_MAGE_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((Config.CTF_EVENT_FIGHTER_BUFFS != null) && !Config.CTF_EVENT_FIGHTER_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.CTF_EVENT_FIGHTER_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param source
+ * @param target
+ * @param skill
+ * @return true if player valid for skill
+ */
+ public static final boolean checkForCTFSkill(L2PcInstance source, L2PcInstance target, Skill skill)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ // CTF is started
+ final int sourcePlayerId = source.getObjectId();
+ final int targetPlayerId = target.getObjectId();
+ final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
+ final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
+
+ // both players not participating
+ if (!isSourceParticipant && !isTargetParticipant)
+ {
+ return true;
+ }
+ // one player not participating
+ if (!(isSourceParticipant && isTargetParticipant))
+ {
+ return false;
+ }
+ // players in the different teams ?
+ if (getParticipantTeamId(sourcePlayerId) != getParticipantTeamId(targetPlayerId))
+ {
+ if (!skill.isBad())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Sets the CTFEvent state<br>
+ * <br>
+ * @param state as EventState<br>
+ */
+ private static void setState(EventState state)
+ {
+ synchronized (_state)
+ {
+ _state = state;
+ }
+ }
+
+ /**
+ * Is CTFEvent inactive?<br>
+ * <br>
+ * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
+ */
+ public static boolean isInactive()
+ {
+ boolean isInactive;
+
+ synchronized (_state)
+ {
+ isInactive = _state == EventState.INACTIVE;
+ }
+
+ return isInactive;
+ }
+
+ /**
+ * Is CTFEvent in inactivating?<br>
+ * <br>
+ * @return boolean: true if event is in inactivating progress, otherwise false<br>
+ */
+ public static boolean isInactivating()
+ {
+ boolean isInactivating;
+
+ synchronized (_state)
+ {
+ isInactivating = _state == EventState.INACTIVATING;
+ }
+
+ return isInactivating;
+ }
+
+ /**
+ * Is CTFEvent in participation?<br>
+ * <br>
+ * @return boolean: true if event is in participation progress, otherwise false<br>
+ */
+ public static boolean isParticipating()
+ {
+ boolean isParticipating;
+
+ synchronized (_state)
+ {
+ isParticipating = _state == EventState.PARTICIPATING;
+ }
+
+ return isParticipating;
+ }
+
+ /**
+ * Is CTFEvent starting?<br>
+ * <br>
+ * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
+ */
+ public static boolean isStarting()
+ {
+ boolean isStarting;
+
+ synchronized (_state)
+ {
+ isStarting = _state == EventState.STARTING;
+ }
+
+ return isStarting;
+ }
+
+ /**
+ * Is CTFEvent started?<br>
+ * <br>
+ * @return boolean: true if event is started, otherwise false<br>
+ */
+ public static boolean isStarted()
+ {
+ boolean isStarted;
+
+ synchronized (_state)
+ {
+ isStarted = _state == EventState.STARTED;
+ }
+
+ return isStarted;
+ }
+
+ /**
+ * Is CTFEvent rewarding?<br>
+ * <br>
+ * @return boolean: true if event is currently rewarding, otherwise false<br>
+ */
+ public static boolean isRewarding()
+ {
+ boolean isRewarding;
+
+ synchronized (_state)
+ {
+ isRewarding = _state == EventState.REWARDING;
+ }
+
+ return isRewarding;
+ }
+
+ /**
+ * Returns the team id of a player, if player is not participant it returns -1
+ * @param playerObjectId
+ * @return byte: team name of the given playerName, if not in event -1
+ */
+ public static byte getParticipantTeamId(int playerObjectId)
+ {
+ return (byte) (_teams[0].containsPlayer(playerObjectId) ? 0 : (_teams[1].containsPlayer(playerObjectId) ? 1 : -1));
+ }
+
+ /**
+ * Returns the team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return CTFEventTeam: team of the given playerObjectId, if not in event null
+ */
+ public static CTFEventTeam getParticipantTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[0] : (_teams[1].containsPlayer(playerObjectId) ? _teams[1] : null));
+ }
+
+ /**
+ * Returns the enemy team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return CTFEventTeam: enemy team of the given playerObjectId, if not in event null
+ */
+ public static CTFEventTeam getParticipantEnemyTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[1] : (_teams[1].containsPlayer(playerObjectId) ? _teams[0] : null));
+ }
+
+ /**
+ * Returns the team coordinates in which the player is in, if player is not in a team return null
+ * @param playerObjectId
+ * @return int[]: coordinates of teams, 2 elements, index 0 for team 1 and index 1 for team 2
+ */
+ public static int[] getParticipantTeamCoordinates(int playerObjectId)
+ {
+ return _teams[0].containsPlayer(playerObjectId) ? _teams[0].getCoordinates() : (_teams[1].containsPlayer(playerObjectId) ? _teams[1].getCoordinates() : null);
+ }
+
+ /**
+ * Is given player participant of the event?
+ * @param playerObjectId
+ * @return boolean: true if player is participant, ohterwise false
+ */
+ public static boolean isPlayerParticipant(int playerObjectId)
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return false;
+ }
+
+ return _teams[0].containsPlayer(playerObjectId) || _teams[1].containsPlayer(playerObjectId);
+ }
+
+ /**
+ * Returns participated player count<br>
+ * <br>
+ * @return int: amount of players registered in the event<br>
+ */
+ public static int getParticipatedPlayersCount()
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return 0;
+ }
+
+ return _teams[0].getParticipatedPlayerCount() + _teams[1].getParticipatedPlayerCount();
+ }
+
+ /**
+ * Returns teams names<br>
+ * <br>
+ * @return String[]: names of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static String[] getTeamNames()
+ {
+ return new String[]
+ {
+ _teams[0].getName(),
+ _teams[1].getName()
+ };
+ }
+
+ /**
+ * Returns player count of both teams<br>
+ * <br>
+ * @return int[]: player count of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPlayerCounts()
+ {
+ return new int[]
+ {
+ _teams[0].getParticipatedPlayerCount(),
+ _teams[1].getParticipatedPlayerCount()
+ };
+ }
+
+ /**
+ * Returns points count of both teams
+ * @return int[]: points of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPoints()
+ {
+ return new int[]
+ {
+ _teams[0].getPoints(),
+ _teams[1].getPoints()
+ };
+ }
+
+ /**
+ * Used when carrier scores, dies or game ends
+ * @param player L2PcInstance
+ */
+ public static void removeFlagCarrier(L2PcInstance player)
+ {
+ // un-equip - destroy flag
+ player.getInventory().unEquipItemInSlot(Inventory.PAPERDOLL_RHAND);
+ player.destroyItemByItemId("ctf", getEnemyTeamFlagId(player), 1, player, false);
+
+ // unblock inventory
+ player.getInventory().unblock();
+
+ // re-equip player items
+ final L2ItemInstance carrierRHand = _teams[0].containsPlayer(player.getObjectId()) ? _team1CarrierRHand : _team2CarrierRHand;
+ final L2ItemInstance carrierLHand = _teams[0].containsPlayer(player.getObjectId()) ? _team1CarrierLHand : _team2CarrierLHand;
+ if ((carrierRHand != null) && (player.getInventory().getItemByItemId(carrierRHand.getId()) != null))
+ {
+ player.getInventory().equipItem(carrierRHand);
+ }
+ if ((carrierLHand != null) && (player.getInventory().getItemByItemId(carrierLHand.getId()) != null))
+ {
+ player.getInventory().equipItem(carrierLHand);
+ }
+ setCarrierUnequippedWeapons(player, null, null);
+
+ // flag carrier removal
+ if (_teams[0].containsPlayer(player.getObjectId()))
+ {
+ _team1Carrier = null;
+ }
+ else
+ {
+ _team2Carrier = null;
+ }
+
+ // show re-equipped weapons
+ player.broadcastUserInfo();
+ }
+
+ /**
+ * Assign the Ctf team flag carrier
+ * @param player L2PcInstance
+ */
+ public static void setTeamCarrier(L2PcInstance player)
+ {
+ if (_teams[0].containsPlayer(player.getObjectId()))
+ {
+ _team1Carrier = player;
+ }
+ else
+ {
+ _team2Carrier = player;
+ }
+ }
+
+ /**
+ * @param player L2PcInstance
+ * @return the team carrier L2PcInstance
+ */
+ public static L2PcInstance getTeamCarrier(L2PcInstance player)
+ {
+ // check if team carrier has disconnected
+ if (((_teams[0].containsPlayer(player.getObjectId()) == true) && (_team1Carrier != null) && (!_team1Carrier.isOnline() || (_team1Carrier.getInstanceId() != _CTFEventInstance))) || ((_teams[1].containsPlayer(player.getObjectId()) == true) && (_team2Carrier != null) && (!_team2Carrier.isOnline() || (_team2Carrier.getInstanceId() != _CTFEventInstance))))
+ {
+ player.destroyItemByItemId("ctf", getEnemyTeamFlagId(player), 1, player, false);
+ return null;
+ }
+
+ // return team carrier
+ return (_teams[0].containsPlayer(player.getObjectId()) ? _team1Carrier : _team2Carrier);
+ }
+
+ /**
+ * @param player L2PcInstance
+ * @return the enemy team carrier L2PcInstance
+ */
+ public static L2PcInstance getEnemyCarrier(L2PcInstance player)
+ {
+ // check if enemy carrier has disconnected
+ if (((_teams[0].containsPlayer(player.getObjectId()) == true) && (_team2Carrier != null) && (!_team2Carrier.isOnline() || (_team2Carrier.getInstanceId() != _CTFEventInstance))) || ((_teams[1].containsPlayer(player.getObjectId()) == true) && (_team1Carrier != null) && (!_team1Carrier.isOnline() || (_team1Carrier.getInstanceId() != _CTFEventInstance))))
+ {
+ player.destroyItemByItemId("ctf", getEnemyTeamFlagId(player), 1, player, false);
+ return null;
+ }
+
+ // return enemy carrier
+ return (_teams[0].containsPlayer(player.getObjectId()) ? _team2Carrier : _team1Carrier);
+ }
+
+ /**
+ * @param player L2PcInstance
+ * @return true if player is the carrier
+ */
+ public static boolean playerIsCarrier(L2PcInstance player)
+ {
+ return ((player == _team1Carrier) || (player == _team2Carrier)) ? true : false;
+ }
+
+ /**
+ * @param player L2ItemInstance
+ * @return int The enemy flag id
+ */
+ public static int getEnemyTeamFlagId(L2PcInstance player)
+ {
+ return (_teams[0].containsPlayer(player.getObjectId()) ? Config.CTF_EVENT_TEAM_2_FLAG : Config.CTF_EVENT_TEAM_1_FLAG);
+ }
+
+ /**
+ * Stores the carrier equipped weapons
+ * @param player L2PcInstance
+ * @param itemRight L2ItemInstance
+ * @param itemLeft L2ItemInstance
+ */
+ public static void setCarrierUnequippedWeapons(L2PcInstance player, L2ItemInstance itemRight, L2ItemInstance itemLeft)
+ {
+ if (_teams[0].containsPlayer(player.getObjectId()))
+ {
+ _team1CarrierRHand = itemRight;
+ _team1CarrierLHand = itemLeft;
+ }
+ else
+ {
+ _team2CarrierRHand = itemRight;
+ _team2CarrierLHand = itemLeft;
+ }
+ }
+
+ /**
+ * Broadcast a message to all participant screens
+ * @param message String
+ * @param duration int (in seconds)
+ */
+ public static void broadcastScreenMessage(String message, int duration)
+ {
+ for (CTFEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if ((playerInstance != null) && (playerInstance.getInstanceId() == _CTFEventInstance))
+ {
+ playerInstance.sendPacket(new ExShowScreenMessage(message, duration * 1000));
+ }
+ }
+ }
+ }
+
+ /**
+ * Broadcast score to all participants
+ */
+ public static void broadcastScoreMessage()
+ {
+ final String score = Config.CTF_EVENT_TEAM_1_NAME + ": " + _teams[0].getPoints() + " - " + Config.CTF_EVENT_TEAM_2_NAME + ": " + _teams[1].getPoints();
+
+ for (CTFEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if ((playerInstance != null) && (playerInstance.getInstanceId() == _CTFEventInstance))
+ {
+ playerInstance.sendPacket(new ExShowScreenMessage(1, -1, 8, 0, 1, 0, 0, false, 15000, true, score, NpcStringId.NONE, null));
+ }
+ }
+ }
+ }
+
+ public static int getCTFEventInstance()
+ {
+ return _CTFEventInstance;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventListener.java (working copy)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class CTFEventListener implements IEventListener
+{
+ private final L2PcInstance _player;
+
+ protected CTFEventListener(L2PcInstance player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return CTFEvent.isStarted() && CTFEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ @Override
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventPlayer.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventPlayer.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventPlayer.java (working copy)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class CTFEventPlayer
+{
+ private final L2PcInstance _player;
+
+ protected CTFEventPlayer(L2PcInstance player)
+ {
+ _player = player;
+
+ }
+
+ public boolean isOnEvent()
+ {
+ return CTFEvent.isStarted() && CTFEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author HorridoJoho
+ */
+public class CTFEventTeam
+{
+ /** The name of the team<br> */
+ private final String _name;
+ /** The team spot coordinated<br> */
+ private int[] _coordinates = new int[3];
+ /** The points of the team<br> */
+ private short _points;
+ /** Name and instance of all participated players in FastMap<br> */
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ /**
+ * C'tor initialize the team<br>
+ * <br>
+ * @param name as String<br>
+ * @param coordinates as int[]<br>
+ */
+ public CTFEventTeam(String name, int[] coordinates)
+ {
+ _name = name;
+ _coordinates = coordinates;
+ _points = 0;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes a player from the team
+ * @param playerObjectId
+ */
+ public void removePlayer(int playerObjectId)
+ {
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.remove(playerObjectId);
+ }
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * Returns the name of the team<br>
+ * <br>
+ * @return String: name of the team<br>
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the coordinates of the team spot<br>
+ * <br>
+ * @return int[]: team coordinates<br>
+ */
+ public int[] getCoordinates()
+ {
+ return _coordinates;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeleporter.java (working copy)
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.Team;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Duel;
+import com.l2jserver.util.Rnd;
+
+public class CTFEventTeleporter implements Runnable
+{
+ /** The instance of the player to teleport */
+ private L2PcInstance _playerInstance = null;
+ /** Coordinates of the spot to teleport to */
+ private int[] _coordinates = new int[3];
+ /** Admin removed this player from event */
+ private boolean _adminRemove = false;
+
+ /**
+ * Initialize the teleporter and start the delayed task.
+ * @param playerInstance
+ * @param coordinates
+ * @param fastSchedule
+ * @param adminRemove
+ */
+ public CTFEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
+ {
+ _playerInstance = playerInstance;
+ _coordinates = coordinates;
+ _adminRemove = adminRemove;
+
+ long delay = (CTFEvent.isStarted() ? Config.CTF_EVENT_RESPAWN_TELEPORT_DELAY : Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
+
+ ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
+ }
+
+ /**
+ * The task method to teleport the player<br>
+ * 1. Unsummon pet if there is one<br>
+ * 2. Remove all effects<br>
+ * 3. Revive and full heal the player<br>
+ * 4. Teleport the player<br>
+ * 5. Broadcast status and user info
+ */
+ @Override
+ public void run()
+ {
+ if (_playerInstance == null)
+ {
+ return;
+ }
+
+ L2Summon summon = _playerInstance.getSummon();
+
+ if (summon != null)
+ {
+ summon.unSummon(_playerInstance);
+ }
+
+ if ((Config.CTF_EVENT_EFFECTS_REMOVAL == 0) || ((Config.CTF_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
+ {
+ _playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
+ }
+
+ if (_playerInstance.isInDuel())
+ {
+ _playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
+ }
+
+ int CTFInstance = CTFEvent.getCTFEventInstance();
+ if (CTFInstance != 0)
+ {
+ if (CTFEvent.isStarted() && !_adminRemove)
+ {
+ _playerInstance.setInstanceId(CTFInstance);
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+
+ _playerInstance.doRevive();
+
+ _playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
+
+ // Reset flag carrier
+ if (CTFEvent.playerIsCarrier(_playerInstance))
+ {
+ CTFEvent.removeFlagCarrier(_playerInstance);
+ CTFEvent.broadcastScreenMessage("The " + CTFEvent.getParticipantEnemyTeam(_playerInstance.getObjectId()).getName() + " flag has been returned!", 5);
+ }
+
+ if (CTFEvent.isStarted() && !_adminRemove)
+ {
+ int teamId = CTFEvent.getParticipantTeamId(_playerInstance.getObjectId()) + 1;
+ switch (teamId)
+ {
+ case 0:
+ _playerInstance.setTeam(Team.NONE);
+ break;
+ case 1:
+ _playerInstance.setTeam(Team.BLUE);
+ break;
+ case 2:
+ _playerInstance.setTeam(Team.RED);
+ break;
+ }
+ }
+ else
+ {
+ _playerInstance.setTeam(Team.NONE);
+ }
+
+ _playerInstance.setCurrentCp(_playerInstance.getMaxCp());
+ _playerInstance.setCurrentHp(_playerInstance.getMaxHp());
+ _playerInstance.setCurrentMp(_playerInstance.getMaxMp());
+
+ _playerInstance.broadcastStatusUpdate();
+ _playerInstance.broadcastUserInfo();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFManager.java (working copy)
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author HorridoJoho
+ */
+public class CTFManager
+{
+ protected static final Logger _log = Logger.getLogger(CTFManager.class.getName());
+
+ /** Task for event cycles<br> */
+ private CTFStartTask _task;
+
+ /**
+ * New instance only by getInstance()<br>
+ */
+ protected CTFManager()
+ {
+ if (Config.CTF_EVENT_ENABLED)
+ {
+ // Cannot start if both teams have same name
+ if (Config.CTF_EVENT_TEAM_1_NAME != Config.CTF_EVENT_TEAM_2_NAME)
+ {
+ CTFEvent.init();
+
+ scheduleEventStart();
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Started.");
+ }
+ else
+ {
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Engine uninitiated. Cannot start if both teams have same name!");
+ }
+ }
+ else
+ {
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Engine is disabled.");
+ }
+ }
+
+ /**
+ * Initialize new/Returns the one and only instance<br>
+ * <br>
+ * @return CTFManager<br>
+ */
+ public static CTFManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ /**
+ * Starts CTFStartTask
+ */
+ public void scheduleEventStart()
+ {
+ try
+ {
+ Calendar currentTime = Calendar.getInstance();
+ Calendar nextStartTime = null;
+ Calendar testStartTime = null;
+ for (String timeOfDay : Config.CTF_EVENT_INTERVAL)
+ {
+ // Creating a Calendar object from the specified interval value
+ testStartTime = Calendar.getInstance();
+ testStartTime.setLenient(true);
+ String[] splitTimeOfDay = timeOfDay.split(":");
+ testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+ testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+ // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
+ if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+ {
+ testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ // Check for the test date to be the minimum (smallest in the specified list)
+ if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
+ {
+ nextStartTime = testStartTime;
+ }
+ }
+ if (nextStartTime != null)
+ {
+ _task = new CTFStartTask(nextStartTime.getTimeInMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+ catch (Exception e)
+ {
+ _log.warning("CTFEventEngine[CTFManager.scheduleEventStart()]: Error figuring out a start time. Check CTFEventInterval in config file.");
+ }
+ }
+
+ /**
+ * Method to start participation
+ */
+ public void startReg()
+ {
+ if (!CTFEvent.startParticipation())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: Event was cancelled.");
+ _log.warning("CTFEventEngine[CTFManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: Registration opened for " + Config.CTF_EVENT_PARTICIPATION_TIME + " minute(s).");
+
+ // schedule registration end
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.CTF_EVENT_PARTICIPATION_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to start the fight
+ */
+ public void startEvent()
+ {
+ if (!CTFEvent.startFight())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: Event cancelled due to lack of Participation.");
+ _log.info("CTFEventEngine[CTFManager.run()]: Lack of registration, abort event.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: Teleporting participants to an arena in " + Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.CTF_EVENT_RUNNING_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to end the event and reward
+ */
+ public void endEvent()
+ {
+ Broadcast.toAllOnlinePlayers(CTFEvent.calculateRewards());
+ CTFEvent.sysMsgToAllParticipants("CTF Event: Teleporting back to the registration npc in " + Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ CTFEvent.stopFight();
+
+ scheduleEventStart();
+ }
+
+ public void skipDelay()
+ {
+ if (_task.nextRun.cancel(false))
+ {
+ _task.setStartTime(System.currentTimeMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Class for CTF cycles
+ */
+ class CTFStartTask implements Runnable
+ {
+ private long _startTime;
+ public ScheduledFuture<?> nextRun;
+
+ public CTFStartTask(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ public void setStartTime(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ @Override
+ public void run()
+ {
+ int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+
+ if (delay > 0)
+ {
+ announce(delay);
+ }
+
+ int nextMsg = 0;
+ if (delay > 3600)
+ {
+ nextMsg = delay - 3600;
+ }
+ else if (delay > 1800)
+ {
+ nextMsg = delay - 1800;
+ }
+ else if (delay > 900)
+ {
+ nextMsg = delay - 900;
+ }
+ else if (delay > 600)
+ {
+ nextMsg = delay - 600;
+ }
+ else if (delay > 300)
+ {
+ nextMsg = delay - 300;
+ }
+ else if (delay > 60)
+ {
+ nextMsg = delay - 60;
+ }
+ else if (delay > 5)
+ {
+ nextMsg = delay - 5;
+ }
+ else if (delay > 0)
+ {
+ nextMsg = delay;
+ }
+ else
+ {
+ // start
+ if (CTFEvent.isInactive())
+ {
+ startReg();
+ }
+ else if (CTFEvent.isParticipating())
+ {
+ startEvent();
+ }
+ else
+ {
+ endEvent();
+ }
+ }
+
+ if (delay > 0)
+ {
+ nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+ }
+ }
+
+ private void announce(long time)
+ {
+ if ((time >= 3600) && ((time % 3600) == 0))
+ {
+ if (CTFEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
+ }
+ else if (CTFEvent.isStarted())
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
+ }
+ }
+ else if (time >= 60)
+ {
+ if (CTFEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: " + (time / 60) + " minute(s) until registration is closed!");
+ }
+ else if (CTFEvent.isStarted())
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: " + (time / 60) + " minute(s) until the event is finished!");
+ }
+ }
+ else
+ {
+ if (CTFEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: " + time + " second(s) until registration is closed!");
+ }
+ else if (CTFEvent.isStarted())
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: " + time + " second(s) until the event is finished!");
+ }
+ }
+ }
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final CTFManager _instance = new CTFManager();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEvent.java (working copy)
@@ -0,0 +1,1478 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.data.xml.impl.DoorData;
+import com.l2jserver.gameserver.data.xml.impl.NpcData;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.SkillData;
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.Location;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
+import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventStart;
+import com.l2jserver.gameserver.model.holders.SkillHolder;
+import com.l2jserver.gameserver.model.itemcontainer.Inventory;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.model.skills.CommonSkill;
+import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.network.NpcStringId;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
+import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.util.Util;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author HorridoJoho
+ */
+public class CTFEvent
+{
+ enum EventState
+ {
+ INACTIVE,
+ INACTIVATING,
+ PARTICIPATING,
+ STARTING,
+ STARTED,
+ REWARDING
+ }
+
+ protected static final Logger _log = Logger.getLogger(CTFEvent.class.getName());
+ /** html path **/
+ private static final String htmlPath = "data/scripts/custom/events/CTF/CTFManager/";
+ /** The teams of the CTFEvent<br> */
+ private static CTFEventTeam[] _teams = new CTFEventTeam[2];
+ /** The state of the CTFEvent<br> */
+ private static EventState _state = EventState.INACTIVE;
+ /** The spawn of the participation npc<br> */
+ private static L2Spawn _npcSpawn = null;
+ /** the npc instance of the participation npc<br> */
+ private static L2Npc _lastNpcSpawn = null;
+ /** The spawn of Team1 flag<br> */
+ private static L2Spawn _flag1Spawn = null;
+ /** the npc instance Team1 flag<br> */
+ private static L2Npc _lastFlag1Spawn = null;
+ /** The spawn of Team2 flag<br> */
+ private static L2Spawn _flag2Spawn = null;
+ /** the npc instance of Team2 flag<br> */
+ private static L2Npc _lastFlag2Spawn = null;
+ /** the Team 1 flag carrier L2PcInstance<br> */
+ private static L2PcInstance _team1Carrier = null;
+ /** the Team 2 flag carrier L2PcInstance<br> */
+ private static L2PcInstance _team2Carrier = null;
+ /** the Team 1 flag carrier right hand item<br> */
+ private static L2ItemInstance _team1CarrierRHand = null;
+ /** the Team 2 flag carrier right hand item<br> */
+ private static L2ItemInstance _team2CarrierRHand = null;
+ /** the Team 1 flag carrier left hand item<br> */
+ private static L2ItemInstance _team1CarrierLHand = null;
+ /** the Team 2 flag carrier left hand item<br> */
+ private static L2ItemInstance _team2CarrierLHand = null;
+ /** Instance id<br> */
+ private static int _CTFEventInstance = 0;
+
+ /**
+ * No instance of this class!<br>
+ */
+ private CTFEvent()
+ {
+ }
+
+ /**
+ * Teams initializing<br>
+ */
+ public static void init()
+ {
+ AntiFeedManager.getInstance().registerEvent(AntiFeedManager.CTF_ID);
+ _teams[0] = new CTFEventTeam(Config.CTF_EVENT_TEAM_1_NAME, Config.CTF_EVENT_TEAM_1_COORDINATES);
+ _teams[1] = new CTFEventTeam(Config.CTF_EVENT_TEAM_2_NAME, Config.CTF_EVENT_TEAM_2_COORDINATES);
+ }
+
+ /**
+ * Starts the participation of the CTFEvent<br>
+ * 1. Get L2NpcTemplate by Config.CTF_EVENT_PARTICIPATION_NPC_ID<br>
+ * 2. Try to spawn a new npc of it<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startParticipation()
+ {
+ try
+ {
+ _npcSpawn = new L2Spawn(Config.CTF_EVENT_PARTICIPATION_NPC_ID);
+
+ _npcSpawn.setX(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[0]);
+ _npcSpawn.setY(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[1]);
+ _npcSpawn.setZ(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ _npcSpawn.setAmount(1);
+ _npcSpawn.setHeading(Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[3]);
+ _npcSpawn.setRespawnDelay(1);
+ // later no need to delete spawn from db, we don't store it (false)
+ SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
+ _npcSpawn.init();
+ _lastNpcSpawn = _npcSpawn.getLastSpawn();
+ _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
+ _lastNpcSpawn.setTitle("CTF Event Participation");
+ _lastNpcSpawn.isAggressive();
+ _lastNpcSpawn.decayMe();
+ _lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
+ _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "CTFEventEngine[CTFEvent.startParticipation()]: exception: " + e.getMessage(), e);
+ return false;
+ }
+
+ setState(EventState.PARTICIPATING);
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventRegistrationStart());
+ return true;
+ }
+
+ private static int highestLevelPcInstanceOf(Map<Integer, L2PcInstance> players)
+ {
+ int maxLevel = Integer.MIN_VALUE, maxLevelId = -1;
+ for (L2PcInstance player : players.values())
+ {
+ if (player.getLevel() >= maxLevel)
+ {
+ maxLevel = player.getLevel();
+ maxLevelId = player.getObjectId();
+ }
+ }
+ return maxLevelId;
+ }
+
+ /**
+ * Starts the CTFEvent fight<br>
+ * 1. Set state EventState.STARTING<br>
+ * 2. Close doors specified in configs<br>
+ * 3. Abort if not enought participants(return false)<br>
+ * 4. Set state EventState.STARTED<br>
+ * 5. Teleport all participants to team spot<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startFight()
+ {
+ // Set state to STARTING
+ setState(EventState.STARTING);
+
+ // Randomize and balance team distribution
+ Map<Integer, L2PcInstance> allParticipants = new FastMap<>();
+ allParticipants.putAll(_teams[0].getParticipatedPlayers());
+ allParticipants.putAll(_teams[1].getParticipatedPlayers());
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+
+ L2PcInstance player;
+ Iterator<L2PcInstance> iter;
+ if (needParticipationFee())
+ {
+ iter = allParticipants.values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!hasParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ int balance[] =
+ {
+ 0,
+ 0
+ }, priority = 0, highestLevelPlayerId;
+ L2PcInstance highestLevelPlayer;
+ // TODO: allParticipants should be sorted by level instead of using highestLevelPcInstanceOf for every fetch
+ while (!allParticipants.isEmpty())
+ {
+ // Priority team gets one player
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Exiting if no more players
+ if (allParticipants.isEmpty())
+ {
+ break;
+ }
+ // The other team gets one player
+ // TODO: Code not dry
+ priority = 1 - priority;
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Recalculating priority
+ priority = balance[0] > balance[1] ? 1 : 0;
+ }
+
+ // Check for enought participants
+ if ((_teams[0].getParticipatedPlayerCount() < Config.CTF_EVENT_MIN_PLAYERS_IN_TEAMS) || (_teams[1].getParticipatedPlayerCount() < Config.CTF_EVENT_MIN_PLAYERS_IN_TEAMS))
+ {
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Unspawn the event NPC
+ unSpawnNpc();
+ AntiFeedManager.getInstance().clear(AntiFeedManager.CTF_ID);
+ return false;
+ }
+
+ if (needParticipationFee())
+ {
+ iter = _teams[0].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ iter = _teams[1].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ if (Config.CTF_EVENT_IN_INSTANCE)
+ {
+ try
+ {
+ _CTFEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.CTF_EVENT_INSTANCE_FILE);
+ InstanceManager.getInstance().getInstance(_CTFEventInstance).setAllowSummon(false);
+ InstanceManager.getInstance().getInstance(_CTFEventInstance).setPvPInstance(true);
+ InstanceManager.getInstance().getInstance(_CTFEventInstance).setEmptyDestroyTime((Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L);
+ }
+ catch (Exception e)
+ {
+ _CTFEventInstance = 0;
+ _log.log(Level.WARNING, "CTFEventEngine[CTFEvent.createDynamicInstance]: exception: " + e.getMessage(), e);
+ }
+ }
+
+ // Spawn the flags
+ try
+ {
+ L2NpcTemplate tmpl = NpcData.getInstance().getTemplate(Config.CTF_EVENT_TEAM_1_HEADQUARTERS);
+ _flag1Spawn = new L2Spawn(tmpl);
+ _flag1Spawn.setX(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[0]);
+ _flag1Spawn.setY(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[1]);
+ _flag1Spawn.setZ(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[2]);
+ _flag1Spawn.setHeading(Util.calculateHeadingFrom(new Location(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[2]), new Location(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[2])));
+ _flag1Spawn.setInstanceId(_CTFEventInstance);
+ _flag1Spawn.setRespawnDelay(1);
+ _flag1Spawn.setAmount(1);
+ SpawnTable.getInstance().addNewSpawn(_flag1Spawn, false);
+ _flag1Spawn.init();
+ _lastFlag1Spawn = _flag1Spawn.getLastSpawn();
+ _lastFlag1Spawn.setCurrentHp(_lastFlag1Spawn.getMaxHp());
+ _lastFlag1Spawn.setTitle(Config.CTF_EVENT_TEAM_1_NAME);
+ _lastFlag1Spawn.isAggressive();
+ _lastFlag1Spawn.decayMe();
+ _lastFlag1Spawn.spawnMe(_flag1Spawn.getLastSpawn().getX(), _flag1Spawn.getLastSpawn().getY(), _flag1Spawn.getLastSpawn().getZ());
+ _lastFlag1Spawn.setIsInvul(true);
+ L2NpcTemplate tmpl2 = NpcData.getInstance().getTemplate(Config.CTF_EVENT_TEAM_2_HEADQUARTERS);
+ _flag2Spawn = new L2Spawn(tmpl2);
+ _flag2Spawn.setX(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[0]);
+ _flag2Spawn.setY(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[1]);
+ _flag2Spawn.setZ(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[2]);
+ _flag2Spawn.setHeading(Util.calculateHeadingFrom(new Location(Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_2_FLAG_COORDINATES[2]), new Location(Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[0], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[1], Config.CTF_EVENT_TEAM_1_FLAG_COORDINATES[2])));
+ _flag2Spawn.setInstanceId(_CTFEventInstance);
+ _flag2Spawn.setRespawnDelay(1);
+ _flag2Spawn.setAmount(1);
+ SpawnTable.getInstance().addNewSpawn(_flag2Spawn, false);
+ _flag2Spawn.init();
+ _lastFlag2Spawn = _flag2Spawn.getLastSpawn();
+ _lastFlag2Spawn.setCurrentHp(_lastFlag2Spawn.getMaxHp());
+ _lastFlag2Spawn.setTitle(Config.CTF_EVENT_TEAM_2_NAME);
+ _lastFlag2Spawn.isAggressive();
+ _lastFlag2Spawn.decayMe();
+ _lastFlag2Spawn.spawnMe(_flag2Spawn.getLastSpawn().getX(), _flag2Spawn.getLastSpawn().getY(), _flag2Spawn.getLastSpawn().getZ());
+ _lastFlag2Spawn.setIsInvul(true);
+ _lastFlag2Spawn.setTarget(_lastFlag2Spawn);
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "CTFEventEngine[CTFEvent.spanwnFlags]: exception: " + e.getMessage(), e);
+ }
+
+ // Opens all doors specified in configs for CTF
+ openDoors(Config.CTF_DOORS_IDS_TO_OPEN);
+ // Closes all doors specified in configs for CTF
+ closeDoors(Config.CTF_DOORS_IDS_TO_CLOSE);
+ // Set state STARTED
+ setState(EventState.STARTED);
+
+ // Iterate over all teams
+ for (CTFEventTeam team : _teams)
+ {
+ // Iterate over all participated player instances in this team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ // Disable player revival.
+ playerInstance.setCanRevive(false);
+
+ // Disabled skills by config.
+ if (!Config.CTF_EVENT_RESTRICTED_SKILLS.isEmpty())
+ {
+ for (SkillHolder skill : Config.CTF_EVENT_RESTRICTED_SKILLS)
+ {
+ if (playerInstance.getSkills().values().contains(skill.getSkill()))
+ {
+ playerInstance.disableSkill(skill.getSkill(), ((Config.CTF_EVENT_RUNNING_TIME * 60) + Config.CTF_EVENT_RESPAWN_TELEPORT_DELAY) * 1000);
+ }
+ }
+ }
+
+ // Teleporter implements Runnable and starts itself
+ new CTFEventTeleporter(playerInstance, team.getCoordinates(), false, false);
+ }
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventStart());
+ return true;
+ }
+
+ /**
+ * Calculates the CTFEvent reward<br>
+ * 1. If both teams are at a tie(points equals), send it as system message to all participants, if one of the teams have 0 participants left online abort rewarding<br>
+ * 2. Wait till teams are not at a tie anymore<br>
+ * 3. Set state EvcentState.REWARDING<br>
+ * 4. Reward team with more points<br>
+ * 5. Show win html to wining team participants<br>
+ * <br>
+ * @return String: winning team name<br>
+ */
+ public static String calculateRewards()
+ {
+ if (_teams[0].getPoints() == _teams[1].getPoints())
+ {
+ // Check if one of the teams have no more players left
+ if ((_teams[0].getParticipatedPlayerCount() == 0) || (_teams[1].getParticipatedPlayerCount() == 0))
+ {
+ // set state to rewarding
+ setState(EventState.REWARDING);
+ // return here, the fight can't be completed
+ broadcastScreenMessage("CTF Event: No team won due to inactivity!", 8);
+ return "CTF Event: Event has ended. No team won due to inactivity!";
+ }
+
+ // Both teams have equals points
+ broadcastScreenMessage("CTF Event: Both teams have tied!", 8);
+ sysMsgToAllParticipants("CTF Event: Event has ended, both teams have tied.");
+ if (Config.CTF_REWARD_TEAM_TIE)
+ {
+ rewardTeam(_teams[0]);
+ rewardTeam(_teams[1]);
+ return "CTF Event: Event has ended with both teams tying.";
+ }
+ return "CTF Event: Event has ended with both teams tying.";
+ }
+
+ // Set state REWARDING so nobody can point anymore
+ setState(EventState.REWARDING);
+
+ // Get team which has more points
+ CTFEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1];
+ rewardTeam(team);
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventFinish());
+
+ broadcastScreenMessage("CTF Event: Team " + team.getName() + " wins!", 8);
+ return "CTF Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills.";
+ }
+
+ private static void rewardTeam(CTFEventTeam team)
+ {
+ // Iterate over all participated player instances of the winning team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance == null)
+ {
+ continue;
+ }
+
+ // Fireworks for rewarded player
+ playerInstance.broadcastPacket(new MagicSkillUse(playerInstance, playerInstance, CommonSkill.FIREWORK.getSkill().getId(), 1, 1, 1));
+
+ SystemMessage systemMessage = null;
+
+ // Iterate over all CTF event rewards
+ for (int[] reward : Config.CTF_EVENT_REWARDS)
+ {
+ PcInventory inv = playerInstance.getInventory();
+
+ // Check for stackable item, non stackabe items need to be added one by one
+ if (ItemTable.getInstance().getTemplate(reward[0]).isStackable())
+ {
+ inv.addItem("CTF Event", reward[0], reward[1], playerInstance, playerInstance);
+
+ if (reward[1] > 1)
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+ systemMessage.addItemName(reward[0]);
+ systemMessage.addLong(reward[1]);
+ }
+ else
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ }
+
+ playerInstance.sendPacket(systemMessage);
+ }
+ else
+ {
+ for (int i = 0; i < reward[1]; ++i)
+ {
+ inv.addItem("CTF Event", reward[0], 1, playerInstance, playerInstance);
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ playerInstance.sendPacket(systemMessage);
+ }
+ }
+ }
+
+ StatusUpdate statusUpdate = new StatusUpdate(playerInstance);
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, playerInstance.getCurrentLoad());
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Reward.html"));
+ playerInstance.sendPacket(statusUpdate);
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+
+ /**
+ * Stops the CTFEvent fight<br>
+ * 1. Set state EventState.INACTIVATING<br>
+ * 2. Remove CTF npc from world<br>
+ * 3. Open doors specified in configs<br>
+ * 4. Teleport all participants back to participation npc location<br>
+ * 5. Teams cleaning<br>
+ * 6. Set state EventState.INACTIVE<br>
+ */
+ public static void stopFight()
+ {
+ // Set state INACTIVATING
+ setState(EventState.INACTIVATING);
+ // Unspawn event npc
+ unSpawnNpc();
+ // Opens all doors specified in configs for CTF
+ openDoors(Config.CTF_DOORS_IDS_TO_CLOSE);
+ // Closes all doors specified in Configs for CTF
+ closeDoors(Config.CTF_DOORS_IDS_TO_OPEN);
+
+ // Reset flag carriers
+ if (_team1Carrier != null)
+ {
+ removeFlagCarrier(_team1Carrier);
+ }
+
+ if (_team2Carrier != null)
+ {
+ removeFlagCarrier(_team2Carrier);
+ }
+
+ // Iterate over all teams
+ for (CTFEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance != null)
+ {
+ // Enable player revival.
+ playerInstance.setCanRevive(true);
+
+ // Untransform player.
+ if (playerInstance.isTransformed())
+ {
+ playerInstance.untransform();
+ }
+
+ // Teleport back.
+ new CTFEventTeleporter(playerInstance, Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+ }
+
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.CTF_ID);
+ }
+
+ /**
+ * Adds a player to a CTFEvent team<br>
+ * 1. Calculate the id of the team in which the player should be added<br>
+ * 2. Add the player to the calculated team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static synchronized boolean addParticipant(L2PcInstance playerInstance)
+ {
+ // Check for nullpoitner
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ byte teamId = 0;
+
+ // Check to which team the player should be added
+ if (_teams[0].getParticipatedPlayerCount() == _teams[1].getParticipatedPlayerCount())
+ {
+ teamId = (byte) (Rnd.get(2));
+ }
+ else
+ {
+ teamId = (byte) (_teams[0].getParticipatedPlayerCount() > _teams[1].getParticipatedPlayerCount() ? 1 : 0);
+ }
+ playerInstance.addEventListener(new CTFEventListener(playerInstance));
+ return _teams[teamId].addPlayer(playerInstance);
+ }
+
+ /**
+ * Removes a CTFEvent player from it's team<br>
+ * 1. Get team id of the player<br>
+ * 2. Remove player from it's team<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if success, otherwise false
+ */
+ public static boolean removeParticipant(int playerObjectId)
+ {
+ // Get the teamId of the player
+ byte teamId = getParticipantTeamId(playerObjectId);
+
+ // Check if the player is participant
+ if (teamId != -1)
+ {
+ // Remove the player from team
+ _teams[teamId].removePlayer(playerObjectId);
+
+ final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
+ if (player != null)
+ {
+ player.removeEventListener(CTFEventListener.class);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean needParticipationFee()
+ {
+ return (Config.CTF_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.CTF_EVENT_PARTICIPATION_FEE[1] != 0);
+ }
+
+ public static boolean hasParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.getInventory().getInventoryItemCount(Config.CTF_EVENT_PARTICIPATION_FEE[0], -1) >= Config.CTF_EVENT_PARTICIPATION_FEE[1];
+ }
+
+ public static boolean payParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.destroyItemByItemId("CTF Participation Fee", Config.CTF_EVENT_PARTICIPATION_FEE[0], Config.CTF_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
+ }
+
+ public static String getParticipationFee()
+ {
+ int itemId = Config.CTF_EVENT_PARTICIPATION_FEE[0];
+ int itemNum = Config.CTF_EVENT_PARTICIPATION_FEE[1];
+
+ if ((itemId == 0) || (itemNum == 0))
+ {
+ return "-";
+ }
+
+ return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
+ }
+
+ /**
+ * Send a SystemMessage to all participated players<br>
+ * 1. Send the message to all players of team number one<br>
+ * 2. Send the message to all players of team number two<br>
+ * <br>
+ * @param message as String<br>
+ */
+ public static void sysMsgToAllParticipants(String message)
+ {
+ for (L2PcInstance playerInstance : _teams[0].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+
+ for (L2PcInstance playerInstance : _teams[1].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+ }
+
+ private static L2DoorInstance getDoor(int doorId)
+ {
+ L2DoorInstance door = null;
+ if (_CTFEventInstance <= 0)
+ {
+ door = DoorData.getInstance().getDoor(doorId);
+ }
+ else
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(_CTFEventInstance);
+ if (inst != null)
+ {
+ door = inst.getDoor(doorId);
+ }
+ }
+ return door;
+ }
+
+ /**
+ * Close doors specified in configs
+ * @param doors
+ */
+ private static void closeDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.closeMe();
+ }
+ }
+ }
+
+ /**
+ * Open doors specified in configs
+ * @param doors
+ */
+ private static void openDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.openMe();
+ }
+ }
+ }
+
+ /**
+ * UnSpawns the CTFEvent npc
+ */
+ private static void unSpawnNpc()
+ {
+ // Delete the npc
+ _lastNpcSpawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
+
+ // Stop respawning of the npc
+ _npcSpawn.stopRespawn();
+ _npcSpawn = null;
+ _lastNpcSpawn = null;
+
+ // Remove flags
+ if (_lastFlag1Spawn != null)
+ {
+ _lastFlag1Spawn.deleteMe();
+ _lastFlag2Spawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastFlag1Spawn.getSpawn(), false);
+ SpawnTable.getInstance().deleteSpawn(_lastFlag2Spawn.getSpawn(), false);
+ _flag1Spawn.stopRespawn();
+ _flag2Spawn.stopRespawn();
+ _flag1Spawn = null;
+ _flag2Spawn = null;
+ _lastFlag1Spawn = null;
+ _lastFlag2Spawn = null;
+ }
+ }
+
+ /**
+ * Called when a player logs in<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogin(L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || (!isStarting() && !isStarted()))
+ {
+ return;
+ }
+
+ byte teamId = getParticipantTeamId(playerInstance.getObjectId());
+
+ if (teamId == -1)
+ {
+ return;
+ }
+
+ _teams[teamId].addPlayer(playerInstance);
+ new CTFEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
+ }
+
+ /**
+ * Called when a player logs out<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogout(L2PcInstance playerInstance)
+ {
+ if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
+ {
+ if (removeParticipant(playerInstance.getObjectId()))
+ {
+ playerInstance.setXYZInvisible((Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[0] + Rnd.get(101)) - 50, (Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[1] + Rnd.get(101)) - 50, Config.CTF_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ }
+ }
+ }
+
+ /**
+ * Called on every onAction in L2PcIstance<br>
+ * <br>
+ * @param playerInstance
+ * @param targetedPlayerObjectId
+ * @return boolean: true if player is allowed to target, otherwise false
+ */
+ public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
+ {
+ if ((playerInstance == null) || !isStarted())
+ {
+ return true;
+ }
+
+ if (playerInstance.isGM())
+ {
+ return true;
+ }
+
+ byte playerTeamId = getParticipantTeamId(playerInstance.getObjectId());
+ byte targetedPlayerTeamId = getParticipantTeamId(targetedPlayerObjectId);
+
+ if (((playerTeamId != -1) && (targetedPlayerTeamId == -1)) || ((playerTeamId == -1) && (targetedPlayerTeamId != -1)))
+ {
+ return false;
+ }
+
+ if ((playerTeamId != -1) && (targetedPlayerTeamId != -1) && (playerTeamId == targetedPlayerTeamId) && (playerInstance.getObjectId() != targetedPlayerObjectId) && !Config.CTF_EVENT_TARGET_TEAM_MEMBERS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every scroll use<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use scroll, otherwise false
+ */
+ public static boolean onScrollUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.CTF_EVENT_SCROLL_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every potion use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use potions, otherwise false
+ */
+ public static boolean onPotionUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.CTF_EVENT_POTIONS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every escape use(thanks to nbd)
+ * @param playerObjectId
+ * @return boolean: true if player is not in CTF event, otherwise false
+ */
+ public static boolean onEscapeUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every summon item use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to summon by item, otherwise false
+ */
+ public static boolean onItemSummon(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.CTF_EVENT_SUMMON_BY_ITEM_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is called when a player is killed<br>
+ * <br>
+ * @param killerCharacter as L2Character<br>
+ * @param killedPlayerInstance as L2PcInstance<br>
+ */
+ public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
+ {
+ if ((killedPlayerInstance == null) || !isStarted())
+ {
+ return;
+ }
+
+ byte killedTeamId = getParticipantTeamId(killedPlayerInstance.getObjectId());
+
+ if (killedTeamId == -1)
+ {
+ return;
+ }
+
+ new CTFEventTeleporter(killedPlayerInstance, _teams[killedTeamId].getCoordinates(), false, false);
+
+ if (killerCharacter == null)
+ {
+ return;
+ }
+
+ L2PcInstance killerPlayerInstance = null;
+
+ if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
+ {
+ killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
+
+ if (killerPlayerInstance == null)
+ {
+ return;
+ }
+ }
+ else if (killerCharacter instanceof L2PcInstance)
+ {
+ killerPlayerInstance = (L2PcInstance) killerCharacter;
+ }
+ else
+ {
+ return;
+ }
+
+ byte killerTeamId = getParticipantTeamId(killerPlayerInstance.getObjectId());
+
+ if ((killerTeamId != -1) && (killedTeamId != -1) && (killerTeamId != killedTeamId))
+ {
+ CTFEventTeam killerTeam = _teams[killerTeamId];
+
+ CreatureSay cs = new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!");
+
+ for (L2PcInstance playerInstance : _teams[killerTeamId].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendPacket(cs);
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnCTFEventKill(killerPlayerInstance, killedPlayerInstance, killerTeam));
+ }
+
+ if (playerIsCarrier(killedPlayerInstance))
+ {
+ broadcastScreenMessage(killerCharacter.getName() + " has killed " + killedPlayerInstance.getName() + "!", 7);
+ }
+ }
+
+ /**
+ * Called on Appearing packet received (player finished teleporting)
+ * @param playerInstance
+ */
+ public static void onTeleported(L2PcInstance playerInstance)
+ {
+ if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
+ {
+ return;
+ }
+
+ if (playerInstance.isMageClass())
+ {
+ if ((Config.CTF_EVENT_MAGE_BUFFS != null) && !Config.CTF_EVENT_MAGE_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.CTF_EVENT_MAGE_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((Config.CTF_EVENT_FIGHTER_BUFFS != null) && !Config.CTF_EVENT_FIGHTER_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.CTF_EVENT_FIGHTER_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param source
+ * @param target
+ * @param skill
+ * @return true if player valid for skill
+ */
+ public static final boolean checkForCTFSkill(L2PcInstance source, L2PcInstance target, Skill skill)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ // CTF is started
+ final int sourcePlayerId = source.getObjectId();
+ final int targetPlayerId = target.getObjectId();
+ final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
+ final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
+
+ // both players not participating
+ if (!isSourceParticipant && !isTargetParticipant)
+ {
+ return true;
+ }
+ // one player not participating
+ if (!(isSourceParticipant && isTargetParticipant))
+ {
+ return false;
+ }
+ // players in the different teams ?
+ if (getParticipantTeamId(sourcePlayerId) != getParticipantTeamId(targetPlayerId))
+ {
+ if (!skill.isBad())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Sets the CTFEvent state<br>
+ * <br>
+ * @param state as EventState<br>
+ */
+ private static void setState(EventState state)
+ {
+ synchronized (_state)
+ {
+ _state = state;
+ }
+ }
+
+ /**
+ * Is CTFEvent inactive?<br>
+ * <br>
+ * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
+ */
+ public static boolean isInactive()
+ {
+ boolean isInactive;
+
+ synchronized (_state)
+ {
+ isInactive = _state == EventState.INACTIVE;
+ }
+
+ return isInactive;
+ }
+
+ /**
+ * Is CTFEvent in inactivating?<br>
+ * <br>
+ * @return boolean: true if event is in inactivating progress, otherwise false<br>
+ */
+ public static boolean isInactivating()
+ {
+ boolean isInactivating;
+
+ synchronized (_state)
+ {
+ isInactivating = _state == EventState.INACTIVATING;
+ }
+
+ return isInactivating;
+ }
+
+ /**
+ * Is CTFEvent in participation?<br>
+ * <br>
+ * @return boolean: true if event is in participation progress, otherwise false<br>
+ */
+ public static boolean isParticipating()
+ {
+ boolean isParticipating;
+
+ synchronized (_state)
+ {
+ isParticipating = _state == EventState.PARTICIPATING;
+ }
+
+ return isParticipating;
+ }
+
+ /**
+ * Is CTFEvent starting?<br>
+ * <br>
+ * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
+ */
+ public static boolean isStarting()
+ {
+ boolean isStarting;
+
+ synchronized (_state)
+ {
+ isStarting = _state == EventState.STARTING;
+ }
+
+ return isStarting;
+ }
+
+ /**
+ * Is CTFEvent started?<br>
+ * <br>
+ * @return boolean: true if event is started, otherwise false<br>
+ */
+ public static boolean isStarted()
+ {
+ boolean isStarted;
+
+ synchronized (_state)
+ {
+ isStarted = _state == EventState.STARTED;
+ }
+
+ return isStarted;
+ }
+
+ /**
+ * Is CTFEvent rewarding?<br>
+ * <br>
+ * @return boolean: true if event is currently rewarding, otherwise false<br>
+ */
+ public static boolean isRewarding()
+ {
+ boolean isRewarding;
+
+ synchronized (_state)
+ {
+ isRewarding = _state == EventState.REWARDING;
+ }
+
+ return isRewarding;
+ }
+
+ /**
+ * Returns the team id of a player, if player is not participant it returns -1
+ * @param playerObjectId
+ * @return byte: team name of the given playerName, if not in event -1
+ */
+ public static byte getParticipantTeamId(int playerObjectId)
+ {
+ return (byte) (_teams[0].containsPlayer(playerObjectId) ? 0 : (_teams[1].containsPlayer(playerObjectId) ? 1 : -1));
+ }
+
+ /**
+ * Returns the team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return CTFEventTeam: team of the given playerObjectId, if not in event null
+ */
+ public static CTFEventTeam getParticipantTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[0] : (_teams[1].containsPlayer(playerObjectId) ? _teams[1] : null));
+ }
+
+ /**
+ * Returns the enemy team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return CTFEventTeam: enemy team of the given playerObjectId, if not in event null
+ */
+ public static CTFEventTeam getParticipantEnemyTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[1] : (_teams[1].containsPlayer(playerObjectId) ? _teams[0] : null));
+ }
+
+ /**
+ * Returns the team coordinates in which the player is in, if player is not in a team return null
+ * @param playerObjectId
+ * @return int[]: coordinates of teams, 2 elements, index 0 for team 1 and index 1 for team 2
+ */
+ public static int[] getParticipantTeamCoordinates(int playerObjectId)
+ {
+ return _teams[0].containsPlayer(playerObjectId) ? _teams[0].getCoordinates() : (_teams[1].containsPlayer(playerObjectId) ? _teams[1].getCoordinates() : null);
+ }
+
+ /**
+ * Is given player participant of the event?
+ * @param playerObjectId
+ * @return boolean: true if player is participant, ohterwise false
+ */
+ public static boolean isPlayerParticipant(int playerObjectId)
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return false;
+ }
+
+ return _teams[0].containsPlayer(playerObjectId) || _teams[1].containsPlayer(playerObjectId);
+ }
+
+ /**
+ * Returns participated player count<br>
+ * <br>
+ * @return int: amount of players registered in the event<br>
+ */
+ public static int getParticipatedPlayersCount()
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return 0;
+ }
+
+ return _teams[0].getParticipatedPlayerCount() + _teams[1].getParticipatedPlayerCount();
+ }
+
+ /**
+ * Returns teams names<br>
+ * <br>
+ * @return String[]: names of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static String[] getTeamNames()
+ {
+ return new String[]
+ {
+ _teams[0].getName(),
+ _teams[1].getName()
+ };
+ }
+
+ /**
+ * Returns player count of both teams<br>
+ * <br>
+ * @return int[]: player count of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPlayerCounts()
+ {
+ return new int[]
+ {
+ _teams[0].getParticipatedPlayerCount(),
+ _teams[1].getParticipatedPlayerCount()
+ };
+ }
+
+ /**
+ * Returns points count of both teams
+ * @return int[]: points of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPoints()
+ {
+ return new int[]
+ {
+ _teams[0].getPoints(),
+ _teams[1].getPoints()
+ };
+ }
+
+ /**
+ * Used when carrier scores, dies or game ends
+ * @param player L2PcInstance
+ */
+ public static void removeFlagCarrier(L2PcInstance player)
+ {
+ // un-equip - destroy flag
+ player.getInventory().unEquipItemInSlot(Inventory.PAPERDOLL_RHAND);
+ player.destroyItemByItemId("ctf", getEnemyTeamFlagId(player), 1, player, false);
+
+ // unblock inventory
+ player.getInventory().unblock();
+
+ // re-equip player items
+ final L2ItemInstance carrierRHand = _teams[0].containsPlayer(player.getObjectId()) ? _team1CarrierRHand : _team2CarrierRHand;
+ final L2ItemInstance carrierLHand = _teams[0].containsPlayer(player.getObjectId()) ? _team1CarrierLHand : _team2CarrierLHand;
+ if ((carrierRHand != null) && (player.getInventory().getItemByItemId(carrierRHand.getId()) != null))
+ {
+ player.getInventory().equipItem(carrierRHand);
+ }
+ if ((carrierLHand != null) && (player.getInventory().getItemByItemId(carrierLHand.getId()) != null))
+ {
+ player.getInventory().equipItem(carrierLHand);
+ }
+ setCarrierUnequippedWeapons(player, null, null);
+
+ // flag carrier removal
+ if (_teams[0].containsPlayer(player.getObjectId()))
+ {
+ _team1Carrier = null;
+ }
+ else
+ {
+ _team2Carrier = null;
+ }
+
+ // show re-equipped weapons
+ player.broadcastUserInfo();
+ }
+
+ /**
+ * Assign the Ctf team flag carrier
+ * @param player L2PcInstance
+ */
+ public static void setTeamCarrier(L2PcInstance player)
+ {
+ if (_teams[0].containsPlayer(player.getObjectId()))
+ {
+ _team1Carrier = player;
+ }
+ else
+ {
+ _team2Carrier = player;
+ }
+ }
+
+ /**
+ * @param player L2PcInstance
+ * @return the team carrier L2PcInstance
+ */
+ public static L2PcInstance getTeamCarrier(L2PcInstance player)
+ {
+ // check if team carrier has disconnected
+ if (((_teams[0].containsPlayer(player.getObjectId()) == true) && (_team1Carrier != null) && (!_team1Carrier.isOnline() || (_team1Carrier.getInstanceId() != _CTFEventInstance))) || ((_teams[1].containsPlayer(player.getObjectId()) == true) && (_team2Carrier != null) && (!_team2Carrier.isOnline() || (_team2Carrier.getInstanceId() != _CTFEventInstance))))
+ {
+ player.destroyItemByItemId("ctf", getEnemyTeamFlagId(player), 1, player, false);
+ return null;
+ }
+
+ // return team carrier
+ return (_teams[0].containsPlayer(player.getObjectId()) ? _team1Carrier : _team2Carrier);
+ }
+
+ /**
+ * @param player L2PcInstance
+ * @return the enemy team carrier L2PcInstance
+ */
+ public static L2PcInstance getEnemyCarrier(L2PcInstance player)
+ {
+ // check if enemy carrier has disconnected
+ if (((_teams[0].containsPlayer(player.getObjectId()) == true) && (_team2Carrier != null) && (!_team2Carrier.isOnline() || (_team2Carrier.getInstanceId() != _CTFEventInstance))) || ((_teams[1].containsPlayer(player.getObjectId()) == true) && (_team1Carrier != null) && (!_team1Carrier.isOnline() || (_team1Carrier.getInstanceId() != _CTFEventInstance))))
+ {
+ player.destroyItemByItemId("ctf", getEnemyTeamFlagId(player), 1, player, false);
+ return null;
+ }
+
+ // return enemy carrier
+ return (_teams[0].containsPlayer(player.getObjectId()) ? _team2Carrier : _team1Carrier);
+ }
+
+ /**
+ * @param player L2PcInstance
+ * @return true if player is the carrier
+ */
+ public static boolean playerIsCarrier(L2PcInstance player)
+ {
+ return ((player == _team1Carrier) || (player == _team2Carrier)) ? true : false;
+ }
+
+ /**
+ * @param player L2ItemInstance
+ * @return int The enemy flag id
+ */
+ public static int getEnemyTeamFlagId(L2PcInstance player)
+ {
+ return (_teams[0].containsPlayer(player.getObjectId()) ? Config.CTF_EVENT_TEAM_2_FLAG : Config.CTF_EVENT_TEAM_1_FLAG);
+ }
+
+ /**
+ * Stores the carrier equipped weapons
+ * @param player L2PcInstance
+ * @param itemRight L2ItemInstance
+ * @param itemLeft L2ItemInstance
+ */
+ public static void setCarrierUnequippedWeapons(L2PcInstance player, L2ItemInstance itemRight, L2ItemInstance itemLeft)
+ {
+ if (_teams[0].containsPlayer(player.getObjectId()))
+ {
+ _team1CarrierRHand = itemRight;
+ _team1CarrierLHand = itemLeft;
+ }
+ else
+ {
+ _team2CarrierRHand = itemRight;
+ _team2CarrierLHand = itemLeft;
+ }
+ }
+
+ /**
+ * Broadcast a message to all participant screens
+ * @param message String
+ * @param duration int (in seconds)
+ */
+ public static void broadcastScreenMessage(String message, int duration)
+ {
+ for (CTFEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if ((playerInstance != null) && (playerInstance.getInstanceId() == _CTFEventInstance))
+ {
+ playerInstance.sendPacket(new ExShowScreenMessage(message, duration * 1000));
+ }
+ }
+ }
+ }
+
+ /**
+ * Broadcast score to all participants
+ */
+ public static void broadcastScoreMessage()
+ {
+ final String score = Config.CTF_EVENT_TEAM_1_NAME + ": " + _teams[0].getPoints() + " - " + Config.CTF_EVENT_TEAM_2_NAME + ": " + _teams[1].getPoints();
+
+ for (CTFEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if ((playerInstance != null) && (playerInstance.getInstanceId() == _CTFEventInstance))
+ {
+ playerInstance.sendPacket(new ExShowScreenMessage(1, -1, 8, 0, 1, 0, 0, false, 15000, true, score, NpcStringId.NONE, null));
+ }
+ }
+ }
+ }
+
+ public static int getCTFEventInstance()
+ {
+ return _CTFEventInstance;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventListener.java (working copy)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class CTFEventListener implements IEventListener
+{
+ private final L2PcInstance _player;
+
+ protected CTFEventListener(L2PcInstance player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return CTFEvent.isStarted() && CTFEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ @Override
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventPlayer.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventPlayer.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventPlayer.java (working copy)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class CTFEventPlayer
+{
+ private final L2PcInstance _player;
+
+ protected CTFEventPlayer(L2PcInstance player)
+ {
+ _player = player;
+
+ }
+
+ public boolean isOnEvent()
+ {
+ return CTFEvent.isStarted() && CTFEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author HorridoJoho
+ */
+public class CTFEventTeam
+{
+ /** The name of the team<br> */
+ private final String _name;
+ /** The team spot coordinated<br> */
+ private int[] _coordinates = new int[3];
+ /** The points of the team<br> */
+ private short _points;
+ /** Name and instance of all participated players in FastMap<br> */
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ /**
+ * C'tor initialize the team<br>
+ * <br>
+ * @param name as String<br>
+ * @param coordinates as int[]<br>
+ */
+ public CTFEventTeam(String name, int[] coordinates)
+ {
+ _name = name;
+ _coordinates = coordinates;
+ _points = 0;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes a player from the team
+ * @param playerObjectId
+ */
+ public void removePlayer(int playerObjectId)
+ {
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.remove(playerObjectId);
+ }
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * Returns the name of the team<br>
+ * <br>
+ * @return String: name of the team<br>
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the coordinates of the team spot<br>
+ * <br>
+ * @return int[]: team coordinates<br>
+ */
+ public int[] getCoordinates()
+ {
+ return _coordinates;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFEventTeleporter.java (working copy)
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.Team;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Duel;
+import com.l2jserver.util.Rnd;
+
+public class CTFEventTeleporter implements Runnable
+{
+ /** The instance of the player to teleport */
+ private L2PcInstance _playerInstance = null;
+ /** Coordinates of the spot to teleport to */
+ private int[] _coordinates = new int[3];
+ /** Admin removed this player from event */
+ private boolean _adminRemove = false;
+
+ /**
+ * Initialize the teleporter and start the delayed task.
+ * @param playerInstance
+ * @param coordinates
+ * @param fastSchedule
+ * @param adminRemove
+ */
+ public CTFEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
+ {
+ _playerInstance = playerInstance;
+ _coordinates = coordinates;
+ _adminRemove = adminRemove;
+
+ long delay = (CTFEvent.isStarted() ? Config.CTF_EVENT_RESPAWN_TELEPORT_DELAY : Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
+
+ ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
+ }
+
+ /**
+ * The task method to teleport the player<br>
+ * 1. Unsummon pet if there is one<br>
+ * 2. Remove all effects<br>
+ * 3. Revive and full heal the player<br>
+ * 4. Teleport the player<br>
+ * 5. Broadcast status and user info
+ */
+ @Override
+ public void run()
+ {
+ if (_playerInstance == null)
+ {
+ return;
+ }
+
+ L2Summon summon = _playerInstance.getSummon();
+
+ if (summon != null)
+ {
+ summon.unSummon(_playerInstance);
+ }
+
+ if ((Config.CTF_EVENT_EFFECTS_REMOVAL == 0) || ((Config.CTF_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
+ {
+ _playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
+ }
+
+ if (_playerInstance.isInDuel())
+ {
+ _playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
+ }
+
+ int CTFInstance = CTFEvent.getCTFEventInstance();
+ if (CTFInstance != 0)
+ {
+ if (CTFEvent.isStarted() && !_adminRemove)
+ {
+ _playerInstance.setInstanceId(CTFInstance);
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+
+ _playerInstance.doRevive();
+
+ _playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
+
+ // Reset flag carrier
+ if (CTFEvent.playerIsCarrier(_playerInstance))
+ {
+ CTFEvent.removeFlagCarrier(_playerInstance);
+ CTFEvent.broadcastScreenMessage("The " + CTFEvent.getParticipantEnemyTeam(_playerInstance.getObjectId()).getName() + " flag has been returned!", 5);
+ }
+
+ if (CTFEvent.isStarted() && !_adminRemove)
+ {
+ int teamId = CTFEvent.getParticipantTeamId(_playerInstance.getObjectId()) + 1;
+ switch (teamId)
+ {
+ case 0:
+ _playerInstance.setTeam(Team.NONE);
+ break;
+ case 1:
+ _playerInstance.setTeam(Team.BLUE);
+ break;
+ case 2:
+ _playerInstance.setTeam(Team.RED);
+ break;
+ }
+ }
+ else
+ {
+ _playerInstance.setTeam(Team.NONE);
+ }
+
+ _playerInstance.setCurrentCp(_playerInstance.getMaxCp());
+ _playerInstance.setCurrentHp(_playerInstance.getMaxHp());
+ _playerInstance.setCurrentMp(_playerInstance.getMaxMp());
+
+ _playerInstance.broadcastStatusUpdate();
+ _playerInstance.broadcastUserInfo();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/ctf/CTFManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/ctf/CTFManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/ctf/CTFManager.java (working copy)
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.ctf;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author HorridoJoho
+ */
+public class CTFManager
+{
+ protected static final Logger _log = Logger.getLogger(CTFManager.class.getName());
+
+ /** Task for event cycles<br> */
+ private CTFStartTask _task;
+
+ /**
+ * New instance only by getInstance()<br>
+ */
+ protected CTFManager()
+ {
+ if (Config.CTF_EVENT_ENABLED)
+ {
+ // Cannot start if both teams have same name
+ if (Config.CTF_EVENT_TEAM_1_NAME != Config.CTF_EVENT_TEAM_2_NAME)
+ {
+ CTFEvent.init();
+
+ scheduleEventStart();
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Started.");
+ }
+ else
+ {
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Engine uninitiated. Cannot start if both teams have same name!");
+ }
+ }
+ else
+ {
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Engine is disabled.");
+ }
+ }
+
+ /**
+ * Initialize new/Returns the one and only instance<br>
+ * <br>
+ * @return CTFManager<br>
+ */
+ public static CTFManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ /**
+ * Starts CTFStartTask
+ */
+ public void scheduleEventStart()
+ {
+ try
+ {
+ Calendar currentTime = Calendar.getInstance();
+ Calendar nextStartTime = null;
+ Calendar testStartTime = null;
+ for (String timeOfDay : Config.CTF_EVENT_INTERVAL)
+ {
+ // Creating a Calendar object from the specified interval value
+ testStartTime = Calendar.getInstance();
+ testStartTime.setLenient(true);
+ String[] splitTimeOfDay = timeOfDay.split(":");
+ testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+ testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+ // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
+ if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+ {
+ testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ // Check for the test date to be the minimum (smallest in the specified list)
+ if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
+ {
+ nextStartTime = testStartTime;
+ }
+ }
+ if (nextStartTime != null)
+ {
+ _task = new CTFStartTask(nextStartTime.getTimeInMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+ catch (Exception e)
+ {
+ _log.warning("CTFEventEngine[CTFManager.scheduleEventStart()]: Error figuring out a start time. Check CTFEventInterval in config file.");
+ }
+ }
+
+ /**
+ * Method to start participation
+ */
+ public void startReg()
+ {
+ if (!CTFEvent.startParticipation())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: Event was cancelled.");
+ _log.warning("CTFEventEngine[CTFManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: Registration opened for " + Config.CTF_EVENT_PARTICIPATION_TIME + " minute(s).");
+
+ // schedule registration end
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.CTF_EVENT_PARTICIPATION_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to start the fight
+ */
+ public void startEvent()
+ {
+ if (!CTFEvent.startFight())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: Event cancelled due to lack of Participation.");
+ _log.info("CTFEventEngine[CTFManager.run()]: Lack of registration, abort event.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: Teleporting participants to an arena in " + Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.CTF_EVENT_RUNNING_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to end the event and reward
+ */
+ public void endEvent()
+ {
+ Broadcast.toAllOnlinePlayers(CTFEvent.calculateRewards());
+ CTFEvent.sysMsgToAllParticipants("CTF Event: Teleporting back to the registration npc in " + Config.CTF_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ CTFEvent.stopFight();
+
+ scheduleEventStart();
+ }
+
+ public void skipDelay()
+ {
+ if (_task.nextRun.cancel(false))
+ {
+ _task.setStartTime(System.currentTimeMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Class for CTF cycles
+ */
+ class CTFStartTask implements Runnable
+ {
+ private long _startTime;
+ public ScheduledFuture<?> nextRun;
+
+ public CTFStartTask(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ public void setStartTime(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ @Override
+ public void run()
+ {
+ int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+
+ if (delay > 0)
+ {
+ announce(delay);
+ }
+
+ int nextMsg = 0;
+ if (delay > 3600)
+ {
+ nextMsg = delay - 3600;
+ }
+ else if (delay > 1800)
+ {
+ nextMsg = delay - 1800;
+ }
+ else if (delay > 900)
+ {
+ nextMsg = delay - 900;
+ }
+ else if (delay > 600)
+ {
+ nextMsg = delay - 600;
+ }
+ else if (delay > 300)
+ {
+ nextMsg = delay - 300;
+ }
+ else if (delay > 60)
+ {
+ nextMsg = delay - 60;
+ }
+ else if (delay > 5)
+ {
+ nextMsg = delay - 5;
+ }
+ else if (delay > 0)
+ {
+ nextMsg = delay;
+ }
+ else
+ {
+ // start
+ if (CTFEvent.isInactive())
+ {
+ startReg();
+ }
+ else if (CTFEvent.isParticipating())
+ {
+ startEvent();
+ }
+ else
+ {
+ endEvent();
+ }
+ }
+
+ if (delay > 0)
+ {
+ nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+ }
+ }
+
+ private void announce(long time)
+ {
+ if ((time >= 3600) && ((time % 3600) == 0))
+ {
+ if (CTFEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
+ }
+ else if (CTFEvent.isStarted())
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
+ }
+ }
+ else if (time >= 60)
+ {
+ if (CTFEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: " + (time / 60) + " minute(s) until registration is closed!");
+ }
+ else if (CTFEvent.isStarted())
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: " + (time / 60) + " minute(s) until the event is finished!");
+ }
+ }
+ else
+ {
+ if (CTFEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("CTF Event: " + time + " second(s) until registration is closed!");
+ }
+ else if (CTFEvent.isStarted())
+ {
+ CTFEvent.sysMsgToAllParticipants("CTF Event: " + time + " second(s) until the event is finished!");
+ }
+ }
+ }
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final CTFManager _instance = new CTFManager();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEvent.java (working copy)
@@ -0,0 +1,1091 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.data.xml.impl.DoorData;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.SkillData;
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
+import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventStart;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.skills.CommonSkill;
+import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author HorridoJoho
+ */
+public class DMEvent
+{
+ enum EventState
+ {
+ INACTIVE,
+ INACTIVATING,
+ PARTICIPATING,
+ STARTING,
+ STARTED,
+ REWARDING
+ }
+
+ protected static final Logger _log = Logger.getLogger(DMEvent.class.getName());
+ /** html path **/
+ private static final String htmlPath = "data/scripts/custom/events/DM/DMManager/";
+ /** The state of the DMEvent<br> */
+ private static EventState _state = EventState.INACTIVE;
+ /** The spawn of the participation npc<br> */
+ private static L2Spawn _npcSpawn = null;
+ /** the npc instance of the participation npc<br> */
+ private static L2Npc _lastNpcSpawn = null;
+ /** Instance id<br> */
+ private static int _DMEventInstance = 0;
+ /** Players of the DMEvent<br> */
+ private static Map<Integer, DMEventPlayer> _participants = new FastMap<>();
+
+ /**
+ * No instance of this class!<br>
+ */
+ private DMEvent()
+ {
+ }
+
+ /**
+ * Teams initializing<br>
+ */
+ public static void init()
+ {
+ AntiFeedManager.getInstance().registerEvent(AntiFeedManager.DM_ID);
+ }
+
+ /**
+ * Starts the participation of the DMEvent<br>
+ * 1. Get L2NpcTemplate by Config.DM_EVENT_PARTICIPATION_NPC_ID<br>
+ * 2. Try to spawn a new npc of it<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startParticipation()
+ {
+ try
+ {
+ _npcSpawn = new L2Spawn(Config.DM_EVENT_PARTICIPATION_NPC_ID);
+
+ _npcSpawn.setX(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[0]);
+ _npcSpawn.setY(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[1]);
+ _npcSpawn.setZ(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ _npcSpawn.setAmount(1);
+ _npcSpawn.setHeading(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[3]);
+ _npcSpawn.setRespawnDelay(1);
+ // later no need to delete spawn from db, we don't store it (false)
+ SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
+ _npcSpawn.init();
+ _lastNpcSpawn = _npcSpawn.getLastSpawn();
+ _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
+ _lastNpcSpawn.setTitle("DM Event Participation");
+ _lastNpcSpawn.isAggressive();
+ _lastNpcSpawn.decayMe();
+ _lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
+ _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "DMEventEngine[DMEvent.startParticipation()]: exception: " + e.getMessage(), e);
+ return false;
+ }
+
+ setState(EventState.PARTICIPATING);
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventRegistrationStart());
+ return true;
+ }
+
+ /**
+ * Starts the DMEvent fight<br>
+ * 1. Set state EventState.STARTING<br>
+ * 2. Close doors specified in configs<br>
+ * 3. Abort if not enought participants(return false)<br>
+ * 4. Set state EventState.STARTED<br>
+ * 5. Teleport all participants to team spot<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startFight()
+ {
+ // Set state to STARTING
+ setState(EventState.STARTING);
+
+ // Check for enought participants
+ if (_participants.size() < Config.DM_EVENT_MIN_PLAYERS)
+ {
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ // Cleanup of participants
+ _participants.clear();
+ // Unspawn the event NPC
+ unSpawnNpc();
+ AntiFeedManager.getInstance().clear(AntiFeedManager.DM_ID);
+ return false;
+ }
+
+ if (Config.DM_EVENT_IN_INSTANCE)
+ {
+ try
+ {
+ _DMEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.DM_EVENT_INSTANCE_FILE);
+ InstanceManager.getInstance().getInstance(_DMEventInstance).setAllowSummon(false);
+ InstanceManager.getInstance().getInstance(_DMEventInstance).setPvPInstance(true);
+ InstanceManager.getInstance().getInstance(_DMEventInstance).setEmptyDestroyTime((Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L);
+ }
+ catch (Exception e)
+ {
+ _DMEventInstance = 0;
+ _log.log(Level.WARNING, "DMEventEngine[DMEvent.createDynamicInstance]: exception: " + e.getMessage(), e);
+ }
+ }
+
+ // Opens all doors specified in configs for DM
+ openDoors(Config.DM_DOORS_IDS_TO_OPEN);
+ // Closes all doors specified in configs for DM
+ closeDoors(Config.DM_DOORS_IDS_TO_CLOSE);
+ // Set state STARTED
+ setState(EventState.STARTED);
+
+ // Iterate over all teams
+ for (DMEventPlayer player : _participants.values())
+ {
+ if (player != null)
+ {
+ // Disable player revival.
+ player.setCanRevive(false);
+ // Teleporter implements Runnable and starts itself
+ new DMEventTeleporter(player.getPlayer(), Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventStart());
+ return true;
+ }
+
+ /**
+ * Calculates the DMEvent reward<br>
+ * 1. If both teams are at a tie(points equals), send it as system message to all participants, if one of the teams have 0 participants left online abort rewarding<br>
+ * 2. Wait till teams are not at a tie anymore<br>
+ * 3. Set state EvcentState.REWARDING<br>
+ * 4. Reward team with more points<br>
+ * 5. Show win html to wining team participants<br>
+ * <br>
+ * @return String: winning team name<br>
+ */
+ public static String calculateRewards()
+ {
+ TreeSet<DMEventPlayer> players = orderPosition(_participants.values());
+ for (int j = 0; j < Config.DM_EVENT_REWARD_FIRST_PLAYERS; j++)
+ {
+ if (players.isEmpty())
+ {
+ break;
+ }
+
+ DMEventPlayer player = players.first();
+
+ if (player.getPoints() == 0)
+ {
+ break;
+ }
+
+ rewardPlayer(player, j + 1);
+ players.remove(player);
+ int playerPointPrev = player.getPoints();
+
+ if (!Config.DM_REWARD_TEAM_TIE)
+ {
+ continue;
+ }
+
+ while (!players.isEmpty())
+ {
+ player = players.first();
+ if (player.getPoints() != playerPointPrev)
+ {
+ break;
+ }
+
+ rewardPlayer(player, j + 1);
+ players.remove(player);
+ }
+ }
+
+ // Set state REWARDING so nobody can point anymore
+ setState(EventState.REWARDING);
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventFinish());
+
+ return "DM Event ended, thanks to everyone who participated!";
+ }
+
+ /**
+ * @param listPlayer
+ * @return
+ */
+ private static TreeSet<DMEventPlayer> orderPosition(Collection<DMEventPlayer> listPlayer)
+ {
+ TreeSet<DMEventPlayer> players = new TreeSet<>((p1, p2) ->
+ {
+ Integer c1 = Integer.valueOf(p2.getPoints() - p1.getPoints());
+ Integer c2 = Integer.valueOf(p1.getDeath() - p2.getDeath());
+ Integer c3 = p1.getHexCode().compareTo(p2.getHexCode());
+
+ if (c1 == 0)
+ {
+ if (c2 == 0)
+ {
+ return c3;
+ }
+
+ return c2;
+ }
+
+ return c1;
+ });
+
+ players.addAll(listPlayer);
+ return players;
+ }
+
+ private static void rewardPlayer(DMEventPlayer p, int pos)
+ {
+ L2PcInstance activeChar = p.getPlayer();
+
+ // Check for nullpointer
+ if (activeChar == null)
+ {
+ return;
+ }
+
+ // Add Fireworks for rewarded player
+ activeChar.broadcastPacket(new MagicSkillUse(activeChar, activeChar, CommonSkill.FIREWORK.getSkill().getId(), 1, 1, 1));
+
+ SystemMessage systemMessage = null;
+
+ // Iterate over all DM event rewards
+ List<int[]> rewards = Config.DM_EVENT_REWARDS.get(pos);
+ for (int[] reward : rewards)
+ {
+ PcInventory inv = activeChar.getInventory();
+
+ // Check for stackable item, non stackabe items need to be added one by one
+ if (ItemTable.getInstance().getTemplate(reward[0]).isStackable())
+ {
+ inv.addItem("DM Event", reward[0], reward[1], activeChar, activeChar);
+
+ if (reward[1] > 1)
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+ systemMessage.addItemName(reward[0]);
+ systemMessage.addLong(reward[1]);
+ }
+ else
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ }
+
+ activeChar.sendPacket(systemMessage);
+ }
+ else
+ {
+ for (int i = 0; i < reward[1]; ++i)
+ {
+ inv.addItem("DM Event", reward[0], 1, activeChar, activeChar);
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ activeChar.sendPacket(systemMessage);
+ }
+ }
+ }
+
+ StatusUpdate statusUpdate = new StatusUpdate(activeChar);
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, activeChar.getCurrentLoad());
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), htmlPath + "Reward.html"));
+ activeChar.sendPacket(statusUpdate);
+ activeChar.sendPacket(npcHtmlMessage);
+ }
+
+ /**
+ * Stops the DMEvent fight<br>
+ * 1. Set state EventState.INACTIVATING<br>
+ * 2. Remove DM npc from world<br>
+ * 3. Open doors specified in configs<br>
+ * 4. Teleport all participants back to participation npc location<br>
+ * 5. Teams cleaning<br>
+ * 6. Set state EventState.INACTIVE<br>
+ */
+ public static void stopFight()
+ {
+ // Set state INACTIVATING
+ setState(EventState.INACTIVATING);
+ // Unspawn event npc
+ unSpawnNpc();
+ // Opens all doors specified in configs for DM
+ openDoors(Config.DM_DOORS_IDS_TO_CLOSE);
+ // Closes all doors specified in Configs for DM
+ closeDoors(Config.DM_DOORS_IDS_TO_OPEN);
+
+ String[] topPositions;
+ String htmltext = "";
+ if (Config.DM_EVENT_SHOW_TOP_RANK)
+ {
+ topPositions = getFirstPosition(Config.DM_EVENT_LIST_TOP_RANK);
+ Boolean c = true;
+ String c1 = "D9CC46";
+ String c2 = "FFFFFF";
+ if (topPositions != null)
+ {
+ for (int i = 0; i < topPositions.length; i++)
+ {
+ String color = (c ? c1 : c2);
+ String[] row = topPositions[i].split("\\,");
+ htmltext += "<tr>";
+ htmltext += "<td width=\"35\" align=\"center\"><font color=\"" + color + "\">" + String.valueOf(i + 1) + "</font></td>";
+ htmltext += "<td width=\"100\" align=\"left\"><font color=\"" + color + "\">" + row[0] + "</font></td>";
+ htmltext += "<td width=\"125\" align=\"right\"><font color=\"" + color + "\">" + row[1] + "</font></td>";
+ htmltext += "</tr>";
+ c = !c;
+ }
+ }
+ }
+
+ // Iterate over all teams
+ for (DMEventPlayer player : _participants.values())
+ {
+ // Check for nullpointer
+ if (player != null)
+ {
+ // Top Rank
+ if (Config.DM_EVENT_SHOW_TOP_RANK)
+ {
+ NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage(0);
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(player.getPlayer().getHtmlPrefix(), htmlPath + "TopRank.htm"));
+ npcHtmlMessage.replace("%toprank%", htmltext);
+ player.getPlayer().sendPacket(npcHtmlMessage);
+ }
+
+ player.setCanRevive(true);
+ new DMEventTeleporter(player.getPlayer(), Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+
+ // Cleanup list
+ _participants = new FastMap<>();
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.DM_ID);
+ }
+
+ public static String[] getFirstPosition(int countPos)
+ {
+ TreeSet<DMEventPlayer> players = orderPosition(_participants.values());
+ String text = "";
+ for (int j = 0; j < countPos; j++)
+ {
+ if (players.isEmpty())
+ {
+ break;
+ }
+
+ DMEventPlayer player = players.first();
+ if (player.getPoints() == 0)
+ {
+ break;
+ }
+
+ text += player.getPlayer().getName() + "," + String.valueOf(player.getPoints()) + ";";
+ players.remove(player);
+
+ int playerPointPrev = player.getPoints();
+
+ if (!Config.DM_REWARD_TEAM_TIE)
+ {
+ continue;
+ }
+
+ while (!players.isEmpty())
+ {
+ player = players.first();
+ if (player.getPoints() != playerPointPrev)
+ {
+ break;
+ }
+
+ text += player.getPlayer().getName() + "," + String.valueOf(player.getPoints()) + ";";
+ players.remove(player);
+ }
+ }
+
+ if (text != "")
+ {
+ return text.split("\\;");
+ }
+
+ return null;
+ }
+
+ /**
+ * Adds a player to a DMEvent team<br>
+ * 1. Calculate the id of the team in which the player should be added<br>
+ * 2. Add the player to the calculated team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static synchronized boolean addParticipant(L2PcInstance playerInstance)
+ {
+ // Check for nullpoitner
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ if (isPlayerParticipant(playerInstance))
+ {
+ return false;
+ }
+
+ String hexCode = hexToString(generateHex(16));
+ _participants.put(playerInstance.getObjectId(), new DMEventPlayer(playerInstance, null, hexCode));
+ playerInstance.addEventListener(new DMEventListener(playerInstance));
+ return true;
+ }
+
+ /**
+ * Removes a DMEvent player from it's team<br>
+ * 1. Get team id of the player<br>
+ * 2. Remove player from it's team<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if success, otherwise false
+ */
+ public static boolean removeParticipant(int playerObjectId)
+ {
+ // Check if the player is participant
+ final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
+ if (player != null)
+ {
+ player.removeEventListener(DMEventListener.class);
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean needParticipationFee()
+ {
+ return (Config.DM_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.DM_EVENT_PARTICIPATION_FEE[1] != 0);
+ }
+
+ public static boolean hasParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.getInventory().getInventoryItemCount(Config.DM_EVENT_PARTICIPATION_FEE[0], -1) >= Config.DM_EVENT_PARTICIPATION_FEE[1];
+ }
+
+ public static boolean payParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.destroyItemByItemId("DM Participation Fee", Config.DM_EVENT_PARTICIPATION_FEE[0], Config.DM_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
+ }
+
+ public static String getParticipationFee()
+ {
+ int itemId = Config.DM_EVENT_PARTICIPATION_FEE[0];
+ int itemNum = Config.DM_EVENT_PARTICIPATION_FEE[1];
+
+ if ((itemId == 0) || (itemNum == 0))
+ {
+ return "-";
+ }
+
+ return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
+ }
+
+ /**
+ * Send a SystemMessage to all participated players<br>
+ * 1. Send the message to all players of team number one<br>
+ * 2. Send the message to all players of team number two<br>
+ * <br>
+ * @param message as String<br>
+ */
+ public static void sysMsgToAllParticipants(String message)
+ {
+ for (DMEventPlayer player : _participants.values())
+ {
+ if (player != null)
+ {
+ player.getPlayer().sendMessage(message);
+ }
+ }
+ }
+
+ private static L2DoorInstance getDoor(int doorId)
+ {
+ L2DoorInstance door = null;
+ if (_DMEventInstance <= 0)
+ {
+ door = DoorData.getInstance().getDoor(doorId);
+ }
+ else
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(_DMEventInstance);
+ if (inst != null)
+ {
+ door = inst.getDoor(doorId);
+ }
+ }
+ return door;
+ }
+
+ /**
+ * Close doors specified in configs
+ * @param doors
+ */
+ private static void closeDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.closeMe();
+ }
+ }
+ }
+
+ /**
+ * Open doors specified in configs
+ * @param doors
+ */
+ private static void openDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.openMe();
+ }
+ }
+ }
+
+ /**
+ * UnSpawns the DMEvent npc
+ */
+ private static void unSpawnNpc()
+ {
+ // Delete the npc
+ _lastNpcSpawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
+ // Stop respawning of the npc
+ _npcSpawn.stopRespawn();
+ _npcSpawn = null;
+ _lastNpcSpawn = null;
+ }
+
+ /**
+ * Called when a player logs in<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogin(L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || (!isStarting() && !isStarted()))
+ {
+ return;
+ }
+
+ if (!isPlayerParticipant(playerInstance))
+ {
+ return;
+ }
+
+ new DMEventTeleporter(playerInstance.getActingPlayer(), Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, true, false);
+ // new DMEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
+ }
+
+ /**
+ * Called when a player logs out<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogout(L2PcInstance playerInstance)
+ {
+ if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
+ {
+ if (removeParticipant(playerInstance.getObjectId()))
+ {
+ playerInstance.setXYZInvisible((Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[0] + Rnd.get(101)) - 50, (Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[1] + Rnd.get(101)) - 50, Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ }
+ }
+ }
+
+ /**
+ * Called on every onAction in L2PcIstance<br>
+ * <br>
+ * @param playerInstance
+ * @param targetedPlayerObjectId
+ * @return boolean: true if player is allowed to target, otherwise false
+ */
+ public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
+ {
+ if ((playerInstance == null) || !isStarted())
+ {
+ return true;
+ }
+
+ if (playerInstance.isGM())
+ {
+ return true;
+ }
+
+ if (!isPlayerParticipant(playerInstance) && isPlayerParticipant(targetedPlayerObjectId))
+ {
+ return false;
+ }
+
+ if (isPlayerParticipant(playerInstance) && !isPlayerParticipant(targetedPlayerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every scroll use<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use scroll, otherwise false
+ */
+ public static boolean onScrollUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.DM_EVENT_SCROLL_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every potion use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use potions, otherwise false
+ */
+ public static boolean onPotionUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.DM_EVENT_POTIONS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every escape use(thanks to nbd)
+ * @param playerObjectId
+ * @return boolean: true if player is not in DM event, otherwise false
+ */
+ public static boolean onEscapeUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every summon item use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to summon by item, otherwise false
+ */
+ public static boolean onItemSummon(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.DM_EVENT_SUMMON_BY_ITEM_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is called when a player is killed<br>
+ * <br>
+ * @param killerCharacter as L2Character<br>
+ * @param killedPlayerInstance as L2PcInstance<br>
+ */
+ public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
+ {
+ if ((killedPlayerInstance == null) || !isStarted())
+ {
+ return;
+ }
+
+ new DMEventTeleporter(killedPlayerInstance, Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+
+ if (killerCharacter == null)
+ {
+ return;
+ }
+
+ L2PcInstance killerPlayerInstance = null;
+
+ if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
+ {
+ killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
+
+ if (killerPlayerInstance == null)
+ {
+ return;
+ }
+ }
+ else if (killerCharacter instanceof L2PcInstance)
+ {
+ killerPlayerInstance = (L2PcInstance) killerCharacter;
+ }
+ else
+ {
+ return;
+ }
+
+ if (isPlayerParticipant(killerPlayerInstance))
+ {
+ _participants.get(killerPlayerInstance.getObjectId()).increasePoints();
+ killerPlayerInstance.sendPacket(new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!"));
+
+ _participants.get(killedPlayerInstance.getObjectId()).increaseDeath();
+ killedPlayerInstance.sendPacket(new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I killed you!"));
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventKill(killerPlayerInstance, killedPlayerInstance, null));
+ }
+ }
+
+ /**
+ * Called on Appearing packet received (player finished teleporting)
+ * @param playerInstance
+ */
+ public static void onTeleported(L2PcInstance playerInstance)
+ {
+ if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
+ {
+ return;
+ }
+
+ if (playerInstance.isMageClass())
+ {
+ if ((Config.DM_EVENT_MAGE_BUFFS != null) && !Config.DM_EVENT_MAGE_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.DM_EVENT_MAGE_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((Config.DM_EVENT_FIGHTER_BUFFS != null) && !Config.DM_EVENT_FIGHTER_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.DM_EVENT_FIGHTER_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param source
+ * @param target
+ * @param skill
+ * @return true if player valid for skill
+ */
+ public static final boolean checkForDMSkill(L2PcInstance source, L2PcInstance target, Skill skill)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+ // DM is started
+ final int sourcePlayerId = source.getObjectId();
+ final int targetPlayerId = target.getObjectId();
+ final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
+ final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
+
+ // both players not participating
+ if (!isSourceParticipant && !isTargetParticipant)
+ {
+ return true;
+ }
+ // one player not participating
+ if (!(isSourceParticipant && isTargetParticipant))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets the DMEvent state<br>
+ * <br>
+ * @param state as EventState<br>
+ */
+ private static void setState(EventState state)
+ {
+ synchronized (_state)
+ {
+ _state = state;
+ }
+ }
+
+ /**
+ * Is DMEvent inactive?<br>
+ * <br>
+ * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
+ */
+ public static boolean isInactive()
+ {
+ boolean isInactive;
+
+ synchronized (_state)
+ {
+ isInactive = _state == EventState.INACTIVE;
+ }
+
+ return isInactive;
+ }
+
+ /**
+ * Is DMEvent in inactivating?<br>
+ * <br>
+ * @return boolean: true if event is in inactivating progress, otherwise false<br>
+ */
+ public static boolean isInactivating()
+ {
+ boolean isInactivating;
+
+ synchronized (_state)
+ {
+ isInactivating = _state == EventState.INACTIVATING;
+ }
+
+ return isInactivating;
+ }
+
+ /**
+ * Is DMEvent in participation?<br>
+ * <br>
+ * @return boolean: true if event is in participation progress, otherwise false<br>
+ */
+ public static boolean isParticipating()
+ {
+ boolean isParticipating;
+
+ synchronized (_state)
+ {
+ isParticipating = _state == EventState.PARTICIPATING;
+ }
+
+ return isParticipating;
+ }
+
+ /**
+ * Is DMEvent starting?<br>
+ * <br>
+ * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
+ */
+ public static boolean isStarting()
+ {
+ boolean isStarting;
+
+ synchronized (_state)
+ {
+ isStarting = _state == EventState.STARTING;
+ }
+
+ return isStarting;
+ }
+
+ /**
+ * Is DMEvent started?<br>
+ * <br>
+ * @return boolean: true if event is started, otherwise false<br>
+ */
+ public static boolean isStarted()
+ {
+ boolean isStarted;
+
+ synchronized (_state)
+ {
+ isStarted = _state == EventState.STARTED;
+ }
+
+ return isStarted;
+ }
+
+ /**
+ * Is DMEvent rewarding?<br>
+ * <br>
+ * @return boolean: true if event is currently rewarding, otherwise false<br>
+ */
+ public static boolean isRewarding()
+ {
+ boolean isRewarding;
+
+ synchronized (_state)
+ {
+ isRewarding = _state == EventState.REWARDING;
+ }
+
+ return isRewarding;
+ }
+
+ public static boolean isPlayerParticipant(L2PcInstance activeChar)
+ {
+ if (activeChar == null)
+ {
+ return false;
+ }
+
+ try
+ {
+ if (_participants.containsKey(activeChar.getObjectId()))
+ {
+ return true;
+ }
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+
+ return false;
+ }
+
+ /**
+ * Is given player participant of the event?
+ * @param objectId
+ * @return boolean: true if player is participant, ohterwise false
+ */
+ public static boolean isPlayerParticipant(int objectId)
+ {
+ L2PcInstance activeChar = L2World.getInstance().getPlayer(objectId);
+ if (activeChar == null)
+ {
+ return false;
+ }
+
+ return isPlayerParticipant(activeChar);
+ }
+
+ public static byte[] generateHex(int size)
+ {
+ byte[] array = new byte[size];
+ Rnd.nextBytes(array);
+ return array;
+ }
+
+ public static String hexToString(byte[] hex)
+ {
+ return new BigInteger(hex).toString(16);
+ }
+
+ public static int getDMEventInstance()
+ {
+ return _DMEventInstance;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventListener.java (working copy)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class DMEventListener implements IEventListener
+{
+ private final L2PcInstance _player;
+
+ protected DMEventListener(L2PcInstance player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return DMEvent.isStarted() && DMEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ @Override
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventPlayer.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventPlayer.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventPlayer.java (working copy)
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class DMEventPlayer
+{
+ private final L2PcInstance _player;
+ private short _points;
+ private short _death;
+ private final String _hexCode;
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ public DMEventPlayer(L2PcInstance player, int[] coordinates, String hexCode)
+ {
+ _player = player;
+ _points = 0;
+ _death = 0;
+ _hexCode = hexCode;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ public boolean isOnEvent()
+ {
+ return DMEvent.isStarted() && DMEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ /**
+ * This method can prevent from displaying 'To Village' button upon death.
+ * @param val
+ */
+ public void setCanRevive(boolean val)
+ {
+ }
+
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ _death = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * @return the _death
+ */
+ public short getDeath()
+ {
+ return _death;
+ }
+
+ /**
+ * @param death the _death to set
+ */
+ public void setDeath(short death)
+ {
+ _death = death;
+ }
+
+ /**
+ * Increases the death of the player<br>
+ */
+ public void increaseDeath()
+ {
+ ++_death;
+ }
+
+ /**
+ * @return the _hexCode
+ */
+ public String getHexCode()
+ {
+ return _hexCode;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author HorridoJoho
+ */
+public class DMEventTeam
+{
+ /** The name of the team<br> */
+ private final String _name;
+ /** The team spot coordinated<br> */
+ private int[] _coordinates = new int[3];
+ /** The points of the team<br> */
+ private short _points;
+ /** Name and instance of all participated players in FastMap<br> */
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ /**
+ * C'tor initialize the team<br>
+ * <br>
+ * @param name as String<br>
+ * @param coordinates as int[]<br>
+ */
+ public DMEventTeam(String name, int[] coordinates)
+ {
+ _name = name;
+ _coordinates = coordinates;
+ _points = 0;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes a player from the team
+ * @param playerObjectId
+ */
+ public void removePlayer(int playerObjectId)
+ {
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.remove(playerObjectId);
+ }
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * Returns the name of the team<br>
+ * <br>
+ * @return String: name of the team<br>
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the coordinates of the team spot<br>
+ * <br>
+ * @return int[]: team coordinates<br>
+ */
+ public int[] getCoordinates()
+ {
+ return _coordinates;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeleporter.java (working copy)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.Team;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Duel;
+import com.l2jserver.util.Rnd;
+
+public class DMEventTeleporter implements Runnable
+{
+ /** The instance of the player to teleport */
+ private L2PcInstance _playerInstance = null;
+ /** Coordinates of the spot to teleport to */
+ private int[] _coordinates = new int[3];
+ /** Admin removed this player from event */
+ private boolean _adminRemove = false;
+
+ /**
+ * Initialize the teleporter and start the delayed task.
+ * @param playerInstance
+ * @param coordinates
+ * @param fastSchedule
+ * @param adminRemove
+ */
+ public DMEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
+ {
+ _playerInstance = playerInstance;
+ _coordinates = coordinates;
+ _adminRemove = adminRemove;
+
+ long delay = (DMEvent.isStarted() ? Config.DM_EVENT_RESPAWN_TELEPORT_DELAY : Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
+
+ ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
+ }
+
+ /**
+ * The task method to teleport the player<br>
+ * 1. Unsummon pet if there is one<br>
+ * 2. Remove all effects<br>
+ * 3. Revive and full heal the player<br>
+ * 4. Teleport the player<br>
+ * 5. Broadcast status and user info
+ */
+ @Override
+ public void run()
+ {
+ if (_playerInstance == null)
+ {
+ return;
+ }
+
+ L2Summon summon = _playerInstance.getSummon();
+
+ if (summon != null)
+ {
+ summon.unSummon(_playerInstance);
+ }
+
+ if ((Config.DM_EVENT_EFFECTS_REMOVAL == 0) || ((Config.DM_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
+ {
+ _playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
+ }
+
+ if (_playerInstance.isInDuel())
+ {
+ _playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
+ }
+
+ int DMInstance = DMEvent.getDMEventInstance();
+ if (DMInstance != 0)
+ {
+ if (DMEvent.isStarted() && !_adminRemove)
+ {
+ _playerInstance.setInstanceId(DMInstance);
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+
+ _playerInstance.doRevive();
+
+ _playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
+
+ _playerInstance.setCurrentCp(_playerInstance.getMaxCp());
+ _playerInstance.setCurrentHp(_playerInstance.getMaxHp());
+ _playerInstance.setCurrentMp(_playerInstance.getMaxMp());
+
+ _playerInstance.broadcastStatusUpdate();
+ _playerInstance.broadcastUserInfo();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMManager.java (working copy)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author HorridoJoho
+ */
+public class DMManager
+{
+ protected static final Logger _log = Logger.getLogger(DMManager.class.getName());
+
+ /** Task for event cycles<br> */
+ private DMStartTask _task;
+
+ /**
+ * New instance only by getInstance()<br>
+ */
+ protected DMManager()
+ {
+ if (Config.DM_EVENT_ENABLED)
+ {
+ DMEvent.init();
+
+ scheduleEventStart();
+ _log.info("DMEventEngine[DMManager.DMManager()]: Started.");
+ }
+ else
+ {
+ _log.info("DMEventEngine[DMManager.DMManager()]: Engine is disabled.");
+ }
+ }
+
+ /**
+ * Initialize new/Returns the one and only instance<br>
+ * <br>
+ * @return DMManager<br>
+ */
+ public static DMManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ /**
+ * Starts DMStartTask
+ */
+ public void scheduleEventStart()
+ {
+ try
+ {
+ Calendar currentTime = Calendar.getInstance();
+ Calendar nextStartTime = null;
+ Calendar testStartTime = null;
+ for (String timeOfDay : Config.DM_EVENT_INTERVAL)
+ {
+ // Creating a Calendar object from the specified interval value
+ testStartTime = Calendar.getInstance();
+ testStartTime.setLenient(true);
+ String[] splitTimeOfDay = timeOfDay.split(":");
+ testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+ testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+ // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
+ if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+ {
+ testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ // Check for the test date to be the minimum (smallest in the specified list)
+ if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
+ {
+ nextStartTime = testStartTime;
+ }
+ }
+ if (nextStartTime != null)
+ {
+ _task = new DMStartTask(nextStartTime.getTimeInMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+ catch (Exception e)
+ {
+ _log.warning("DMEventEngine[DMManager.scheduleEventStart()]: Error figuring out a start time. Check DMEventInterval in config file.");
+ }
+ }
+
+ /**
+ * Method to start participation
+ */
+ public void startReg()
+ {
+ if (!DMEvent.startParticipation())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: Event was cancelled.");
+ _log.warning("DMEventEngine[DMManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: Registration opened for " + Config.DM_EVENT_PARTICIPATION_TIME + " minute(s).");
+
+ // schedule registration end
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.DM_EVENT_PARTICIPATION_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to start the fight
+ */
+ public void startEvent()
+ {
+ if (!DMEvent.startFight())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: Event cancelled due to lack of Participation.");
+ _log.info("DMEventEngine[DMManager.run()]: Lack of registration, abort event.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: Teleporting participants to an arena in " + Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.DM_EVENT_RUNNING_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to end the event and reward
+ */
+ public void endEvent()
+ {
+ Broadcast.toAllOnlinePlayers(DMEvent.calculateRewards());
+ DMEvent.sysMsgToAllParticipants("DM Event: Teleporting back to the registration npc in " + Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ DMEvent.stopFight();
+
+ scheduleEventStart();
+ }
+
+ public void skipDelay()
+ {
+ if (_task.nextRun.cancel(false))
+ {
+ _task.setStartTime(System.currentTimeMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Class for DM cycles
+ */
+ class DMStartTask implements Runnable
+ {
+ private long _startTime;
+ public ScheduledFuture<?> nextRun;
+
+ public DMStartTask(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ public void setStartTime(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ @Override
+ public void run()
+ {
+ int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+
+ if (delay > 0)
+ {
+ announce(delay);
+ }
+
+ int nextMsg = 0;
+ if (delay > 3600)
+ {
+ nextMsg = delay - 3600;
+ }
+ else if (delay > 1800)
+ {
+ nextMsg = delay - 1800;
+ }
+ else if (delay > 900)
+ {
+ nextMsg = delay - 900;
+ }
+ else if (delay > 600)
+ {
+ nextMsg = delay - 600;
+ }
+ else if (delay > 300)
+ {
+ nextMsg = delay - 300;
+ }
+ else if (delay > 60)
+ {
+ nextMsg = delay - 60;
+ }
+ else if (delay > 5)
+ {
+ nextMsg = delay - 5;
+ }
+ else if (delay > 0)
+ {
+ nextMsg = delay;
+ }
+ else
+ {
+ // start
+ if (DMEvent.isInactive())
+ {
+ startReg();
+ }
+ else if (DMEvent.isParticipating())
+ {
+ startEvent();
+ }
+ else
+ {
+ endEvent();
+ }
+ }
+
+ if (delay > 0)
+ {
+ nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+ }
+ }
+
+ private void announce(long time)
+ {
+ if ((time >= 3600) && ((time % 3600) == 0))
+ {
+ if (DMEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
+ }
+ else if (DMEvent.isStarted())
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
+ }
+ }
+ else if (time >= 60)
+ {
+ if (DMEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: " + (time / 60) + " minute(s) until registration is closed!");
+ }
+ else if (DMEvent.isStarted())
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: " + (time / 60) + " minute(s) until the event is finished!");
+ }
+ }
+ else
+ {
+ if (DMEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: " + time + " second(s) until registration is closed!");
+ }
+ else if (DMEvent.isStarted())
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: " + time + " second(s) until the event is finished!");
+ }
+ }
+ }
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final DMManager _instance = new DMManager();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEvent.java (working copy)
@@ -0,0 +1,1091 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.data.xml.impl.DoorData;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.SkillData;
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
+import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventStart;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.skills.CommonSkill;
+import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author HorridoJoho
+ */
+public class DMEvent
+{
+ enum EventState
+ {
+ INACTIVE,
+ INACTIVATING,
+ PARTICIPATING,
+ STARTING,
+ STARTED,
+ REWARDING
+ }
+
+ protected static final Logger _log = Logger.getLogger(DMEvent.class.getName());
+ /** html path **/
+ private static final String htmlPath = "data/scripts/custom/events/DM/DMManager/";
+ /** The state of the DMEvent<br> */
+ private static EventState _state = EventState.INACTIVE;
+ /** The spawn of the participation npc<br> */
+ private static L2Spawn _npcSpawn = null;
+ /** the npc instance of the participation npc<br> */
+ private static L2Npc _lastNpcSpawn = null;
+ /** Instance id<br> */
+ private static int _DMEventInstance = 0;
+ /** Players of the DMEvent<br> */
+ private static Map<Integer, DMEventPlayer> _participants = new FastMap<>();
+
+ /**
+ * No instance of this class!<br>
+ */
+ private DMEvent()
+ {
+ }
+
+ /**
+ * Teams initializing<br>
+ */
+ public static void init()
+ {
+ AntiFeedManager.getInstance().registerEvent(AntiFeedManager.DM_ID);
+ }
+
+ /**
+ * Starts the participation of the DMEvent<br>
+ * 1. Get L2NpcTemplate by Config.DM_EVENT_PARTICIPATION_NPC_ID<br>
+ * 2. Try to spawn a new npc of it<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startParticipation()
+ {
+ try
+ {
+ _npcSpawn = new L2Spawn(Config.DM_EVENT_PARTICIPATION_NPC_ID);
+
+ _npcSpawn.setX(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[0]);
+ _npcSpawn.setY(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[1]);
+ _npcSpawn.setZ(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ _npcSpawn.setAmount(1);
+ _npcSpawn.setHeading(Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[3]);
+ _npcSpawn.setRespawnDelay(1);
+ // later no need to delete spawn from db, we don't store it (false)
+ SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
+ _npcSpawn.init();
+ _lastNpcSpawn = _npcSpawn.getLastSpawn();
+ _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
+ _lastNpcSpawn.setTitle("DM Event Participation");
+ _lastNpcSpawn.isAggressive();
+ _lastNpcSpawn.decayMe();
+ _lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
+ _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "DMEventEngine[DMEvent.startParticipation()]: exception: " + e.getMessage(), e);
+ return false;
+ }
+
+ setState(EventState.PARTICIPATING);
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventRegistrationStart());
+ return true;
+ }
+
+ /**
+ * Starts the DMEvent fight<br>
+ * 1. Set state EventState.STARTING<br>
+ * 2. Close doors specified in configs<br>
+ * 3. Abort if not enought participants(return false)<br>
+ * 4. Set state EventState.STARTED<br>
+ * 5. Teleport all participants to team spot<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startFight()
+ {
+ // Set state to STARTING
+ setState(EventState.STARTING);
+
+ // Check for enought participants
+ if (_participants.size() < Config.DM_EVENT_MIN_PLAYERS)
+ {
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ // Cleanup of participants
+ _participants.clear();
+ // Unspawn the event NPC
+ unSpawnNpc();
+ AntiFeedManager.getInstance().clear(AntiFeedManager.DM_ID);
+ return false;
+ }
+
+ if (Config.DM_EVENT_IN_INSTANCE)
+ {
+ try
+ {
+ _DMEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.DM_EVENT_INSTANCE_FILE);
+ InstanceManager.getInstance().getInstance(_DMEventInstance).setAllowSummon(false);
+ InstanceManager.getInstance().getInstance(_DMEventInstance).setPvPInstance(true);
+ InstanceManager.getInstance().getInstance(_DMEventInstance).setEmptyDestroyTime((Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L);
+ }
+ catch (Exception e)
+ {
+ _DMEventInstance = 0;
+ _log.log(Level.WARNING, "DMEventEngine[DMEvent.createDynamicInstance]: exception: " + e.getMessage(), e);
+ }
+ }
+
+ // Opens all doors specified in configs for DM
+ openDoors(Config.DM_DOORS_IDS_TO_OPEN);
+ // Closes all doors specified in configs for DM
+ closeDoors(Config.DM_DOORS_IDS_TO_CLOSE);
+ // Set state STARTED
+ setState(EventState.STARTED);
+
+ // Iterate over all teams
+ for (DMEventPlayer player : _participants.values())
+ {
+ if (player != null)
+ {
+ // Disable player revival.
+ player.setCanRevive(false);
+ // Teleporter implements Runnable and starts itself
+ new DMEventTeleporter(player.getPlayer(), Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventStart());
+ return true;
+ }
+
+ /**
+ * Calculates the DMEvent reward<br>
+ * 1. If both teams are at a tie(points equals), send it as system message to all participants, if one of the teams have 0 participants left online abort rewarding<br>
+ * 2. Wait till teams are not at a tie anymore<br>
+ * 3. Set state EvcentState.REWARDING<br>
+ * 4. Reward team with more points<br>
+ * 5. Show win html to wining team participants<br>
+ * <br>
+ * @return String: winning team name<br>
+ */
+ public static String calculateRewards()
+ {
+ TreeSet<DMEventPlayer> players = orderPosition(_participants.values());
+ for (int j = 0; j < Config.DM_EVENT_REWARD_FIRST_PLAYERS; j++)
+ {
+ if (players.isEmpty())
+ {
+ break;
+ }
+
+ DMEventPlayer player = players.first();
+
+ if (player.getPoints() == 0)
+ {
+ break;
+ }
+
+ rewardPlayer(player, j + 1);
+ players.remove(player);
+ int playerPointPrev = player.getPoints();
+
+ if (!Config.DM_REWARD_TEAM_TIE)
+ {
+ continue;
+ }
+
+ while (!players.isEmpty())
+ {
+ player = players.first();
+ if (player.getPoints() != playerPointPrev)
+ {
+ break;
+ }
+
+ rewardPlayer(player, j + 1);
+ players.remove(player);
+ }
+ }
+
+ // Set state REWARDING so nobody can point anymore
+ setState(EventState.REWARDING);
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventFinish());
+
+ return "DM Event ended, thanks to everyone who participated!";
+ }
+
+ /**
+ * @param listPlayer
+ * @return
+ */
+ private static TreeSet<DMEventPlayer> orderPosition(Collection<DMEventPlayer> listPlayer)
+ {
+ TreeSet<DMEventPlayer> players = new TreeSet<>((p1, p2) ->
+ {
+ Integer c1 = Integer.valueOf(p2.getPoints() - p1.getPoints());
+ Integer c2 = Integer.valueOf(p1.getDeath() - p2.getDeath());
+ Integer c3 = p1.getHexCode().compareTo(p2.getHexCode());
+
+ if (c1 == 0)
+ {
+ if (c2 == 0)
+ {
+ return c3;
+ }
+
+ return c2;
+ }
+
+ return c1;
+ });
+
+ players.addAll(listPlayer);
+ return players;
+ }
+
+ private static void rewardPlayer(DMEventPlayer p, int pos)
+ {
+ L2PcInstance activeChar = p.getPlayer();
+
+ // Check for nullpointer
+ if (activeChar == null)
+ {
+ return;
+ }
+
+ // Add Fireworks for rewarded player
+ activeChar.broadcastPacket(new MagicSkillUse(activeChar, activeChar, CommonSkill.FIREWORK.getSkill().getId(), 1, 1, 1));
+
+ SystemMessage systemMessage = null;
+
+ // Iterate over all DM event rewards
+ List<int[]> rewards = Config.DM_EVENT_REWARDS.get(pos);
+ for (int[] reward : rewards)
+ {
+ PcInventory inv = activeChar.getInventory();
+
+ // Check for stackable item, non stackabe items need to be added one by one
+ if (ItemTable.getInstance().getTemplate(reward[0]).isStackable())
+ {
+ inv.addItem("DM Event", reward[0], reward[1], activeChar, activeChar);
+
+ if (reward[1] > 1)
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+ systemMessage.addItemName(reward[0]);
+ systemMessage.addLong(reward[1]);
+ }
+ else
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ }
+
+ activeChar.sendPacket(systemMessage);
+ }
+ else
+ {
+ for (int i = 0; i < reward[1]; ++i)
+ {
+ inv.addItem("DM Event", reward[0], 1, activeChar, activeChar);
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ activeChar.sendPacket(systemMessage);
+ }
+ }
+ }
+
+ StatusUpdate statusUpdate = new StatusUpdate(activeChar);
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, activeChar.getCurrentLoad());
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), htmlPath + "Reward.html"));
+ activeChar.sendPacket(statusUpdate);
+ activeChar.sendPacket(npcHtmlMessage);
+ }
+
+ /**
+ * Stops the DMEvent fight<br>
+ * 1. Set state EventState.INACTIVATING<br>
+ * 2. Remove DM npc from world<br>
+ * 3. Open doors specified in configs<br>
+ * 4. Teleport all participants back to participation npc location<br>
+ * 5. Teams cleaning<br>
+ * 6. Set state EventState.INACTIVE<br>
+ */
+ public static void stopFight()
+ {
+ // Set state INACTIVATING
+ setState(EventState.INACTIVATING);
+ // Unspawn event npc
+ unSpawnNpc();
+ // Opens all doors specified in configs for DM
+ openDoors(Config.DM_DOORS_IDS_TO_CLOSE);
+ // Closes all doors specified in Configs for DM
+ closeDoors(Config.DM_DOORS_IDS_TO_OPEN);
+
+ String[] topPositions;
+ String htmltext = "";
+ if (Config.DM_EVENT_SHOW_TOP_RANK)
+ {
+ topPositions = getFirstPosition(Config.DM_EVENT_LIST_TOP_RANK);
+ Boolean c = true;
+ String c1 = "D9CC46";
+ String c2 = "FFFFFF";
+ if (topPositions != null)
+ {
+ for (int i = 0; i < topPositions.length; i++)
+ {
+ String color = (c ? c1 : c2);
+ String[] row = topPositions[i].split("\\,");
+ htmltext += "<tr>";
+ htmltext += "<td width=\"35\" align=\"center\"><font color=\"" + color + "\">" + String.valueOf(i + 1) + "</font></td>";
+ htmltext += "<td width=\"100\" align=\"left\"><font color=\"" + color + "\">" + row[0] + "</font></td>";
+ htmltext += "<td width=\"125\" align=\"right\"><font color=\"" + color + "\">" + row[1] + "</font></td>";
+ htmltext += "</tr>";
+ c = !c;
+ }
+ }
+ }
+
+ // Iterate over all teams
+ for (DMEventPlayer player : _participants.values())
+ {
+ // Check for nullpointer
+ if (player != null)
+ {
+ // Top Rank
+ if (Config.DM_EVENT_SHOW_TOP_RANK)
+ {
+ NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage(0);
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(player.getPlayer().getHtmlPrefix(), htmlPath + "TopRank.htm"));
+ npcHtmlMessage.replace("%toprank%", htmltext);
+ player.getPlayer().sendPacket(npcHtmlMessage);
+ }
+
+ player.setCanRevive(true);
+ new DMEventTeleporter(player.getPlayer(), Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+
+ // Cleanup list
+ _participants = new FastMap<>();
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.DM_ID);
+ }
+
+ public static String[] getFirstPosition(int countPos)
+ {
+ TreeSet<DMEventPlayer> players = orderPosition(_participants.values());
+ String text = "";
+ for (int j = 0; j < countPos; j++)
+ {
+ if (players.isEmpty())
+ {
+ break;
+ }
+
+ DMEventPlayer player = players.first();
+ if (player.getPoints() == 0)
+ {
+ break;
+ }
+
+ text += player.getPlayer().getName() + "," + String.valueOf(player.getPoints()) + ";";
+ players.remove(player);
+
+ int playerPointPrev = player.getPoints();
+
+ if (!Config.DM_REWARD_TEAM_TIE)
+ {
+ continue;
+ }
+
+ while (!players.isEmpty())
+ {
+ player = players.first();
+ if (player.getPoints() != playerPointPrev)
+ {
+ break;
+ }
+
+ text += player.getPlayer().getName() + "," + String.valueOf(player.getPoints()) + ";";
+ players.remove(player);
+ }
+ }
+
+ if (text != "")
+ {
+ return text.split("\\;");
+ }
+
+ return null;
+ }
+
+ /**
+ * Adds a player to a DMEvent team<br>
+ * 1. Calculate the id of the team in which the player should be added<br>
+ * 2. Add the player to the calculated team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static synchronized boolean addParticipant(L2PcInstance playerInstance)
+ {
+ // Check for nullpoitner
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ if (isPlayerParticipant(playerInstance))
+ {
+ return false;
+ }
+
+ String hexCode = hexToString(generateHex(16));
+ _participants.put(playerInstance.getObjectId(), new DMEventPlayer(playerInstance, null, hexCode));
+ playerInstance.addEventListener(new DMEventListener(playerInstance));
+ return true;
+ }
+
+ /**
+ * Removes a DMEvent player from it's team<br>
+ * 1. Get team id of the player<br>
+ * 2. Remove player from it's team<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if success, otherwise false
+ */
+ public static boolean removeParticipant(int playerObjectId)
+ {
+ // Check if the player is participant
+ final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
+ if (player != null)
+ {
+ player.removeEventListener(DMEventListener.class);
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean needParticipationFee()
+ {
+ return (Config.DM_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.DM_EVENT_PARTICIPATION_FEE[1] != 0);
+ }
+
+ public static boolean hasParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.getInventory().getInventoryItemCount(Config.DM_EVENT_PARTICIPATION_FEE[0], -1) >= Config.DM_EVENT_PARTICIPATION_FEE[1];
+ }
+
+ public static boolean payParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.destroyItemByItemId("DM Participation Fee", Config.DM_EVENT_PARTICIPATION_FEE[0], Config.DM_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
+ }
+
+ public static String getParticipationFee()
+ {
+ int itemId = Config.DM_EVENT_PARTICIPATION_FEE[0];
+ int itemNum = Config.DM_EVENT_PARTICIPATION_FEE[1];
+
+ if ((itemId == 0) || (itemNum == 0))
+ {
+ return "-";
+ }
+
+ return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
+ }
+
+ /**
+ * Send a SystemMessage to all participated players<br>
+ * 1. Send the message to all players of team number one<br>
+ * 2. Send the message to all players of team number two<br>
+ * <br>
+ * @param message as String<br>
+ */
+ public static void sysMsgToAllParticipants(String message)
+ {
+ for (DMEventPlayer player : _participants.values())
+ {
+ if (player != null)
+ {
+ player.getPlayer().sendMessage(message);
+ }
+ }
+ }
+
+ private static L2DoorInstance getDoor(int doorId)
+ {
+ L2DoorInstance door = null;
+ if (_DMEventInstance <= 0)
+ {
+ door = DoorData.getInstance().getDoor(doorId);
+ }
+ else
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(_DMEventInstance);
+ if (inst != null)
+ {
+ door = inst.getDoor(doorId);
+ }
+ }
+ return door;
+ }
+
+ /**
+ * Close doors specified in configs
+ * @param doors
+ */
+ private static void closeDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.closeMe();
+ }
+ }
+ }
+
+ /**
+ * Open doors specified in configs
+ * @param doors
+ */
+ private static void openDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.openMe();
+ }
+ }
+ }
+
+ /**
+ * UnSpawns the DMEvent npc
+ */
+ private static void unSpawnNpc()
+ {
+ // Delete the npc
+ _lastNpcSpawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
+ // Stop respawning of the npc
+ _npcSpawn.stopRespawn();
+ _npcSpawn = null;
+ _lastNpcSpawn = null;
+ }
+
+ /**
+ * Called when a player logs in<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogin(L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || (!isStarting() && !isStarted()))
+ {
+ return;
+ }
+
+ if (!isPlayerParticipant(playerInstance))
+ {
+ return;
+ }
+
+ new DMEventTeleporter(playerInstance.getActingPlayer(), Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, true, false);
+ // new DMEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
+ }
+
+ /**
+ * Called when a player logs out<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogout(L2PcInstance playerInstance)
+ {
+ if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
+ {
+ if (removeParticipant(playerInstance.getObjectId()))
+ {
+ playerInstance.setXYZInvisible((Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[0] + Rnd.get(101)) - 50, (Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[1] + Rnd.get(101)) - 50, Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ }
+ }
+ }
+
+ /**
+ * Called on every onAction in L2PcIstance<br>
+ * <br>
+ * @param playerInstance
+ * @param targetedPlayerObjectId
+ * @return boolean: true if player is allowed to target, otherwise false
+ */
+ public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
+ {
+ if ((playerInstance == null) || !isStarted())
+ {
+ return true;
+ }
+
+ if (playerInstance.isGM())
+ {
+ return true;
+ }
+
+ if (!isPlayerParticipant(playerInstance) && isPlayerParticipant(targetedPlayerObjectId))
+ {
+ return false;
+ }
+
+ if (isPlayerParticipant(playerInstance) && !isPlayerParticipant(targetedPlayerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every scroll use<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use scroll, otherwise false
+ */
+ public static boolean onScrollUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.DM_EVENT_SCROLL_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every potion use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use potions, otherwise false
+ */
+ public static boolean onPotionUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.DM_EVENT_POTIONS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every escape use(thanks to nbd)
+ * @param playerObjectId
+ * @return boolean: true if player is not in DM event, otherwise false
+ */
+ public static boolean onEscapeUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every summon item use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to summon by item, otherwise false
+ */
+ public static boolean onItemSummon(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.DM_EVENT_SUMMON_BY_ITEM_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is called when a player is killed<br>
+ * <br>
+ * @param killerCharacter as L2Character<br>
+ * @param killedPlayerInstance as L2PcInstance<br>
+ */
+ public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
+ {
+ if ((killedPlayerInstance == null) || !isStarted())
+ {
+ return;
+ }
+
+ new DMEventTeleporter(killedPlayerInstance, Config.DM_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+
+ if (killerCharacter == null)
+ {
+ return;
+ }
+
+ L2PcInstance killerPlayerInstance = null;
+
+ if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
+ {
+ killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
+
+ if (killerPlayerInstance == null)
+ {
+ return;
+ }
+ }
+ else if (killerCharacter instanceof L2PcInstance)
+ {
+ killerPlayerInstance = (L2PcInstance) killerCharacter;
+ }
+ else
+ {
+ return;
+ }
+
+ if (isPlayerParticipant(killerPlayerInstance))
+ {
+ _participants.get(killerPlayerInstance.getObjectId()).increasePoints();
+ killerPlayerInstance.sendPacket(new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!"));
+
+ _participants.get(killedPlayerInstance.getObjectId()).increaseDeath();
+ killedPlayerInstance.sendPacket(new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I killed you!"));
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnDMEventKill(killerPlayerInstance, killedPlayerInstance, null));
+ }
+ }
+
+ /**
+ * Called on Appearing packet received (player finished teleporting)
+ * @param playerInstance
+ */
+ public static void onTeleported(L2PcInstance playerInstance)
+ {
+ if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
+ {
+ return;
+ }
+
+ if (playerInstance.isMageClass())
+ {
+ if ((Config.DM_EVENT_MAGE_BUFFS != null) && !Config.DM_EVENT_MAGE_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.DM_EVENT_MAGE_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((Config.DM_EVENT_FIGHTER_BUFFS != null) && !Config.DM_EVENT_FIGHTER_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.DM_EVENT_FIGHTER_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param source
+ * @param target
+ * @param skill
+ * @return true if player valid for skill
+ */
+ public static final boolean checkForDMSkill(L2PcInstance source, L2PcInstance target, Skill skill)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+ // DM is started
+ final int sourcePlayerId = source.getObjectId();
+ final int targetPlayerId = target.getObjectId();
+ final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
+ final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
+
+ // both players not participating
+ if (!isSourceParticipant && !isTargetParticipant)
+ {
+ return true;
+ }
+ // one player not participating
+ if (!(isSourceParticipant && isTargetParticipant))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets the DMEvent state<br>
+ * <br>
+ * @param state as EventState<br>
+ */
+ private static void setState(EventState state)
+ {
+ synchronized (_state)
+ {
+ _state = state;
+ }
+ }
+
+ /**
+ * Is DMEvent inactive?<br>
+ * <br>
+ * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
+ */
+ public static boolean isInactive()
+ {
+ boolean isInactive;
+
+ synchronized (_state)
+ {
+ isInactive = _state == EventState.INACTIVE;
+ }
+
+ return isInactive;
+ }
+
+ /**
+ * Is DMEvent in inactivating?<br>
+ * <br>
+ * @return boolean: true if event is in inactivating progress, otherwise false<br>
+ */
+ public static boolean isInactivating()
+ {
+ boolean isInactivating;
+
+ synchronized (_state)
+ {
+ isInactivating = _state == EventState.INACTIVATING;
+ }
+
+ return isInactivating;
+ }
+
+ /**
+ * Is DMEvent in participation?<br>
+ * <br>
+ * @return boolean: true if event is in participation progress, otherwise false<br>
+ */
+ public static boolean isParticipating()
+ {
+ boolean isParticipating;
+
+ synchronized (_state)
+ {
+ isParticipating = _state == EventState.PARTICIPATING;
+ }
+
+ return isParticipating;
+ }
+
+ /**
+ * Is DMEvent starting?<br>
+ * <br>
+ * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
+ */
+ public static boolean isStarting()
+ {
+ boolean isStarting;
+
+ synchronized (_state)
+ {
+ isStarting = _state == EventState.STARTING;
+ }
+
+ return isStarting;
+ }
+
+ /**
+ * Is DMEvent started?<br>
+ * <br>
+ * @return boolean: true if event is started, otherwise false<br>
+ */
+ public static boolean isStarted()
+ {
+ boolean isStarted;
+
+ synchronized (_state)
+ {
+ isStarted = _state == EventState.STARTED;
+ }
+
+ return isStarted;
+ }
+
+ /**
+ * Is DMEvent rewarding?<br>
+ * <br>
+ * @return boolean: true if event is currently rewarding, otherwise false<br>
+ */
+ public static boolean isRewarding()
+ {
+ boolean isRewarding;
+
+ synchronized (_state)
+ {
+ isRewarding = _state == EventState.REWARDING;
+ }
+
+ return isRewarding;
+ }
+
+ public static boolean isPlayerParticipant(L2PcInstance activeChar)
+ {
+ if (activeChar == null)
+ {
+ return false;
+ }
+
+ try
+ {
+ if (_participants.containsKey(activeChar.getObjectId()))
+ {
+ return true;
+ }
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+
+ return false;
+ }
+
+ /**
+ * Is given player participant of the event?
+ * @param objectId
+ * @return boolean: true if player is participant, ohterwise false
+ */
+ public static boolean isPlayerParticipant(int objectId)
+ {
+ L2PcInstance activeChar = L2World.getInstance().getPlayer(objectId);
+ if (activeChar == null)
+ {
+ return false;
+ }
+
+ return isPlayerParticipant(activeChar);
+ }
+
+ public static byte[] generateHex(int size)
+ {
+ byte[] array = new byte[size];
+ Rnd.nextBytes(array);
+ return array;
+ }
+
+ public static String hexToString(byte[] hex)
+ {
+ return new BigInteger(hex).toString(16);
+ }
+
+ public static int getDMEventInstance()
+ {
+ return _DMEventInstance;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventListener.java (working copy)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class DMEventListener implements IEventListener
+{
+ private final L2PcInstance _player;
+
+ protected DMEventListener(L2PcInstance player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return DMEvent.isStarted() && DMEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ @Override
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventPlayer.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventPlayer.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventPlayer.java (working copy)
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class DMEventPlayer
+{
+ private final L2PcInstance _player;
+ private short _points;
+ private short _death;
+ private final String _hexCode;
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ public DMEventPlayer(L2PcInstance player, int[] coordinates, String hexCode)
+ {
+ _player = player;
+ _points = 0;
+ _death = 0;
+ _hexCode = hexCode;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ public boolean isOnEvent()
+ {
+ return DMEvent.isStarted() && DMEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ /**
+ * This method can prevent from displaying 'To Village' button upon death.
+ * @param val
+ */
+ public void setCanRevive(boolean val)
+ {
+ }
+
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ _death = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * @return the _death
+ */
+ public short getDeath()
+ {
+ return _death;
+ }
+
+ /**
+ * @param death the _death to set
+ */
+ public void setDeath(short death)
+ {
+ _death = death;
+ }
+
+ /**
+ * Increases the death of the player<br>
+ */
+ public void increaseDeath()
+ {
+ ++_death;
+ }
+
+ /**
+ * @return the _hexCode
+ */
+ public String getHexCode()
+ {
+ return _hexCode;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author HorridoJoho
+ */
+public class DMEventTeam
+{
+ /** The name of the team<br> */
+ private final String _name;
+ /** The team spot coordinated<br> */
+ private int[] _coordinates = new int[3];
+ /** The points of the team<br> */
+ private short _points;
+ /** Name and instance of all participated players in FastMap<br> */
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ /**
+ * C'tor initialize the team<br>
+ * <br>
+ * @param name as String<br>
+ * @param coordinates as int[]<br>
+ */
+ public DMEventTeam(String name, int[] coordinates)
+ {
+ _name = name;
+ _coordinates = coordinates;
+ _points = 0;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes a player from the team
+ * @param playerObjectId
+ */
+ public void removePlayer(int playerObjectId)
+ {
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.remove(playerObjectId);
+ }
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * Returns the name of the team<br>
+ * <br>
+ * @return String: name of the team<br>
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the coordinates of the team spot<br>
+ * <br>
+ * @return int[]: team coordinates<br>
+ */
+ public int[] getCoordinates()
+ {
+ return _coordinates;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMEventTeleporter.java (working copy)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.Team;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Duel;
+import com.l2jserver.util.Rnd;
+
+public class DMEventTeleporter implements Runnable
+{
+ /** The instance of the player to teleport */
+ private L2PcInstance _playerInstance = null;
+ /** Coordinates of the spot to teleport to */
+ private int[] _coordinates = new int[3];
+ /** Admin removed this player from event */
+ private boolean _adminRemove = false;
+
+ /**
+ * Initialize the teleporter and start the delayed task.
+ * @param playerInstance
+ * @param coordinates
+ * @param fastSchedule
+ * @param adminRemove
+ */
+ public DMEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
+ {
+ _playerInstance = playerInstance;
+ _coordinates = coordinates;
+ _adminRemove = adminRemove;
+
+ long delay = (DMEvent.isStarted() ? Config.DM_EVENT_RESPAWN_TELEPORT_DELAY : Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
+
+ ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
+ }
+
+ /**
+ * The task method to teleport the player<br>
+ * 1. Unsummon pet if there is one<br>
+ * 2. Remove all effects<br>
+ * 3. Revive and full heal the player<br>
+ * 4. Teleport the player<br>
+ * 5. Broadcast status and user info
+ */
+ @Override
+ public void run()
+ {
+ if (_playerInstance == null)
+ {
+ return;
+ }
+
+ L2Summon summon = _playerInstance.getSummon();
+
+ if (summon != null)
+ {
+ summon.unSummon(_playerInstance);
+ }
+
+ if ((Config.DM_EVENT_EFFECTS_REMOVAL == 0) || ((Config.DM_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
+ {
+ _playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
+ }
+
+ if (_playerInstance.isInDuel())
+ {
+ _playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
+ }
+
+ int DMInstance = DMEvent.getDMEventInstance();
+ if (DMInstance != 0)
+ {
+ if (DMEvent.isStarted() && !_adminRemove)
+ {
+ _playerInstance.setInstanceId(DMInstance);
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+
+ _playerInstance.doRevive();
+
+ _playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
+
+ _playerInstance.setCurrentCp(_playerInstance.getMaxCp());
+ _playerInstance.setCurrentHp(_playerInstance.getMaxHp());
+ _playerInstance.setCurrentMp(_playerInstance.getMaxMp());
+
+ _playerInstance.broadcastStatusUpdate();
+ _playerInstance.broadcastUserInfo();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/dm/DMManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/dm/DMManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/dm/DMManager.java (working copy)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.dm;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author HorridoJoho
+ */
+public class DMManager
+{
+ protected static final Logger _log = Logger.getLogger(DMManager.class.getName());
+
+ /** Task for event cycles<br> */
+ private DMStartTask _task;
+
+ /**
+ * New instance only by getInstance()<br>
+ */
+ protected DMManager()
+ {
+ if (Config.DM_EVENT_ENABLED)
+ {
+ DMEvent.init();
+
+ scheduleEventStart();
+ _log.info("DMEventEngine[DMManager.DMManager()]: Started.");
+ }
+ else
+ {
+ _log.info("DMEventEngine[DMManager.DMManager()]: Engine is disabled.");
+ }
+ }
+
+ /**
+ * Initialize new/Returns the one and only instance<br>
+ * <br>
+ * @return DMManager<br>
+ */
+ public static DMManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ /**
+ * Starts DMStartTask
+ */
+ public void scheduleEventStart()
+ {
+ try
+ {
+ Calendar currentTime = Calendar.getInstance();
+ Calendar nextStartTime = null;
+ Calendar testStartTime = null;
+ for (String timeOfDay : Config.DM_EVENT_INTERVAL)
+ {
+ // Creating a Calendar object from the specified interval value
+ testStartTime = Calendar.getInstance();
+ testStartTime.setLenient(true);
+ String[] splitTimeOfDay = timeOfDay.split(":");
+ testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+ testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+ // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
+ if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+ {
+ testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ // Check for the test date to be the minimum (smallest in the specified list)
+ if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
+ {
+ nextStartTime = testStartTime;
+ }
+ }
+ if (nextStartTime != null)
+ {
+ _task = new DMStartTask(nextStartTime.getTimeInMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+ catch (Exception e)
+ {
+ _log.warning("DMEventEngine[DMManager.scheduleEventStart()]: Error figuring out a start time. Check DMEventInterval in config file.");
+ }
+ }
+
+ /**
+ * Method to start participation
+ */
+ public void startReg()
+ {
+ if (!DMEvent.startParticipation())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: Event was cancelled.");
+ _log.warning("DMEventEngine[DMManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: Registration opened for " + Config.DM_EVENT_PARTICIPATION_TIME + " minute(s).");
+
+ // schedule registration end
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.DM_EVENT_PARTICIPATION_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to start the fight
+ */
+ public void startEvent()
+ {
+ if (!DMEvent.startFight())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: Event cancelled due to lack of Participation.");
+ _log.info("DMEventEngine[DMManager.run()]: Lack of registration, abort event.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: Teleporting participants to an arena in " + Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.DM_EVENT_RUNNING_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to end the event and reward
+ */
+ public void endEvent()
+ {
+ Broadcast.toAllOnlinePlayers(DMEvent.calculateRewards());
+ DMEvent.sysMsgToAllParticipants("DM Event: Teleporting back to the registration npc in " + Config.DM_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ DMEvent.stopFight();
+
+ scheduleEventStart();
+ }
+
+ public void skipDelay()
+ {
+ if (_task.nextRun.cancel(false))
+ {
+ _task.setStartTime(System.currentTimeMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Class for DM cycles
+ */
+ class DMStartTask implements Runnable
+ {
+ private long _startTime;
+ public ScheduledFuture<?> nextRun;
+
+ public DMStartTask(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ public void setStartTime(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ @Override
+ public void run()
+ {
+ int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+
+ if (delay > 0)
+ {
+ announce(delay);
+ }
+
+ int nextMsg = 0;
+ if (delay > 3600)
+ {
+ nextMsg = delay - 3600;
+ }
+ else if (delay > 1800)
+ {
+ nextMsg = delay - 1800;
+ }
+ else if (delay > 900)
+ {
+ nextMsg = delay - 900;
+ }
+ else if (delay > 600)
+ {
+ nextMsg = delay - 600;
+ }
+ else if (delay > 300)
+ {
+ nextMsg = delay - 300;
+ }
+ else if (delay > 60)
+ {
+ nextMsg = delay - 60;
+ }
+ else if (delay > 5)
+ {
+ nextMsg = delay - 5;
+ }
+ else if (delay > 0)
+ {
+ nextMsg = delay;
+ }
+ else
+ {
+ // start
+ if (DMEvent.isInactive())
+ {
+ startReg();
+ }
+ else if (DMEvent.isParticipating())
+ {
+ startEvent();
+ }
+ else
+ {
+ endEvent();
+ }
+ }
+
+ if (delay > 0)
+ {
+ nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+ }
+ }
+
+ private void announce(long time)
+ {
+ if ((time >= 3600) && ((time % 3600) == 0))
+ {
+ if (DMEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
+ }
+ else if (DMEvent.isStarted())
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
+ }
+ }
+ else if (time >= 60)
+ {
+ if (DMEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: " + (time / 60) + " minute(s) until registration is closed!");
+ }
+ else if (DMEvent.isStarted())
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: " + (time / 60) + " minute(s) until the event is finished!");
+ }
+ }
+ else
+ {
+ if (DMEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("DM Event: " + time + " second(s) until registration is closed!");
+ }
+ else if (DMEvent.isStarted())
+ {
+ DMEvent.sysMsgToAllParticipants("DM Event: " + time + " second(s) until the event is finished!");
+ }
+ }
+ }
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final DMManager _instance = new DMManager();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEvent.java (working copy)
@@ -0,0 +1,1204 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.data.xml.impl.DoorData;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.SkillData;
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
+import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventStart;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.skills.CommonSkill;
+import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.network.NpcStringId;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
+import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author HorridoJoho
+ */
+public class TvTEvent
+{
+ enum EventState
+ {
+ INACTIVE,
+ INACTIVATING,
+ PARTICIPATING,
+ STARTING,
+ STARTED,
+ REWARDING
+ }
+
+ protected static final Logger _log = Logger.getLogger(TvTEvent.class.getName());
+ /** html path **/
+ private static final String htmlPath = "data/scripts/custom/events/TvT/TvTManager/";
+ /** The teams of the TvTEvent<br> */
+ private static TvTEventTeam[] _teams = new TvTEventTeam[2];
+ /** The state of the TvTEvent<br> */
+ private static EventState _state = EventState.INACTIVE;
+ /** The spawn of the participation npc<br> */
+ private static L2Spawn _npcSpawn = null;
+ /** the npc instance of the participation npc<br> */
+ private static L2Npc _lastNpcSpawn = null;
+ /** Instance id<br> */
+ private static int _TvTEventInstance = 0;
+
+ /**
+ * No instance of this class!<br>
+ */
+ private TvTEvent()
+ {
+ }
+
+ /**
+ * Teams initializing<br>
+ */
+ public static void init()
+ {
+ AntiFeedManager.getInstance().registerEvent(AntiFeedManager.TVT_ID);
+ _teams[0] = new TvTEventTeam(Config.TVT_EVENT_TEAM_1_NAME, Config.TVT_EVENT_TEAM_1_COORDINATES);
+ _teams[1] = new TvTEventTeam(Config.TVT_EVENT_TEAM_2_NAME, Config.TVT_EVENT_TEAM_2_COORDINATES);
+ }
+
+ /**
+ * Starts the participation of the TvTEvent<br>
+ * 1. Get L2NpcTemplate by Config.TVT_EVENT_PARTICIPATION_NPC_ID<br>
+ * 2. Try to spawn a new npc of it<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startParticipation()
+ {
+ try
+ {
+ _npcSpawn = new L2Spawn(Config.TVT_EVENT_PARTICIPATION_NPC_ID);
+
+ _npcSpawn.setX(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[0]);
+ _npcSpawn.setY(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[1]);
+ _npcSpawn.setZ(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ _npcSpawn.setAmount(1);
+ _npcSpawn.setHeading(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[3]);
+ _npcSpawn.setRespawnDelay(1);
+ // later no need to delete spawn from db, we don't store it (false)
+ SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
+ _npcSpawn.init();
+ _lastNpcSpawn = _npcSpawn.getLastSpawn();
+ _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
+ _lastNpcSpawn.setTitle("TvT Event Participation");
+ _lastNpcSpawn.isAggressive();
+ _lastNpcSpawn.decayMe();
+ _lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
+ _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "TvTEventEngine[TvTEvent.startParticipation()]: exception: " + e.getMessage(), e);
+ return false;
+ }
+
+ setState(EventState.PARTICIPATING);
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventRegistrationStart());
+ return true;
+ }
+
+ private static int highestLevelPcInstanceOf(Map<Integer, L2PcInstance> players)
+ {
+ int maxLevel = Integer.MIN_VALUE, maxLevelId = -1;
+ for (L2PcInstance player : players.values())
+ {
+ if (player.getLevel() >= maxLevel)
+ {
+ maxLevel = player.getLevel();
+ maxLevelId = player.getObjectId();
+ }
+ }
+ return maxLevelId;
+ }
+
+ /**
+ * Starts the TvTEvent fight<br>
+ * 1. Set state EventState.STARTING<br>
+ * 2. Close doors specified in configs<br>
+ * 3. Abort if not enought participants(return false)<br>
+ * 4. Set state EventState.STARTED<br>
+ * 5. Teleport all participants to team spot<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startFight()
+ {
+ // Set state to STARTING
+ setState(EventState.STARTING);
+
+ // Randomize and balance team distribution
+ Map<Integer, L2PcInstance> allParticipants = new FastMap<>();
+ allParticipants.putAll(_teams[0].getParticipatedPlayers());
+ allParticipants.putAll(_teams[1].getParticipatedPlayers());
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+
+ L2PcInstance player;
+ Iterator<L2PcInstance> iter;
+ if (needParticipationFee())
+ {
+ iter = allParticipants.values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!hasParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ int balance[] =
+ {
+ 0,
+ 0
+ }, priority = 0, highestLevelPlayerId;
+ L2PcInstance highestLevelPlayer;
+ // TODO: allParticipants should be sorted by level instead of using highestLevelPcInstanceOf for every fetch
+ while (!allParticipants.isEmpty())
+ {
+ // Priority team gets one player
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Exiting if no more players
+ if (allParticipants.isEmpty())
+ {
+ break;
+ }
+ // The other team gets one player
+ // TODO: Code not dry
+ priority = 1 - priority;
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Recalculating priority
+ priority = balance[0] > balance[1] ? 1 : 0;
+ }
+
+ // Check for enought participants
+ if ((_teams[0].getParticipatedPlayerCount() < Config.TVT_EVENT_MIN_PLAYERS_IN_TEAMS) || (_teams[1].getParticipatedPlayerCount() < Config.TVT_EVENT_MIN_PLAYERS_IN_TEAMS))
+ {
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Unspawn the event NPC
+ unSpawnNpc();
+ AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
+ return false;
+ }
+
+ if (needParticipationFee())
+ {
+ iter = _teams[0].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ iter = _teams[1].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ if (Config.TVT_EVENT_IN_INSTANCE)
+ {
+ try
+ {
+ _TvTEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.TVT_EVENT_INSTANCE_FILE);
+ InstanceManager.getInstance().getInstance(_TvTEventInstance).setAllowSummon(false);
+ InstanceManager.getInstance().getInstance(_TvTEventInstance).setPvPInstance(true);
+ InstanceManager.getInstance().getInstance(_TvTEventInstance).setEmptyDestroyTime((Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L);
+ }
+ catch (Exception e)
+ {
+ _TvTEventInstance = 0;
+ _log.log(Level.WARNING, "TvTEventEngine[TvTEvent.createDynamicInstance]: exception: " + e.getMessage(), e);
+ }
+ }
+
+ // Opens all doors specified in configs for tvt
+ openDoors(Config.TVT_DOORS_IDS_TO_OPEN);
+ // Closes all doors specified in configs for tvt
+ closeDoors(Config.TVT_DOORS_IDS_TO_CLOSE);
+ // Set state STARTED
+ setState(EventState.STARTED);
+
+ // Iterate over all teams
+ for (TvTEventTeam team : _teams)
+ {
+ // Iterate over all participated player instances in this team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ // Disable player revival.
+ playerInstance.setCanRevive(false);
+ // Teleporter implements Runnable and starts itself
+ new TvTEventTeleporter(playerInstance, team.getCoordinates(), false, false);
+ }
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventStart());
+ return true;
+ }
+
+ /**
+ * Calculates the TvTEvent reward<br>
+ * 1. If both teams are at a tie(points equals), send it as system message to all participants, if one of the teams have 0 participants left online abort rewarding<br>
+ * 2. Wait till teams are not at a tie anymore<br>
+ * 3. Set state EvcentState.REWARDING<br>
+ * 4. Reward team with more points<br>
+ * 5. Show win html to wining team participants<br>
+ * <br>
+ * @return String: winning team name<br>
+ */
+ public static String calculateRewards()
+ {
+ if (_teams[0].getPoints() == _teams[1].getPoints())
+ {
+ // Check if one of the teams have no more players left
+ if ((_teams[0].getParticipatedPlayerCount() == 0) || (_teams[1].getParticipatedPlayerCount() == 0))
+ {
+ // set state to rewarding
+ setState(EventState.REWARDING);
+ // return here, the fight can't be completed
+ return "TvT Event: Event has ended. No team won due to inactivity!";
+ }
+
+ // Both teams have equals points
+ sysMsgToAllParticipants("TvT Event: Event has ended, both teams have tied.");
+ if (Config.TVT_REWARD_TEAM_TIE)
+ {
+ rewardTeam(_teams[0]);
+ rewardTeam(_teams[1]);
+ return "TvT Event: Event has ended with both teams tying.";
+ }
+ return "TvT Event: Event has ended with both teams tying.";
+ }
+
+ // Set state REWARDING so nobody can point anymore
+ setState(EventState.REWARDING);
+
+ // Get team which has more points
+ TvTEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1];
+ rewardTeam(team);
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventFinish());
+ return "TvT Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills.";
+ }
+
+ private static void rewardTeam(TvTEventTeam team)
+ {
+ // Iterate over all participated player instances of the winning team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance == null)
+ {
+ continue;
+ }
+
+ // Add Fireworks for rewarded player
+ playerInstance.broadcastPacket(new MagicSkillUse(playerInstance, playerInstance, CommonSkill.FIREWORK.getSkill().getId(), 1, 1, 1));
+
+ SystemMessage systemMessage = null;
+
+ // Iterate over all tvt event rewards
+ for (int[] reward : Config.TVT_EVENT_REWARDS)
+ {
+ PcInventory inv = playerInstance.getInventory();
+
+ // Check for stackable item, non stackabe items need to be added one by one
+ if (ItemTable.getInstance().getTemplate(reward[0]).isStackable())
+ {
+ inv.addItem("TvT Event", reward[0], reward[1], playerInstance, playerInstance);
+
+ if (reward[1] > 1)
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+ systemMessage.addItemName(reward[0]);
+ systemMessage.addLong(reward[1]);
+ }
+ else
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ }
+
+ playerInstance.sendPacket(systemMessage);
+ }
+ else
+ {
+ for (int i = 0; i < reward[1]; ++i)
+ {
+ inv.addItem("TvT Event", reward[0], 1, playerInstance, playerInstance);
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ playerInstance.sendPacket(systemMessage);
+ }
+ }
+ }
+
+ StatusUpdate statusUpdate = new StatusUpdate(playerInstance);
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, playerInstance.getCurrentLoad());
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Reward.html"));
+ playerInstance.sendPacket(statusUpdate);
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+
+ /**
+ * Stops the TvTEvent fight<br>
+ * 1. Set state EventState.INACTIVATING<br>
+ * 2. Remove tvt npc from world<br>
+ * 3. Open doors specified in configs<br>
+ * 4. Teleport all participants back to participation npc location<br>
+ * 5. Teams cleaning<br>
+ * 6. Set state EventState.INACTIVE<br>
+ */
+ public static void stopFight()
+ {
+ // Set state INACTIVATING
+ setState(EventState.INACTIVATING);
+ // Unspawn event npc
+ unSpawnNpc();
+ // Opens all doors specified in configs for tvt
+ openDoors(Config.TVT_DOORS_IDS_TO_CLOSE);
+ // Closes all doors specified in Configs for tvt
+ closeDoors(Config.TVT_DOORS_IDS_TO_OPEN);
+
+ // Iterate over all teams
+ for (TvTEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance != null)
+ {
+ // Enable player revival.
+ playerInstance.setCanRevive(true);
+ // Teleport back.
+ new TvTEventTeleporter(playerInstance, Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+ }
+
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
+ }
+
+ /**
+ * Adds a player to a TvTEvent team<br>
+ * 1. Calculate the id of the team in which the player should be added<br>
+ * 2. Add the player to the calculated team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static synchronized boolean addParticipant(L2PcInstance playerInstance)
+ {
+ // Check for nullpoitner
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ byte teamId = 0;
+
+ // Check to which team the player should be added
+ if (_teams[0].getParticipatedPlayerCount() == _teams[1].getParticipatedPlayerCount())
+ {
+ teamId = (byte) (Rnd.get(2));
+ }
+ else
+ {
+ teamId = (byte) (_teams[0].getParticipatedPlayerCount() > _teams[1].getParticipatedPlayerCount() ? 1 : 0);
+ }
+ playerInstance.addEventListener(new TvTEventListener(playerInstance));
+ return _teams[teamId].addPlayer(playerInstance);
+ }
+
+ /**
+ * Removes a TvTEvent player from it's team<br>
+ * 1. Get team id of the player<br>
+ * 2. Remove player from it's team<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if success, otherwise false
+ */
+ public static boolean removeParticipant(int playerObjectId)
+ {
+ // Get the teamId of the player
+ byte teamId = getParticipantTeamId(playerObjectId);
+
+ // Check if the player is participant
+ if (teamId != -1)
+ {
+ // Remove the player from team
+ _teams[teamId].removePlayer(playerObjectId);
+
+ final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
+ if (player != null)
+ {
+ player.removeEventListener(TvTEventListener.class);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean needParticipationFee()
+ {
+ return (Config.TVT_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.TVT_EVENT_PARTICIPATION_FEE[1] != 0);
+ }
+
+ public static boolean hasParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.getInventory().getInventoryItemCount(Config.TVT_EVENT_PARTICIPATION_FEE[0], -1) >= Config.TVT_EVENT_PARTICIPATION_FEE[1];
+ }
+
+ public static boolean payParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.destroyItemByItemId("TvT Participation Fee", Config.TVT_EVENT_PARTICIPATION_FEE[0], Config.TVT_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
+ }
+
+ public static String getParticipationFee()
+ {
+ int itemId = Config.TVT_EVENT_PARTICIPATION_FEE[0];
+ int itemNum = Config.TVT_EVENT_PARTICIPATION_FEE[1];
+
+ if ((itemId == 0) || (itemNum == 0))
+ {
+ return "-";
+ }
+
+ return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
+ }
+
+ /**
+ * Send a SystemMessage to all participated players<br>
+ * 1. Send the message to all players of team number one<br>
+ * 2. Send the message to all players of team number two<br>
+ * <br>
+ * @param message as String<br>
+ */
+ public static void sysMsgToAllParticipants(String message)
+ {
+ for (L2PcInstance playerInstance : _teams[0].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+
+ for (L2PcInstance playerInstance : _teams[1].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+ }
+
+ private static L2DoorInstance getDoor(int doorId)
+ {
+ L2DoorInstance door = null;
+ if (_TvTEventInstance <= 0)
+ {
+ door = DoorData.getInstance().getDoor(doorId);
+ }
+ else
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(_TvTEventInstance);
+ if (inst != null)
+ {
+ door = inst.getDoor(doorId);
+ }
+ }
+ return door;
+ }
+
+ /**
+ * Close doors specified in configs
+ * @param doors
+ */
+ private static void closeDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.closeMe();
+ }
+ }
+ }
+
+ /**
+ * Open doors specified in configs
+ * @param doors
+ */
+ private static void openDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.openMe();
+ }
+ }
+ }
+
+ /**
+ * UnSpawns the TvTEvent npc
+ */
+ private static void unSpawnNpc()
+ {
+ // Delete the npc
+ _lastNpcSpawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
+ // Stop respawning of the npc
+ _npcSpawn.stopRespawn();
+ _npcSpawn = null;
+ _lastNpcSpawn = null;
+ }
+
+ /**
+ * Called when a player logs in<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogin(L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || (!isStarting() && !isStarted()))
+ {
+ return;
+ }
+
+ byte teamId = getParticipantTeamId(playerInstance.getObjectId());
+
+ if (teamId == -1)
+ {
+ return;
+ }
+
+ _teams[teamId].addPlayer(playerInstance);
+ new TvTEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
+ }
+
+ /**
+ * Called when a player logs out<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogout(L2PcInstance playerInstance)
+ {
+ if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
+ {
+ if (removeParticipant(playerInstance.getObjectId()))
+ {
+ playerInstance.setXYZInvisible((Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[0] + Rnd.get(101)) - 50, (Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[1] + Rnd.get(101)) - 50, Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ }
+ }
+ }
+
+ /**
+ * Called on every onAction in L2PcIstance<br>
+ * <br>
+ * @param playerInstance
+ * @param targetedPlayerObjectId
+ * @return boolean: true if player is allowed to target, otherwise false
+ */
+ public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
+ {
+ if ((playerInstance == null) || !isStarted())
+ {
+ return true;
+ }
+
+ if (playerInstance.isGM())
+ {
+ return true;
+ }
+
+ byte playerTeamId = getParticipantTeamId(playerInstance.getObjectId());
+ byte targetedPlayerTeamId = getParticipantTeamId(targetedPlayerObjectId);
+
+ if (((playerTeamId != -1) && (targetedPlayerTeamId == -1)) || ((playerTeamId == -1) && (targetedPlayerTeamId != -1)))
+ {
+ return false;
+ }
+
+ if ((playerTeamId != -1) && (targetedPlayerTeamId != -1) && (playerTeamId == targetedPlayerTeamId) && (playerInstance.getObjectId() != targetedPlayerObjectId) && !Config.TVT_EVENT_TARGET_TEAM_MEMBERS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every scroll use<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use scroll, otherwise false
+ */
+ public static boolean onScrollUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_SCROLL_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every potion use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use potions, otherwise false
+ */
+ public static boolean onPotionUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_POTIONS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every escape use(thanks to nbd)
+ * @param playerObjectId
+ * @return boolean: true if player is not in tvt event, otherwise false
+ */
+ public static boolean onEscapeUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every summon item use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to summon by item, otherwise false
+ */
+ public static boolean onItemSummon(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_SUMMON_BY_ITEM_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is called when a player is killed<br>
+ * <br>
+ * @param killerCharacter as L2Character<br>
+ * @param killedPlayerInstance as L2PcInstance<br>
+ */
+ public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
+ {
+ if ((killedPlayerInstance == null) || !isStarted())
+ {
+ return;
+ }
+
+ byte killedTeamId = getParticipantTeamId(killedPlayerInstance.getObjectId());
+
+ if (killedTeamId == -1)
+ {
+ return;
+ }
+
+ new TvTEventTeleporter(killedPlayerInstance, _teams[killedTeamId].getCoordinates(), false, false);
+
+ if (killerCharacter == null)
+ {
+ return;
+ }
+
+ L2PcInstance killerPlayerInstance = null;
+
+ if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
+ {
+ killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
+
+ if (killerPlayerInstance == null)
+ {
+ return;
+ }
+ }
+ else if (killerCharacter instanceof L2PcInstance)
+ {
+ killerPlayerInstance = (L2PcInstance) killerCharacter;
+ }
+ else
+ {
+ return;
+ }
+
+ byte killerTeamId = getParticipantTeamId(killerPlayerInstance.getObjectId());
+
+ if ((killerTeamId != -1) && (killedTeamId != -1) && (killerTeamId != killedTeamId))
+ {
+ TvTEventTeam killerTeam = _teams[killerTeamId];
+
+ killerTeam.increasePoints();
+
+ CreatureSay cs = new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!");
+
+ for (L2PcInstance playerInstance : _teams[killerTeamId].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendPacket(cs);
+ broadcastScoreMessage();
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventKill(killerPlayerInstance, killedPlayerInstance, killerTeam));
+ }
+ }
+
+ /**
+ * Called on Appearing packet received (player finished teleporting)
+ * @param playerInstance
+ */
+ public static void onTeleported(L2PcInstance playerInstance)
+ {
+ if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
+ {
+ return;
+ }
+
+ if (playerInstance.isMageClass())
+ {
+ if ((Config.TVT_EVENT_MAGE_BUFFS != null) && !Config.TVT_EVENT_MAGE_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.TVT_EVENT_MAGE_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((Config.TVT_EVENT_FIGHTER_BUFFS != null) && !Config.TVT_EVENT_FIGHTER_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.TVT_EVENT_FIGHTER_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param source
+ * @param target
+ * @param skill
+ * @return true if player valid for skill
+ */
+ public static final boolean checkForTvTSkill(L2PcInstance source, L2PcInstance target, Skill skill)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+ // TvT is started
+ final int sourcePlayerId = source.getObjectId();
+ final int targetPlayerId = target.getObjectId();
+ final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
+ final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
+
+ // both players not participating
+ if (!isSourceParticipant && !isTargetParticipant)
+ {
+ return true;
+ }
+ // one player not participating
+ if (!(isSourceParticipant && isTargetParticipant))
+ {
+ return false;
+ }
+ // players in the different teams ?
+ if (getParticipantTeamId(sourcePlayerId) != getParticipantTeamId(targetPlayerId))
+ {
+ if (!skill.isBad())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Sets the TvTEvent state<br>
+ * <br>
+ * @param state as EventState<br>
+ */
+ private static void setState(EventState state)
+ {
+ synchronized (_state)
+ {
+ _state = state;
+ }
+ }
+
+ /**
+ * Is TvTEvent inactive?<br>
+ * <br>
+ * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
+ */
+ public static boolean isInactive()
+ {
+ boolean isInactive;
+
+ synchronized (_state)
+ {
+ isInactive = _state == EventState.INACTIVE;
+ }
+
+ return isInactive;
+ }
+
+ /**
+ * Is TvTEvent in inactivating?<br>
+ * <br>
+ * @return boolean: true if event is in inactivating progress, otherwise false<br>
+ */
+ public static boolean isInactivating()
+ {
+ boolean isInactivating;
+
+ synchronized (_state)
+ {
+ isInactivating = _state == EventState.INACTIVATING;
+ }
+
+ return isInactivating;
+ }
+
+ /**
+ * Is TvTEvent in participation?<br>
+ * <br>
+ * @return boolean: true if event is in participation progress, otherwise false<br>
+ */
+ public static boolean isParticipating()
+ {
+ boolean isParticipating;
+
+ synchronized (_state)
+ {
+ isParticipating = _state == EventState.PARTICIPATING;
+ }
+
+ return isParticipating;
+ }
+
+ /**
+ * Is TvTEvent starting?<br>
+ * <br>
+ * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
+ */
+ public static boolean isStarting()
+ {
+ boolean isStarting;
+
+ synchronized (_state)
+ {
+ isStarting = _state == EventState.STARTING;
+ }
+
+ return isStarting;
+ }
+
+ /**
+ * Is TvTEvent started?<br>
+ * <br>
+ * @return boolean: true if event is started, otherwise false<br>
+ */
+ public static boolean isStarted()
+ {
+ boolean isStarted;
+
+ synchronized (_state)
+ {
+ isStarted = _state == EventState.STARTED;
+ }
+
+ return isStarted;
+ }
+
+ /**
+ * Is TvTEvent rewarding?<br>
+ * <br>
+ * @return boolean: true if event is currently rewarding, otherwise false<br>
+ */
+ public static boolean isRewarding()
+ {
+ boolean isRewarding;
+
+ synchronized (_state)
+ {
+ isRewarding = _state == EventState.REWARDING;
+ }
+
+ return isRewarding;
+ }
+
+ /**
+ * Returns the team id of a player, if player is not participant it returns -1
+ * @param playerObjectId
+ * @return byte: team name of the given playerName, if not in event -1
+ */
+ public static byte getParticipantTeamId(int playerObjectId)
+ {
+ return (byte) (_teams[0].containsPlayer(playerObjectId) ? 0 : (_teams[1].containsPlayer(playerObjectId) ? 1 : -1));
+ }
+
+ /**
+ * Returns the team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return TvTEventTeam: team of the given playerObjectId, if not in event null
+ */
+ public static TvTEventTeam getParticipantTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[0] : (_teams[1].containsPlayer(playerObjectId) ? _teams[1] : null));
+ }
+
+ /**
+ * Returns the enemy team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return TvTEventTeam: enemy team of the given playerObjectId, if not in event null
+ */
+ public static TvTEventTeam getParticipantEnemyTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[1] : (_teams[1].containsPlayer(playerObjectId) ? _teams[0] : null));
+ }
+
+ /**
+ * Returns the team coordinates in which the player is in, if player is not in a team return null
+ * @param playerObjectId
+ * @return int[]: coordinates of teams, 2 elements, index 0 for team 1 and index 1 for team 2
+ */
+ public static int[] getParticipantTeamCoordinates(int playerObjectId)
+ {
+ return _teams[0].containsPlayer(playerObjectId) ? _teams[0].getCoordinates() : (_teams[1].containsPlayer(playerObjectId) ? _teams[1].getCoordinates() : null);
+ }
+
+ /**
+ * Is given player participant of the event?
+ * @param playerObjectId
+ * @return boolean: true if player is participant, ohterwise false
+ */
+ public static boolean isPlayerParticipant(int playerObjectId)
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return false;
+ }
+
+ return _teams[0].containsPlayer(playerObjectId) || _teams[1].containsPlayer(playerObjectId);
+ }
+
+ /**
+ * Returns participated player count<br>
+ * <br>
+ * @return int: amount of players registered in the event<br>
+ */
+ public static int getParticipatedPlayersCount()
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return 0;
+ }
+
+ return _teams[0].getParticipatedPlayerCount() + _teams[1].getParticipatedPlayerCount();
+ }
+
+ /**
+ * Returns teams names<br>
+ * <br>
+ * @return String[]: names of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static String[] getTeamNames()
+ {
+ return new String[]
+ {
+ _teams[0].getName(),
+ _teams[1].getName()
+ };
+ }
+
+ /**
+ * Returns player count of both teams<br>
+ * <br>
+ * @return int[]: player count of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPlayerCounts()
+ {
+ return new int[]
+ {
+ _teams[0].getParticipatedPlayerCount(),
+ _teams[1].getParticipatedPlayerCount()
+ };
+ }
+
+ /**
+ * Returns points count of both teams
+ * @return int[]: points of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPoints()
+ {
+ return new int[]
+ {
+ _teams[0].getPoints(),
+ _teams[1].getPoints()
+ };
+ }
+
+ /**
+ * Broadcast score to all participants
+ */
+ public static void broadcastScoreMessage()
+ {
+ final String score = Config.TVT_EVENT_TEAM_1_NAME + ": " + _teams[0].getPoints() + " - " + Config.TVT_EVENT_TEAM_2_NAME + ": " + _teams[1].getPoints();
+
+ for (TvTEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if ((playerInstance != null) && (playerInstance.getInstanceId() == _TvTEventInstance))
+ {
+ playerInstance.sendPacket(new ExShowScreenMessage(1, -1, 8, 0, 1, 0, 0, false, 15000, true, score, NpcStringId.NONE, null));
+ }
+ }
+ }
+ }
+
+ public static int getTvTEventInstance()
+ {
+ return _TvTEventInstance;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventListener.java (working copy)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class TvTEventListener implements IEventListener
+{
+ private final L2PcInstance _player;
+
+ protected TvTEventListener(L2PcInstance player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ @Override
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventPlayer.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventPlayer.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventPlayer.java (working copy)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class TvTEventPlayer
+{
+ private final L2PcInstance _player;
+
+ protected TvTEventPlayer(L2PcInstance player)
+ {
+ _player = player;
+
+ }
+
+ public boolean isOnEvent()
+ {
+ return TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author HorridoJoho
+ */
+public class TvTEventTeam
+{
+ /** The name of the team<br> */
+ private final String _name;
+ /** The team spot coordinated<br> */
+ private int[] _coordinates = new int[3];
+ /** The points of the team<br> */
+ private short _points;
+ /** Name and instance of all participated players in FastMap<br> */
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ /**
+ * C'tor initialize the team<br>
+ * <br>
+ * @param name as String<br>
+ * @param coordinates as int[]<br>
+ */
+ public TvTEventTeam(String name, int[] coordinates)
+ {
+ _name = name;
+ _coordinates = coordinates;
+ _points = 0;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes a player from the team
+ * @param playerObjectId
+ */
+ public void removePlayer(int playerObjectId)
+ {
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.remove(playerObjectId);
+ }
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * Returns the name of the team<br>
+ * <br>
+ * @return String: name of the team<br>
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the coordinates of the team spot<br>
+ * <br>
+ * @return int[]: team coordinates<br>
+ */
+ public int[] getCoordinates()
+ {
+ return _coordinates;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeleporter.java (working copy)
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.Team;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Duel;
+import com.l2jserver.util.Rnd;
+
+public class TvTEventTeleporter implements Runnable
+{
+ /** The instance of the player to teleport */
+ private L2PcInstance _playerInstance = null;
+ /** Coordinates of the spot to teleport to */
+ private int[] _coordinates = new int[3];
+ /** Admin removed this player from event */
+ private boolean _adminRemove = false;
+
+ /**
+ * Initialize the teleporter and start the delayed task.
+ * @param playerInstance
+ * @param coordinates
+ * @param fastSchedule
+ * @param adminRemove
+ */
+ public TvTEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
+ {
+ _playerInstance = playerInstance;
+ _coordinates = coordinates;
+ _adminRemove = adminRemove;
+
+ long delay = (TvTEvent.isStarted() ? Config.TVT_EVENT_RESPAWN_TELEPORT_DELAY : Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
+
+ ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
+ }
+
+ /**
+ * The task method to teleport the player<br>
+ * 1. Unsummon pet if there is one<br>
+ * 2. Remove all effects<br>
+ * 3. Revive and full heal the player<br>
+ * 4. Teleport the player<br>
+ * 5. Broadcast status and user info
+ */
+ @Override
+ public void run()
+ {
+ if (_playerInstance == null)
+ {
+ return;
+ }
+
+ L2Summon summon = _playerInstance.getSummon();
+
+ if (summon != null)
+ {
+ summon.unSummon(_playerInstance);
+ }
+
+ if ((Config.TVT_EVENT_EFFECTS_REMOVAL == 0) || ((Config.TVT_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
+ {
+ _playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
+ }
+
+ if (_playerInstance.isInDuel())
+ {
+ _playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
+ }
+
+ int TvTInstance = TvTEvent.getTvTEventInstance();
+ if (TvTInstance != 0)
+ {
+ if (TvTEvent.isStarted() && !_adminRemove)
+ {
+ _playerInstance.setInstanceId(TvTInstance);
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+
+ _playerInstance.doRevive();
+
+ _playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
+
+ if (TvTEvent.isStarted() && !_adminRemove)
+ {
+ int teamId = TvTEvent.getParticipantTeamId(_playerInstance.getObjectId()) + 1;
+ switch (teamId)
+ {
+ case 0:
+ _playerInstance.setTeam(Team.NONE);
+ break;
+ case 1:
+ _playerInstance.setTeam(Team.BLUE);
+ break;
+ case 2:
+ _playerInstance.setTeam(Team.RED);
+ break;
+ }
+ }
+ else
+ {
+ _playerInstance.setTeam(Team.NONE);
+ }
+
+ _playerInstance.setCurrentCp(_playerInstance.getMaxCp());
+ _playerInstance.setCurrentHp(_playerInstance.getMaxHp());
+ _playerInstance.setCurrentMp(_playerInstance.getMaxMp());
+
+ _playerInstance.broadcastStatusUpdate();
+ _playerInstance.broadcastUserInfo();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTManager.java (working copy)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author HorridoJoho
+ */
+public class TvTManager
+{
+ protected static final Logger _log = Logger.getLogger(TvTManager.class.getName());
+
+ /** Task for event cycles<br> */
+ private TvTStartTask _task;
+
+ /**
+ * New instance only by getInstance()<br>
+ */
+ protected TvTManager()
+ {
+ if (Config.TVT_EVENT_ENABLED)
+ {
+ TvTEvent.init();
+
+ scheduleEventStart();
+ _log.info("TvTEventEngine[TvTManager.TvTManager()]: Started.");
+ }
+ else
+ {
+ _log.info("TvTEventEngine[TvTManager.TvTManager()]: Engine is disabled.");
+ }
+ }
+
+ /**
+ * Initialize new/Returns the one and only instance<br>
+ * <br>
+ * @return TvTManager<br>
+ */
+ public static TvTManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ /**
+ * Starts TvTStartTask
+ */
+ public void scheduleEventStart()
+ {
+ try
+ {
+ Calendar currentTime = Calendar.getInstance();
+ Calendar nextStartTime = null;
+ Calendar testStartTime = null;
+ for (String timeOfDay : Config.TVT_EVENT_INTERVAL)
+ {
+ // Creating a Calendar object from the specified interval value
+ testStartTime = Calendar.getInstance();
+ testStartTime.setLenient(true);
+ String[] splitTimeOfDay = timeOfDay.split(":");
+ testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+ testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+ // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
+ if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+ {
+ testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ // Check for the test date to be the minimum (smallest in the specified list)
+ if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
+ {
+ nextStartTime = testStartTime;
+ }
+ }
+ if (nextStartTime != null)
+ {
+ _task = new TvTStartTask(nextStartTime.getTimeInMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+ catch (Exception e)
+ {
+ _log.warning("TvTEventEngine[TvTManager.scheduleEventStart()]: Error figuring out a start time. Check TvTEventInterval in config file.");
+ }
+ }
+
+ /**
+ * Method to start participation
+ */
+ public void startReg()
+ {
+ if (!TvTEvent.startParticipation())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: Event was cancelled.");
+ _log.warning("TvTEventEngine[TvTManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: Registration opened for " + Config.TVT_EVENT_PARTICIPATION_TIME + " minute(s).");
+
+ // schedule registration end
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.TVT_EVENT_PARTICIPATION_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to start the fight
+ */
+ public void startEvent()
+ {
+ if (!TvTEvent.startFight())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: Event cancelled due to lack of Participation.");
+ _log.info("TvTEventEngine[TvTManager.run()]: Lack of registration, abort event.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: Teleporting participants to an arena in " + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.TVT_EVENT_RUNNING_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to end the event and reward
+ */
+ public void endEvent()
+ {
+ Broadcast.toAllOnlinePlayers(TvTEvent.calculateRewards());
+ TvTEvent.sysMsgToAllParticipants("TvT Event: Teleporting back to the registration npc in " + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ TvTEvent.stopFight();
+
+ scheduleEventStart();
+ }
+
+ public void skipDelay()
+ {
+ if (_task.nextRun.cancel(false))
+ {
+ _task.setStartTime(System.currentTimeMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Class for TvT cycles
+ */
+ class TvTStartTask implements Runnable
+ {
+ private long _startTime;
+ public ScheduledFuture<?> nextRun;
+
+ public TvTStartTask(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ public void setStartTime(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ @Override
+ public void run()
+ {
+ int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+
+ if (delay > 0)
+ {
+ announce(delay);
+ }
+
+ int nextMsg = 0;
+ if (delay > 3600)
+ {
+ nextMsg = delay - 3600;
+ }
+ else if (delay > 1800)
+ {
+ nextMsg = delay - 1800;
+ }
+ else if (delay > 900)
+ {
+ nextMsg = delay - 900;
+ }
+ else if (delay > 600)
+ {
+ nextMsg = delay - 600;
+ }
+ else if (delay > 300)
+ {
+ nextMsg = delay - 300;
+ }
+ else if (delay > 60)
+ {
+ nextMsg = delay - 60;
+ }
+ else if (delay > 5)
+ {
+ nextMsg = delay - 5;
+ }
+ else if (delay > 0)
+ {
+ nextMsg = delay;
+ }
+ else
+ {
+ // start
+ if (TvTEvent.isInactive())
+ {
+ startReg();
+ }
+ else if (TvTEvent.isParticipating())
+ {
+ startEvent();
+ }
+ else
+ {
+ endEvent();
+ }
+ }
+
+ if (delay > 0)
+ {
+ nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+ }
+ }
+
+ private void announce(long time)
+ {
+ if ((time >= 3600) && ((time % 3600) == 0))
+ {
+ if (TvTEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
+ }
+ else if (TvTEvent.isStarted())
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
+ }
+ }
+ else if (time >= 60)
+ {
+ if (TvTEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: " + (time / 60) + " minute(s) until registration is closed!");
+ }
+ else if (TvTEvent.isStarted())
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60) + " minute(s) until the event is finished!");
+ }
+ }
+ else
+ {
+ if (TvTEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: " + time + " second(s) until registration is closed!");
+ }
+ else if (TvTEvent.isStarted())
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: " + time + " second(s) until the event is finished!");
+ }
+ }
+ }
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final TvTManager _instance = new TvTManager();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEvent.java (working copy)
@@ -0,0 +1,1204 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.data.xml.impl.DoorData;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.SkillData;
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
+import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventStart;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.skills.CommonSkill;
+import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.network.NpcStringId;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
+import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author HorridoJoho
+ */
+public class TvTEvent
+{
+ enum EventState
+ {
+ INACTIVE,
+ INACTIVATING,
+ PARTICIPATING,
+ STARTING,
+ STARTED,
+ REWARDING
+ }
+
+ protected static final Logger _log = Logger.getLogger(TvTEvent.class.getName());
+ /** html path **/
+ private static final String htmlPath = "data/scripts/custom/events/TvT/TvTManager/";
+ /** The teams of the TvTEvent<br> */
+ private static TvTEventTeam[] _teams = new TvTEventTeam[2];
+ /** The state of the TvTEvent<br> */
+ private static EventState _state = EventState.INACTIVE;
+ /** The spawn of the participation npc<br> */
+ private static L2Spawn _npcSpawn = null;
+ /** the npc instance of the participation npc<br> */
+ private static L2Npc _lastNpcSpawn = null;
+ /** Instance id<br> */
+ private static int _TvTEventInstance = 0;
+
+ /**
+ * No instance of this class!<br>
+ */
+ private TvTEvent()
+ {
+ }
+
+ /**
+ * Teams initializing<br>
+ */
+ public static void init()
+ {
+ AntiFeedManager.getInstance().registerEvent(AntiFeedManager.TVT_ID);
+ _teams[0] = new TvTEventTeam(Config.TVT_EVENT_TEAM_1_NAME, Config.TVT_EVENT_TEAM_1_COORDINATES);
+ _teams[1] = new TvTEventTeam(Config.TVT_EVENT_TEAM_2_NAME, Config.TVT_EVENT_TEAM_2_COORDINATES);
+ }
+
+ /**
+ * Starts the participation of the TvTEvent<br>
+ * 1. Get L2NpcTemplate by Config.TVT_EVENT_PARTICIPATION_NPC_ID<br>
+ * 2. Try to spawn a new npc of it<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startParticipation()
+ {
+ try
+ {
+ _npcSpawn = new L2Spawn(Config.TVT_EVENT_PARTICIPATION_NPC_ID);
+
+ _npcSpawn.setX(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[0]);
+ _npcSpawn.setY(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[1]);
+ _npcSpawn.setZ(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ _npcSpawn.setAmount(1);
+ _npcSpawn.setHeading(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[3]);
+ _npcSpawn.setRespawnDelay(1);
+ // later no need to delete spawn from db, we don't store it (false)
+ SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
+ _npcSpawn.init();
+ _lastNpcSpawn = _npcSpawn.getLastSpawn();
+ _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
+ _lastNpcSpawn.setTitle("TvT Event Participation");
+ _lastNpcSpawn.isAggressive();
+ _lastNpcSpawn.decayMe();
+ _lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
+ _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, "TvTEventEngine[TvTEvent.startParticipation()]: exception: " + e.getMessage(), e);
+ return false;
+ }
+
+ setState(EventState.PARTICIPATING);
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventRegistrationStart());
+ return true;
+ }
+
+ private static int highestLevelPcInstanceOf(Map<Integer, L2PcInstance> players)
+ {
+ int maxLevel = Integer.MIN_VALUE, maxLevelId = -1;
+ for (L2PcInstance player : players.values())
+ {
+ if (player.getLevel() >= maxLevel)
+ {
+ maxLevel = player.getLevel();
+ maxLevelId = player.getObjectId();
+ }
+ }
+ return maxLevelId;
+ }
+
+ /**
+ * Starts the TvTEvent fight<br>
+ * 1. Set state EventState.STARTING<br>
+ * 2. Close doors specified in configs<br>
+ * 3. Abort if not enought participants(return false)<br>
+ * 4. Set state EventState.STARTED<br>
+ * 5. Teleport all participants to team spot<br>
+ * <br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static boolean startFight()
+ {
+ // Set state to STARTING
+ setState(EventState.STARTING);
+
+ // Randomize and balance team distribution
+ Map<Integer, L2PcInstance> allParticipants = new FastMap<>();
+ allParticipants.putAll(_teams[0].getParticipatedPlayers());
+ allParticipants.putAll(_teams[1].getParticipatedPlayers());
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+
+ L2PcInstance player;
+ Iterator<L2PcInstance> iter;
+ if (needParticipationFee())
+ {
+ iter = allParticipants.values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!hasParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ int balance[] =
+ {
+ 0,
+ 0
+ }, priority = 0, highestLevelPlayerId;
+ L2PcInstance highestLevelPlayer;
+ // TODO: allParticipants should be sorted by level instead of using highestLevelPcInstanceOf for every fetch
+ while (!allParticipants.isEmpty())
+ {
+ // Priority team gets one player
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Exiting if no more players
+ if (allParticipants.isEmpty())
+ {
+ break;
+ }
+ // The other team gets one player
+ // TODO: Code not dry
+ priority = 1 - priority;
+ highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
+ highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
+ allParticipants.remove(highestLevelPlayerId);
+ _teams[priority].addPlayer(highestLevelPlayer);
+ balance[priority] += highestLevelPlayer.getLevel();
+ // Recalculating priority
+ priority = balance[0] > balance[1] ? 1 : 0;
+ }
+
+ // Check for enought participants
+ if ((_teams[0].getParticipatedPlayerCount() < Config.TVT_EVENT_MIN_PLAYERS_IN_TEAMS) || (_teams[1].getParticipatedPlayerCount() < Config.TVT_EVENT_MIN_PLAYERS_IN_TEAMS))
+ {
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Unspawn the event NPC
+ unSpawnNpc();
+ AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
+ return false;
+ }
+
+ if (needParticipationFee())
+ {
+ iter = _teams[0].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ iter = _teams[1].getParticipatedPlayers().values().iterator();
+ while (iter.hasNext())
+ {
+ player = iter.next();
+ if (!payParticipationFee(player))
+ {
+ iter.remove();
+ }
+ }
+ }
+
+ if (Config.TVT_EVENT_IN_INSTANCE)
+ {
+ try
+ {
+ _TvTEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.TVT_EVENT_INSTANCE_FILE);
+ InstanceManager.getInstance().getInstance(_TvTEventInstance).setAllowSummon(false);
+ InstanceManager.getInstance().getInstance(_TvTEventInstance).setPvPInstance(true);
+ InstanceManager.getInstance().getInstance(_TvTEventInstance).setEmptyDestroyTime((Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L);
+ }
+ catch (Exception e)
+ {
+ _TvTEventInstance = 0;
+ _log.log(Level.WARNING, "TvTEventEngine[TvTEvent.createDynamicInstance]: exception: " + e.getMessage(), e);
+ }
+ }
+
+ // Opens all doors specified in configs for tvt
+ openDoors(Config.TVT_DOORS_IDS_TO_OPEN);
+ // Closes all doors specified in configs for tvt
+ closeDoors(Config.TVT_DOORS_IDS_TO_CLOSE);
+ // Set state STARTED
+ setState(EventState.STARTED);
+
+ // Iterate over all teams
+ for (TvTEventTeam team : _teams)
+ {
+ // Iterate over all participated player instances in this team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ // Disable player revival.
+ playerInstance.setCanRevive(false);
+ // Teleporter implements Runnable and starts itself
+ new TvTEventTeleporter(playerInstance, team.getCoordinates(), false, false);
+ }
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventStart());
+ return true;
+ }
+
+ /**
+ * Calculates the TvTEvent reward<br>
+ * 1. If both teams are at a tie(points equals), send it as system message to all participants, if one of the teams have 0 participants left online abort rewarding<br>
+ * 2. Wait till teams are not at a tie anymore<br>
+ * 3. Set state EvcentState.REWARDING<br>
+ * 4. Reward team with more points<br>
+ * 5. Show win html to wining team participants<br>
+ * <br>
+ * @return String: winning team name<br>
+ */
+ public static String calculateRewards()
+ {
+ if (_teams[0].getPoints() == _teams[1].getPoints())
+ {
+ // Check if one of the teams have no more players left
+ if ((_teams[0].getParticipatedPlayerCount() == 0) || (_teams[1].getParticipatedPlayerCount() == 0))
+ {
+ // set state to rewarding
+ setState(EventState.REWARDING);
+ // return here, the fight can't be completed
+ return "TvT Event: Event has ended. No team won due to inactivity!";
+ }
+
+ // Both teams have equals points
+ sysMsgToAllParticipants("TvT Event: Event has ended, both teams have tied.");
+ if (Config.TVT_REWARD_TEAM_TIE)
+ {
+ rewardTeam(_teams[0]);
+ rewardTeam(_teams[1]);
+ return "TvT Event: Event has ended with both teams tying.";
+ }
+ return "TvT Event: Event has ended with both teams tying.";
+ }
+
+ // Set state REWARDING so nobody can point anymore
+ setState(EventState.REWARDING);
+
+ // Get team which has more points
+ TvTEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1];
+ rewardTeam(team);
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventFinish());
+ return "TvT Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills.";
+ }
+
+ private static void rewardTeam(TvTEventTeam team)
+ {
+ // Iterate over all participated player instances of the winning team
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance == null)
+ {
+ continue;
+ }
+
+ // Add Fireworks for rewarded player
+ playerInstance.broadcastPacket(new MagicSkillUse(playerInstance, playerInstance, CommonSkill.FIREWORK.getSkill().getId(), 1, 1, 1));
+
+ SystemMessage systemMessage = null;
+
+ // Iterate over all tvt event rewards
+ for (int[] reward : Config.TVT_EVENT_REWARDS)
+ {
+ PcInventory inv = playerInstance.getInventory();
+
+ // Check for stackable item, non stackabe items need to be added one by one
+ if (ItemTable.getInstance().getTemplate(reward[0]).isStackable())
+ {
+ inv.addItem("TvT Event", reward[0], reward[1], playerInstance, playerInstance);
+
+ if (reward[1] > 1)
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+ systemMessage.addItemName(reward[0]);
+ systemMessage.addLong(reward[1]);
+ }
+ else
+ {
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ }
+
+ playerInstance.sendPacket(systemMessage);
+ }
+ else
+ {
+ for (int i = 0; i < reward[1]; ++i)
+ {
+ inv.addItem("TvT Event", reward[0], 1, playerInstance, playerInstance);
+ systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ systemMessage.addItemName(reward[0]);
+ playerInstance.sendPacket(systemMessage);
+ }
+ }
+ }
+
+ StatusUpdate statusUpdate = new StatusUpdate(playerInstance);
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, playerInstance.getCurrentLoad());
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Reward.html"));
+ playerInstance.sendPacket(statusUpdate);
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+
+ /**
+ * Stops the TvTEvent fight<br>
+ * 1. Set state EventState.INACTIVATING<br>
+ * 2. Remove tvt npc from world<br>
+ * 3. Open doors specified in configs<br>
+ * 4. Teleport all participants back to participation npc location<br>
+ * 5. Teams cleaning<br>
+ * 6. Set state EventState.INACTIVE<br>
+ */
+ public static void stopFight()
+ {
+ // Set state INACTIVATING
+ setState(EventState.INACTIVATING);
+ // Unspawn event npc
+ unSpawnNpc();
+ // Opens all doors specified in configs for tvt
+ openDoors(Config.TVT_DOORS_IDS_TO_CLOSE);
+ // Closes all doors specified in Configs for tvt
+ closeDoors(Config.TVT_DOORS_IDS_TO_OPEN);
+
+ // Iterate over all teams
+ for (TvTEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ // Check for nullpointer
+ if (playerInstance != null)
+ {
+ // Enable player revival.
+ playerInstance.setCanRevive(true);
+ // Teleport back.
+ new TvTEventTeleporter(playerInstance, Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
+ }
+ }
+ }
+
+ // Cleanup of teams
+ _teams[0].cleanMe();
+ _teams[1].cleanMe();
+ // Set state INACTIVE
+ setState(EventState.INACTIVE);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
+ }
+
+ /**
+ * Adds a player to a TvTEvent team<br>
+ * 1. Calculate the id of the team in which the player should be added<br>
+ * 2. Add the player to the calculated team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public static synchronized boolean addParticipant(L2PcInstance playerInstance)
+ {
+ // Check for nullpoitner
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ byte teamId = 0;
+
+ // Check to which team the player should be added
+ if (_teams[0].getParticipatedPlayerCount() == _teams[1].getParticipatedPlayerCount())
+ {
+ teamId = (byte) (Rnd.get(2));
+ }
+ else
+ {
+ teamId = (byte) (_teams[0].getParticipatedPlayerCount() > _teams[1].getParticipatedPlayerCount() ? 1 : 0);
+ }
+ playerInstance.addEventListener(new TvTEventListener(playerInstance));
+ return _teams[teamId].addPlayer(playerInstance);
+ }
+
+ /**
+ * Removes a TvTEvent player from it's team<br>
+ * 1. Get team id of the player<br>
+ * 2. Remove player from it's team<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if success, otherwise false
+ */
+ public static boolean removeParticipant(int playerObjectId)
+ {
+ // Get the teamId of the player
+ byte teamId = getParticipantTeamId(playerObjectId);
+
+ // Check if the player is participant
+ if (teamId != -1)
+ {
+ // Remove the player from team
+ _teams[teamId].removePlayer(playerObjectId);
+
+ final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
+ if (player != null)
+ {
+ player.removeEventListener(TvTEventListener.class);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean needParticipationFee()
+ {
+ return (Config.TVT_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.TVT_EVENT_PARTICIPATION_FEE[1] != 0);
+ }
+
+ public static boolean hasParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.getInventory().getInventoryItemCount(Config.TVT_EVENT_PARTICIPATION_FEE[0], -1) >= Config.TVT_EVENT_PARTICIPATION_FEE[1];
+ }
+
+ public static boolean payParticipationFee(L2PcInstance playerInstance)
+ {
+ return playerInstance.destroyItemByItemId("TvT Participation Fee", Config.TVT_EVENT_PARTICIPATION_FEE[0], Config.TVT_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
+ }
+
+ public static String getParticipationFee()
+ {
+ int itemId = Config.TVT_EVENT_PARTICIPATION_FEE[0];
+ int itemNum = Config.TVT_EVENT_PARTICIPATION_FEE[1];
+
+ if ((itemId == 0) || (itemNum == 0))
+ {
+ return "-";
+ }
+
+ return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
+ }
+
+ /**
+ * Send a SystemMessage to all participated players<br>
+ * 1. Send the message to all players of team number one<br>
+ * 2. Send the message to all players of team number two<br>
+ * <br>
+ * @param message as String<br>
+ */
+ public static void sysMsgToAllParticipants(String message)
+ {
+ for (L2PcInstance playerInstance : _teams[0].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+
+ for (L2PcInstance playerInstance : _teams[1].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendMessage(message);
+ }
+ }
+ }
+
+ private static L2DoorInstance getDoor(int doorId)
+ {
+ L2DoorInstance door = null;
+ if (_TvTEventInstance <= 0)
+ {
+ door = DoorData.getInstance().getDoor(doorId);
+ }
+ else
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(_TvTEventInstance);
+ if (inst != null)
+ {
+ door = inst.getDoor(doorId);
+ }
+ }
+ return door;
+ }
+
+ /**
+ * Close doors specified in configs
+ * @param doors
+ */
+ private static void closeDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.closeMe();
+ }
+ }
+ }
+
+ /**
+ * Open doors specified in configs
+ * @param doors
+ */
+ private static void openDoors(List<Integer> doors)
+ {
+ for (int doorId : doors)
+ {
+ final L2DoorInstance doorInstance = getDoor(doorId);
+ if (doorInstance != null)
+ {
+ doorInstance.openMe();
+ }
+ }
+ }
+
+ /**
+ * UnSpawns the TvTEvent npc
+ */
+ private static void unSpawnNpc()
+ {
+ // Delete the npc
+ _lastNpcSpawn.deleteMe();
+ SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
+ // Stop respawning of the npc
+ _npcSpawn.stopRespawn();
+ _npcSpawn = null;
+ _lastNpcSpawn = null;
+ }
+
+ /**
+ * Called when a player logs in<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogin(L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || (!isStarting() && !isStarted()))
+ {
+ return;
+ }
+
+ byte teamId = getParticipantTeamId(playerInstance.getObjectId());
+
+ if (teamId == -1)
+ {
+ return;
+ }
+
+ _teams[teamId].addPlayer(playerInstance);
+ new TvTEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
+ }
+
+ /**
+ * Called when a player logs out<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static void onLogout(L2PcInstance playerInstance)
+ {
+ if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
+ {
+ if (removeParticipant(playerInstance.getObjectId()))
+ {
+ playerInstance.setXYZInvisible((Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[0] + Rnd.get(101)) - 50, (Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[1] + Rnd.get(101)) - 50, Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
+ }
+ }
+ }
+
+ /**
+ * Called on every onAction in L2PcIstance<br>
+ * <br>
+ * @param playerInstance
+ * @param targetedPlayerObjectId
+ * @return boolean: true if player is allowed to target, otherwise false
+ */
+ public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
+ {
+ if ((playerInstance == null) || !isStarted())
+ {
+ return true;
+ }
+
+ if (playerInstance.isGM())
+ {
+ return true;
+ }
+
+ byte playerTeamId = getParticipantTeamId(playerInstance.getObjectId());
+ byte targetedPlayerTeamId = getParticipantTeamId(targetedPlayerObjectId);
+
+ if (((playerTeamId != -1) && (targetedPlayerTeamId == -1)) || ((playerTeamId == -1) && (targetedPlayerTeamId != -1)))
+ {
+ return false;
+ }
+
+ if ((playerTeamId != -1) && (targetedPlayerTeamId != -1) && (playerTeamId == targetedPlayerTeamId) && (playerInstance.getObjectId() != targetedPlayerObjectId) && !Config.TVT_EVENT_TARGET_TEAM_MEMBERS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every scroll use<br>
+ * <br>
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use scroll, otherwise false
+ */
+ public static boolean onScrollUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_SCROLL_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every potion use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to use potions, otherwise false
+ */
+ public static boolean onPotionUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_POTIONS_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every escape use(thanks to nbd)
+ * @param playerObjectId
+ * @return boolean: true if player is not in tvt event, otherwise false
+ */
+ public static boolean onEscapeUse(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called on every summon item use
+ * @param playerObjectId
+ * @return boolean: true if player is allowed to summon by item, otherwise false
+ */
+ public static boolean onItemSummon(int playerObjectId)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+
+ if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_SUMMON_BY_ITEM_ALLOWED)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is called when a player is killed<br>
+ * <br>
+ * @param killerCharacter as L2Character<br>
+ * @param killedPlayerInstance as L2PcInstance<br>
+ */
+ public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
+ {
+ if ((killedPlayerInstance == null) || !isStarted())
+ {
+ return;
+ }
+
+ byte killedTeamId = getParticipantTeamId(killedPlayerInstance.getObjectId());
+
+ if (killedTeamId == -1)
+ {
+ return;
+ }
+
+ new TvTEventTeleporter(killedPlayerInstance, _teams[killedTeamId].getCoordinates(), false, false);
+
+ if (killerCharacter == null)
+ {
+ return;
+ }
+
+ L2PcInstance killerPlayerInstance = null;
+
+ if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
+ {
+ killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
+
+ if (killerPlayerInstance == null)
+ {
+ return;
+ }
+ }
+ else if (killerCharacter instanceof L2PcInstance)
+ {
+ killerPlayerInstance = (L2PcInstance) killerCharacter;
+ }
+ else
+ {
+ return;
+ }
+
+ byte killerTeamId = getParticipantTeamId(killerPlayerInstance.getObjectId());
+
+ if ((killerTeamId != -1) && (killedTeamId != -1) && (killerTeamId != killedTeamId))
+ {
+ TvTEventTeam killerTeam = _teams[killerTeamId];
+
+ killerTeam.increasePoints();
+
+ CreatureSay cs = new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!");
+
+ for (L2PcInstance playerInstance : _teams[killerTeamId].getParticipatedPlayers().values())
+ {
+ if (playerInstance != null)
+ {
+ playerInstance.sendPacket(cs);
+ broadcastScoreMessage();
+ }
+ }
+
+ // Notify to scripts.
+ EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventKill(killerPlayerInstance, killedPlayerInstance, killerTeam));
+ }
+ }
+
+ /**
+ * Called on Appearing packet received (player finished teleporting)
+ * @param playerInstance
+ */
+ public static void onTeleported(L2PcInstance playerInstance)
+ {
+ if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
+ {
+ return;
+ }
+
+ if (playerInstance.isMageClass())
+ {
+ if ((Config.TVT_EVENT_MAGE_BUFFS != null) && !Config.TVT_EVENT_MAGE_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.TVT_EVENT_MAGE_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((Config.TVT_EVENT_FIGHTER_BUFFS != null) && !Config.TVT_EVENT_FIGHTER_BUFFS.isEmpty())
+ {
+ for (Entry<Integer, Integer> e : Config.TVT_EVENT_FIGHTER_BUFFS.entrySet())
+ {
+ Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
+ if (skill != null)
+ {
+ skill.applyEffects(playerInstance, playerInstance);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param source
+ * @param target
+ * @param skill
+ * @return true if player valid for skill
+ */
+ public static final boolean checkForTvTSkill(L2PcInstance source, L2PcInstance target, Skill skill)
+ {
+ if (!isStarted())
+ {
+ return true;
+ }
+ // TvT is started
+ final int sourcePlayerId = source.getObjectId();
+ final int targetPlayerId = target.getObjectId();
+ final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
+ final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
+
+ // both players not participating
+ if (!isSourceParticipant && !isTargetParticipant)
+ {
+ return true;
+ }
+ // one player not participating
+ if (!(isSourceParticipant && isTargetParticipant))
+ {
+ return false;
+ }
+ // players in the different teams ?
+ if (getParticipantTeamId(sourcePlayerId) != getParticipantTeamId(targetPlayerId))
+ {
+ if (!skill.isBad())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Sets the TvTEvent state<br>
+ * <br>
+ * @param state as EventState<br>
+ */
+ private static void setState(EventState state)
+ {
+ synchronized (_state)
+ {
+ _state = state;
+ }
+ }
+
+ /**
+ * Is TvTEvent inactive?<br>
+ * <br>
+ * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
+ */
+ public static boolean isInactive()
+ {
+ boolean isInactive;
+
+ synchronized (_state)
+ {
+ isInactive = _state == EventState.INACTIVE;
+ }
+
+ return isInactive;
+ }
+
+ /**
+ * Is TvTEvent in inactivating?<br>
+ * <br>
+ * @return boolean: true if event is in inactivating progress, otherwise false<br>
+ */
+ public static boolean isInactivating()
+ {
+ boolean isInactivating;
+
+ synchronized (_state)
+ {
+ isInactivating = _state == EventState.INACTIVATING;
+ }
+
+ return isInactivating;
+ }
+
+ /**
+ * Is TvTEvent in participation?<br>
+ * <br>
+ * @return boolean: true if event is in participation progress, otherwise false<br>
+ */
+ public static boolean isParticipating()
+ {
+ boolean isParticipating;
+
+ synchronized (_state)
+ {
+ isParticipating = _state == EventState.PARTICIPATING;
+ }
+
+ return isParticipating;
+ }
+
+ /**
+ * Is TvTEvent starting?<br>
+ * <br>
+ * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
+ */
+ public static boolean isStarting()
+ {
+ boolean isStarting;
+
+ synchronized (_state)
+ {
+ isStarting = _state == EventState.STARTING;
+ }
+
+ return isStarting;
+ }
+
+ /**
+ * Is TvTEvent started?<br>
+ * <br>
+ * @return boolean: true if event is started, otherwise false<br>
+ */
+ public static boolean isStarted()
+ {
+ boolean isStarted;
+
+ synchronized (_state)
+ {
+ isStarted = _state == EventState.STARTED;
+ }
+
+ return isStarted;
+ }
+
+ /**
+ * Is TvTEvent rewarding?<br>
+ * <br>
+ * @return boolean: true if event is currently rewarding, otherwise false<br>
+ */
+ public static boolean isRewarding()
+ {
+ boolean isRewarding;
+
+ synchronized (_state)
+ {
+ isRewarding = _state == EventState.REWARDING;
+ }
+
+ return isRewarding;
+ }
+
+ /**
+ * Returns the team id of a player, if player is not participant it returns -1
+ * @param playerObjectId
+ * @return byte: team name of the given playerName, if not in event -1
+ */
+ public static byte getParticipantTeamId(int playerObjectId)
+ {
+ return (byte) (_teams[0].containsPlayer(playerObjectId) ? 0 : (_teams[1].containsPlayer(playerObjectId) ? 1 : -1));
+ }
+
+ /**
+ * Returns the team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return TvTEventTeam: team of the given playerObjectId, if not in event null
+ */
+ public static TvTEventTeam getParticipantTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[0] : (_teams[1].containsPlayer(playerObjectId) ? _teams[1] : null));
+ }
+
+ /**
+ * Returns the enemy team of a player, if player is not participant it returns null
+ * @param playerObjectId
+ * @return TvTEventTeam: enemy team of the given playerObjectId, if not in event null
+ */
+ public static TvTEventTeam getParticipantEnemyTeam(int playerObjectId)
+ {
+ return (_teams[0].containsPlayer(playerObjectId) ? _teams[1] : (_teams[1].containsPlayer(playerObjectId) ? _teams[0] : null));
+ }
+
+ /**
+ * Returns the team coordinates in which the player is in, if player is not in a team return null
+ * @param playerObjectId
+ * @return int[]: coordinates of teams, 2 elements, index 0 for team 1 and index 1 for team 2
+ */
+ public static int[] getParticipantTeamCoordinates(int playerObjectId)
+ {
+ return _teams[0].containsPlayer(playerObjectId) ? _teams[0].getCoordinates() : (_teams[1].containsPlayer(playerObjectId) ? _teams[1].getCoordinates() : null);
+ }
+
+ /**
+ * Is given player participant of the event?
+ * @param playerObjectId
+ * @return boolean: true if player is participant, ohterwise false
+ */
+ public static boolean isPlayerParticipant(int playerObjectId)
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return false;
+ }
+
+ return _teams[0].containsPlayer(playerObjectId) || _teams[1].containsPlayer(playerObjectId);
+ }
+
+ /**
+ * Returns participated player count<br>
+ * <br>
+ * @return int: amount of players registered in the event<br>
+ */
+ public static int getParticipatedPlayersCount()
+ {
+ if (!isParticipating() && !isStarting() && !isStarted())
+ {
+ return 0;
+ }
+
+ return _teams[0].getParticipatedPlayerCount() + _teams[1].getParticipatedPlayerCount();
+ }
+
+ /**
+ * Returns teams names<br>
+ * <br>
+ * @return String[]: names of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static String[] getTeamNames()
+ {
+ return new String[]
+ {
+ _teams[0].getName(),
+ _teams[1].getName()
+ };
+ }
+
+ /**
+ * Returns player count of both teams<br>
+ * <br>
+ * @return int[]: player count of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPlayerCounts()
+ {
+ return new int[]
+ {
+ _teams[0].getParticipatedPlayerCount(),
+ _teams[1].getParticipatedPlayerCount()
+ };
+ }
+
+ /**
+ * Returns points count of both teams
+ * @return int[]: points of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
+ */
+ public static int[] getTeamsPoints()
+ {
+ return new int[]
+ {
+ _teams[0].getPoints(),
+ _teams[1].getPoints()
+ };
+ }
+
+ /**
+ * Broadcast score to all participants
+ */
+ public static void broadcastScoreMessage()
+ {
+ final String score = Config.TVT_EVENT_TEAM_1_NAME + ": " + _teams[0].getPoints() + " - " + Config.TVT_EVENT_TEAM_2_NAME + ": " + _teams[1].getPoints();
+
+ for (TvTEventTeam team : _teams)
+ {
+ for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
+ {
+ if ((playerInstance != null) && (playerInstance.getInstanceId() == _TvTEventInstance))
+ {
+ playerInstance.sendPacket(new ExShowScreenMessage(1, -1, 8, 0, 1, 0, 0, false, 15000, true, score, NpcStringId.NONE, null));
+ }
+ }
+ }
+ }
+
+ public static int getTvTEventInstance()
+ {
+ return _TvTEventInstance;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventListener.java (working copy)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class TvTEventListener implements IEventListener
+{
+ private final L2PcInstance _player;
+
+ protected TvTEventListener(L2PcInstance player)
+ {
+ _player = player;
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ @Override
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventPlayer.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventPlayer.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventPlayer.java (working copy)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class TvTEventPlayer
+{
+ private final L2PcInstance _player;
+
+ protected TvTEventPlayer(L2PcInstance player)
+ {
+ _player = player;
+
+ }
+
+ public boolean isOnEvent()
+ {
+ return TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+
+ public boolean canRevive()
+ {
+ return false;
+ }
+
+ public L2PcInstance getPlayer()
+ {
+ return _player;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import java.util.Map;
+
+import javolution.util.FastMap;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author HorridoJoho
+ */
+public class TvTEventTeam
+{
+ /** The name of the team<br> */
+ private final String _name;
+ /** The team spot coordinated<br> */
+ private int[] _coordinates = new int[3];
+ /** The points of the team<br> */
+ private short _points;
+ /** Name and instance of all participated players in FastMap<br> */
+ private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
+
+ /**
+ * C'tor initialize the team<br>
+ * <br>
+ * @param name as String<br>
+ * @param coordinates as int[]<br>
+ */
+ public TvTEventTeam(String name, int[] coordinates)
+ {
+ _name = name;
+ _coordinates = coordinates;
+ _points = 0;
+ }
+
+ /**
+ * Adds a player to the team<br>
+ * <br>
+ * @param playerInstance as L2PcInstance<br>
+ * @return boolean: true if success, otherwise false<br>
+ */
+ public boolean addPlayer(L2PcInstance playerInstance)
+ {
+ if (playerInstance == null)
+ {
+ return false;
+ }
+
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes a player from the team
+ * @param playerObjectId
+ */
+ public void removePlayer(int playerObjectId)
+ {
+ synchronized (_participatedPlayers)
+ {
+ _participatedPlayers.remove(playerObjectId);
+ }
+ }
+
+ /**
+ * Increases the points of the team<br>
+ */
+ public void increasePoints()
+ {
+ ++_points;
+ }
+
+ /**
+ * Cleanup the team and make it ready for adding players again<br>
+ */
+ public void cleanMe()
+ {
+ _participatedPlayers.clear();
+ _participatedPlayers = new FastMap<>();
+ _points = 0;
+ }
+
+ /**
+ * Is given player in this team?
+ * @param playerObjectId
+ * @return boolean: true if player is in this team, otherwise false
+ */
+ public boolean containsPlayer(int playerObjectId)
+ {
+ boolean containsPlayer;
+
+ synchronized (_participatedPlayers)
+ {
+ containsPlayer = _participatedPlayers.containsKey(playerObjectId);
+ }
+
+ return containsPlayer;
+ }
+
+ /**
+ * Returns the name of the team<br>
+ * <br>
+ * @return String: name of the team<br>
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the coordinates of the team spot<br>
+ * <br>
+ * @return int[]: team coordinates<br>
+ */
+ public int[] getCoordinates()
+ {
+ return _coordinates;
+ }
+
+ /**
+ * Returns the points of the team<br>
+ * <br>
+ * @return short: team points<br>
+ */
+ public short getPoints()
+ {
+ return _points;
+ }
+
+ /**
+ * Returns name and instance of all participated players in FastMap<br>
+ * <br>
+ * @return Map<String, L2PcInstance>: map of players in this team<br>
+ */
+ public Map<Integer, L2PcInstance> getParticipatedPlayers()
+ {
+ Map<Integer, L2PcInstance> participatedPlayers = null;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayers = _participatedPlayers;
+ }
+
+ return participatedPlayers;
+ }
+
+ /**
+ * Returns player count of this team<br>
+ * <br>
+ * @return int: number of players in team<br>
+ */
+ public int getParticipatedPlayerCount()
+ {
+ int participatedPlayerCount;
+
+ synchronized (_participatedPlayers)
+ {
+ participatedPlayerCount = _participatedPlayers.size();
+ }
+
+ return participatedPlayerCount;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTEventTeleporter.java (working copy)
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.enums.Team;
+import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Duel;
+import com.l2jserver.util.Rnd;
+
+public class TvTEventTeleporter implements Runnable
+{
+ /** The instance of the player to teleport */
+ private L2PcInstance _playerInstance = null;
+ /** Coordinates of the spot to teleport to */
+ private int[] _coordinates = new int[3];
+ /** Admin removed this player from event */
+ private boolean _adminRemove = false;
+
+ /**
+ * Initialize the teleporter and start the delayed task.
+ * @param playerInstance
+ * @param coordinates
+ * @param fastSchedule
+ * @param adminRemove
+ */
+ public TvTEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
+ {
+ _playerInstance = playerInstance;
+ _coordinates = coordinates;
+ _adminRemove = adminRemove;
+
+ long delay = (TvTEvent.isStarted() ? Config.TVT_EVENT_RESPAWN_TELEPORT_DELAY : Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
+
+ ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
+ }
+
+ /**
+ * The task method to teleport the player<br>
+ * 1. Unsummon pet if there is one<br>
+ * 2. Remove all effects<br>
+ * 3. Revive and full heal the player<br>
+ * 4. Teleport the player<br>
+ * 5. Broadcast status and user info
+ */
+ @Override
+ public void run()
+ {
+ if (_playerInstance == null)
+ {
+ return;
+ }
+
+ L2Summon summon = _playerInstance.getSummon();
+
+ if (summon != null)
+ {
+ summon.unSummon(_playerInstance);
+ }
+
+ if ((Config.TVT_EVENT_EFFECTS_REMOVAL == 0) || ((Config.TVT_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
+ {
+ _playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
+ }
+
+ if (_playerInstance.isInDuel())
+ {
+ _playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
+ }
+
+ int TvTInstance = TvTEvent.getTvTEventInstance();
+ if (TvTInstance != 0)
+ {
+ if (TvTEvent.isStarted() && !_adminRemove)
+ {
+ _playerInstance.setInstanceId(TvTInstance);
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+ }
+ else
+ {
+ _playerInstance.setInstanceId(0);
+ }
+
+ _playerInstance.doRevive();
+
+ _playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
+
+ if (TvTEvent.isStarted() && !_adminRemove)
+ {
+ int teamId = TvTEvent.getParticipantTeamId(_playerInstance.getObjectId()) + 1;
+ switch (teamId)
+ {
+ case 0:
+ _playerInstance.setTeam(Team.NONE);
+ break;
+ case 1:
+ _playerInstance.setTeam(Team.BLUE);
+ break;
+ case 2:
+ _playerInstance.setTeam(Team.RED);
+ break;
+ }
+ }
+ else
+ {
+ _playerInstance.setTeam(Team.NONE);
+ }
+
+ _playerInstance.setCurrentCp(_playerInstance.getMaxCp());
+ _playerInstance.setCurrentHp(_playerInstance.getMaxHp());
+ _playerInstance.setCurrentMp(_playerInstance.getMaxMp());
+
+ _playerInstance.broadcastStatusUpdate();
+ _playerInstance.broadcastUserInfo();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/events/tvt/TvTManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/events/tvt/TvTManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/events/tvt/TvTManager.java (working copy)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.entity.events.tvt;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.util.Broadcast;
+
+/**
+ * @author HorridoJoho
+ */
+public class TvTManager
+{
+ protected static final Logger _log = Logger.getLogger(TvTManager.class.getName());
+
+ /** Task for event cycles<br> */
+ private TvTStartTask _task;
+
+ /**
+ * New instance only by getInstance()<br>
+ */
+ protected TvTManager()
+ {
+ if (Config.TVT_EVENT_ENABLED)
+ {
+ TvTEvent.init();
+
+ scheduleEventStart();
+ _log.info("TvTEventEngine[TvTManager.TvTManager()]: Started.");
+ }
+ else
+ {
+ _log.info("TvTEventEngine[TvTManager.TvTManager()]: Engine is disabled.");
+ }
+ }
+
+ /**
+ * Initialize new/Returns the one and only instance<br>
+ * <br>
+ * @return TvTManager<br>
+ */
+ public static TvTManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ /**
+ * Starts TvTStartTask
+ */
+ public void scheduleEventStart()
+ {
+ try
+ {
+ Calendar currentTime = Calendar.getInstance();
+ Calendar nextStartTime = null;
+ Calendar testStartTime = null;
+ for (String timeOfDay : Config.TVT_EVENT_INTERVAL)
+ {
+ // Creating a Calendar object from the specified interval value
+ testStartTime = Calendar.getInstance();
+ testStartTime.setLenient(true);
+ String[] splitTimeOfDay = timeOfDay.split(":");
+ testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+ testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+ // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
+ if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+ {
+ testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ // Check for the test date to be the minimum (smallest in the specified list)
+ if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
+ {
+ nextStartTime = testStartTime;
+ }
+ }
+ if (nextStartTime != null)
+ {
+ _task = new TvTStartTask(nextStartTime.getTimeInMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+ catch (Exception e)
+ {
+ _log.warning("TvTEventEngine[TvTManager.scheduleEventStart()]: Error figuring out a start time. Check TvTEventInterval in config file.");
+ }
+ }
+
+ /**
+ * Method to start participation
+ */
+ public void startReg()
+ {
+ if (!TvTEvent.startParticipation())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: Event was cancelled.");
+ _log.warning("TvTEventEngine[TvTManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: Registration opened for " + Config.TVT_EVENT_PARTICIPATION_TIME + " minute(s).");
+
+ // schedule registration end
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.TVT_EVENT_PARTICIPATION_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to start the fight
+ */
+ public void startEvent()
+ {
+ if (!TvTEvent.startFight())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: Event cancelled due to lack of Participation.");
+ _log.info("TvTEventEngine[TvTManager.run()]: Lack of registration, abort event.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: Teleporting participants to an arena in " + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ _task.setStartTime(System.currentTimeMillis() + (60000L * Config.TVT_EVENT_RUNNING_TIME));
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Method to end the event and reward
+ */
+ public void endEvent()
+ {
+ Broadcast.toAllOnlinePlayers(TvTEvent.calculateRewards());
+ TvTEvent.sysMsgToAllParticipants("TvT Event: Teleporting back to the registration npc in " + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
+ TvTEvent.stopFight();
+
+ scheduleEventStart();
+ }
+
+ public void skipDelay()
+ {
+ if (_task.nextRun.cancel(false))
+ {
+ _task.setStartTime(System.currentTimeMillis());
+ ThreadPoolManager.getInstance().executeGeneral(_task);
+ }
+ }
+
+ /**
+ * Class for TvT cycles
+ */
+ class TvTStartTask implements Runnable
+ {
+ private long _startTime;
+ public ScheduledFuture<?> nextRun;
+
+ public TvTStartTask(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ public void setStartTime(long startTime)
+ {
+ _startTime = startTime;
+ }
+
+ @Override
+ public void run()
+ {
+ int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+
+ if (delay > 0)
+ {
+ announce(delay);
+ }
+
+ int nextMsg = 0;
+ if (delay > 3600)
+ {
+ nextMsg = delay - 3600;
+ }
+ else if (delay > 1800)
+ {
+ nextMsg = delay - 1800;
+ }
+ else if (delay > 900)
+ {
+ nextMsg = delay - 900;
+ }
+ else if (delay > 600)
+ {
+ nextMsg = delay - 600;
+ }
+ else if (delay > 300)
+ {
+ nextMsg = delay - 300;
+ }
+ else if (delay > 60)
+ {
+ nextMsg = delay - 60;
+ }
+ else if (delay > 5)
+ {
+ nextMsg = delay - 5;
+ }
+ else if (delay > 0)
+ {
+ nextMsg = delay;
+ }
+ else
+ {
+ // start
+ if (TvTEvent.isInactive())
+ {
+ startReg();
+ }
+ else if (TvTEvent.isParticipating())
+ {
+ startEvent();
+ }
+ else
+ {
+ endEvent();
+ }
+ }
+
+ if (delay > 0)
+ {
+ nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+ }
+ }
+
+ private void announce(long time)
+ {
+ if ((time >= 3600) && ((time % 3600) == 0))
+ {
+ if (TvTEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
+ }
+ else if (TvTEvent.isStarted())
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
+ }
+ }
+ else if (time >= 60)
+ {
+ if (TvTEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: " + (time / 60) + " minute(s) until registration is closed!");
+ }
+ else if (TvTEvent.isStarted())
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60) + " minute(s) until the event is finished!");
+ }
+ }
+ else
+ {
+ if (TvTEvent.isParticipating())
+ {
+ Broadcast.toAllOnlinePlayers("TvT Event: " + time + " second(s) until registration is closed!");
+ }
+ else if (TvTEvent.isStarted())
+ {
+ TvTEvent.sysMsgToAllParticipants("TvT Event: " + time + " second(s) until the event is finished!");
+ }
+ }
+ }
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final TvTManager _instance = new TvTManager();
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/L2Event.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/L2Event.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/entity/L2Event.java (working copy)
@@ -519,7 +519,14 @@
}
eventState = EventState.OFF;
+
+ // TODO: TvT Event
AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
+ // TODO: CTF Event
+ AntiFeedManager.getInstance().clear(AntiFeedManager.CTF_ID);
+ // TODO: DM Event
+ AntiFeedManager.getInstance().clear(AntiFeedManager.DM_ID);
+
unspawnEventNpcs(); // Just in case
// _npcs.clear();
_registeredPlayers.clear();
Index: java/com/l2jserver/gameserver/model/entity/TvTEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/TvTEventTeam.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/entity/TvTEventTeam.java (working copy)
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2004-2015 L2J Server
- *
- * This file is part of L2J Server.
- *
- * L2J Server 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.
- *
- * L2J Server 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 com.l2jserver.gameserver.model.entity;
-
-import java.util.Map;
-
-import javolution.util.FastMap;
-
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-
-/**
- * @author HorridoJoho
- */
-public class TvTEventTeam
-{
- /** The name of the team<br> */
- private final String _name;
- /** The team spot coordinated<br> */
- private int[] _coordinates = new int[3];
- /** The points of the team<br> */
- private short _points;
- /** Name and instance of all participated players in FastMap<br> */
- private Map<Integer, L2PcInstance> _participatedPlayers = new FastMap<>();
-
- /**
- * C'tor initialize the team<br>
- * <br>
- * @param name as String<br>
- * @param coordinates as int[]<br>
- */
- public TvTEventTeam(String name, int[] coordinates)
- {
- _name = name;
- _coordinates = coordinates;
- _points = 0;
- }
-
- /**
- * Adds a player to the team<br>
- * <br>
- * @param playerInstance as L2PcInstance<br>
- * @return boolean: true if success, otherwise false<br>
- */
- public boolean addPlayer(L2PcInstance playerInstance)
- {
- if (playerInstance == null)
- {
- return false;
- }
-
- synchronized (_participatedPlayers)
- {
- _participatedPlayers.put(playerInstance.getObjectId(), playerInstance);
- }
-
- return true;
- }
-
- /**
- * Removes a player from the team
- * @param playerObjectId
- */
- public void removePlayer(int playerObjectId)
- {
- synchronized (_participatedPlayers)
- {
- _participatedPlayers.remove(playerObjectId);
- }
- }
-
- /**
- * Increases the points of the team<br>
- */
- public void increasePoints()
- {
- ++_points;
- }
-
- /**
- * Cleanup the team and make it ready for adding players again<br>
- */
- public void cleanMe()
- {
- _participatedPlayers.clear();
- _participatedPlayers = new FastMap<>();
- _points = 0;
- }
-
- /**
- * Is given player in this team?
- * @param playerObjectId
- * @return boolean: true if player is in this team, otherwise false
- */
- public boolean containsPlayer(int playerObjectId)
- {
- boolean containsPlayer;
-
- synchronized (_participatedPlayers)
- {
- containsPlayer = _participatedPlayers.containsKey(playerObjectId);
- }
-
- return containsPlayer;
- }
-
- /**
- * Returns the name of the team<br>
- * <br>
- * @return String: name of the team<br>
- */
- public String getName()
- {
- return _name;
- }
-
- /**
- * Returns the coordinates of the team spot<br>
- * <br>
- * @return int[]: team coordinates<br>
- */
- public int[] getCoordinates()
- {
- return _coordinates;
- }
-
- /**
- * Returns the points of the team<br>
- * <br>
- * @return short: team points<br>
- */
- public short getPoints()
- {
- return _points;
- }
-
- /**
- * Returns name and instance of all participated players in FastMap<br>
- * <br>
- * @return Map<String, L2PcInstance>: map of players in this team<br>
- */
- public Map<Integer, L2PcInstance> getParticipatedPlayers()
- {
- Map<Integer, L2PcInstance> participatedPlayers = null;
-
- synchronized (_participatedPlayers)
- {
- participatedPlayers = _participatedPlayers;
- }
-
- return participatedPlayers;
- }
-
- /**
- * Returns player count of this team<br>
- * <br>
- * @return int: number of players in team<br>
- */
- public int getParticipatedPlayerCount()
- {
- int participatedPlayerCount;
-
- synchronized (_participatedPlayers)
- {
- participatedPlayerCount = _participatedPlayers.size();
- }
-
- return participatedPlayerCount;
- }
-}
Index: java/com/l2jserver/gameserver/model/entity/TvTEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/TvTEventTeleporter.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/entity/TvTEventTeleporter.java (working copy)
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2004-2015 L2J Server
- *
- * This file is part of L2J Server.
- *
- * L2J Server 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.
- *
- * L2J Server 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 com.l2jserver.gameserver.model.entity;
-
-import com.l2jserver.Config;
-import com.l2jserver.gameserver.ThreadPoolManager;
-import com.l2jserver.gameserver.enums.Team;
-import com.l2jserver.gameserver.model.actor.L2Summon;
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.util.Rnd;
-
-public class TvTEventTeleporter implements Runnable
-{
- /** The instance of the player to teleport */
- private L2PcInstance _playerInstance = null;
- /** Coordinates of the spot to teleport to */
- private int[] _coordinates = new int[3];
- /** Admin removed this player from event */
- private boolean _adminRemove = false;
-
- /**
- * Initialize the teleporter and start the delayed task.
- * @param playerInstance
- * @param coordinates
- * @param fastSchedule
- * @param adminRemove
- */
- public TvTEventTeleporter(L2PcInstance playerInstance, int[] coordinates, boolean fastSchedule, boolean adminRemove)
- {
- _playerInstance = playerInstance;
- _coordinates = coordinates;
- _adminRemove = adminRemove;
-
- long delay = (TvTEvent.isStarted() ? Config.TVT_EVENT_RESPAWN_TELEPORT_DELAY : Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY) * 1000;
-
- ThreadPoolManager.getInstance().scheduleGeneral(this, fastSchedule ? 0 : delay);
- }
-
- /**
- * The task method to teleport the player<br>
- * 1. Unsummon pet if there is one<br>
- * 2. Remove all effects<br>
- * 3. Revive and full heal the player<br>
- * 4. Teleport the player<br>
- * 5. Broadcast status and user info
- */
- @Override
- public void run()
- {
- if (_playerInstance == null)
- {
- return;
- }
-
- L2Summon summon = _playerInstance.getSummon();
-
- if (summon != null)
- {
- summon.unSummon(_playerInstance);
- }
-
- if ((Config.TVT_EVENT_EFFECTS_REMOVAL == 0) || ((Config.TVT_EVENT_EFFECTS_REMOVAL == 1) && ((_playerInstance.getTeam() == Team.NONE) || (_playerInstance.isInDuel() && (_playerInstance.getDuelState() != Duel.DUELSTATE_INTERRUPTED)))))
- {
- _playerInstance.stopAllEffectsExceptThoseThatLastThroughDeath();
- }
-
- if (_playerInstance.isInDuel())
- {
- _playerInstance.setDuelState(Duel.DUELSTATE_INTERRUPTED);
- }
-
- int TvTInstance = TvTEvent.getTvTEventInstance();
- if (TvTInstance != 0)
- {
- if (TvTEvent.isStarted() && !_adminRemove)
- {
- _playerInstance.setInstanceId(TvTInstance);
- }
- else
- {
- _playerInstance.setInstanceId(0);
- }
- }
- else
- {
- _playerInstance.setInstanceId(0);
- }
-
- _playerInstance.doRevive();
-
- _playerInstance.teleToLocation((_coordinates[0] + Rnd.get(101)) - 50, (_coordinates[1] + Rnd.get(101)) - 50, _coordinates[2], false);
-
- if (TvTEvent.isStarted() && !_adminRemove)
- {
- int teamId = TvTEvent.getParticipantTeamId(_playerInstance.getObjectId()) + 1;
- switch (teamId)
- {
- case 0:
- _playerInstance.setTeam(Team.NONE);
- break;
- case 1:
- _playerInstance.setTeam(Team.BLUE);
- break;
- case 2:
- _playerInstance.setTeam(Team.RED);
- break;
- }
- }
- else
- {
- _playerInstance.setTeam(Team.NONE);
- }
-
- _playerInstance.setCurrentCp(_playerInstance.getMaxCp());
- _playerInstance.setCurrentHp(_playerInstance.getMaxHp());
- _playerInstance.setCurrentMp(_playerInstance.getMaxMp());
-
- _playerInstance.broadcastStatusUpdate();
- _playerInstance.broadcastUserInfo();
- }
-}
Index: java/com/l2jserver/gameserver/model/entity/TvTManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/TvTManager.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/entity/TvTManager.java (working copy)
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2004-2015 L2J Server
- *
- * This file is part of L2J Server.
- *
- * L2J Server 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.
- *
- * L2J Server 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 com.l2jserver.gameserver.model.entity;
-
-import java.util.Calendar;
-import java.util.concurrent.ScheduledFuture;
-import java.util.logging.Logger;
-
-import com.l2jserver.Config;
-import com.l2jserver.gameserver.ThreadPoolManager;
-import com.l2jserver.gameserver.util.Broadcast;
-
-/**
- * @author HorridoJoho
- */
-public class TvTManager
-{
- protected static final Logger _log = Logger.getLogger(TvTManager.class.getName());
-
- /** Task for event cycles<br> */
- private TvTStartTask _task;
-
- /**
- * New instance only by getInstance()<br>
- */
- protected TvTManager()
- {
- if (Config.TVT_EVENT_ENABLED)
- {
- TvTEvent.init();
-
- scheduleEventStart();
- _log.info("TvTEventEngine[TvTManager.TvTManager()]: Started.");
- }
- else
- {
- _log.info("TvTEventEngine[TvTManager.TvTManager()]: Engine is disabled.");
- }
- }
-
- /**
- * Initialize new/Returns the one and only instance<br>
- * <br>
- * @return TvTManager<br>
- */
- public static TvTManager getInstance()
- {
- return SingletonHolder._instance;
- }
-
- /**
- * Starts TvTStartTask
- */
- public void scheduleEventStart()
- {
- try
- {
- Calendar currentTime = Calendar.getInstance();
- Calendar nextStartTime = null;
- Calendar testStartTime = null;
- for (String timeOfDay : Config.TVT_EVENT_INTERVAL)
- {
- // Creating a Calendar object from the specified interval value
- testStartTime = Calendar.getInstance();
- testStartTime.setLenient(true);
- String[] splitTimeOfDay = timeOfDay.split(":");
- testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
- testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
- // If the date is in the past, make it the next day (Example: Checking for "1:00", when the time is 23:57.)
- if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
- {
- testStartTime.add(Calendar.DAY_OF_MONTH, 1);
- }
- // Check for the test date to be the minimum (smallest in the specified list)
- if ((nextStartTime == null) || (testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis()))
- {
- nextStartTime = testStartTime;
- }
- }
- if (nextStartTime != null)
- {
- _task = new TvTStartTask(nextStartTime.getTimeInMillis());
- ThreadPoolManager.getInstance().executeGeneral(_task);
- }
- }
- catch (Exception e)
- {
- _log.warning("TvTEventEngine[TvTManager.scheduleEventStart()]: Error figuring out a start time. Check TvTEventInterval in config file.");
- }
- }
-
- /**
- * Method to start participation
- */
- public void startReg()
- {
- if (!TvTEvent.startParticipation())
- {
- Broadcast.toAllOnlinePlayers("TvT Event: Event was cancelled.");
- _log.warning("TvTEventEngine[TvTManager.run()]: Error spawning event npc for participation.");
-
- scheduleEventStart();
- }
- else
- {
- Broadcast.toAllOnlinePlayers("TvT Event: Registration opened for " + Config.TVT_EVENT_PARTICIPATION_TIME + " minute(s).");
-
- // schedule registration end
- _task.setStartTime(System.currentTimeMillis() + (60000L * Config.TVT_EVENT_PARTICIPATION_TIME));
- ThreadPoolManager.getInstance().executeGeneral(_task);
- }
- }
-
- /**
- * Method to start the fight
- */
- public void startEvent()
- {
- if (!TvTEvent.startFight())
- {
- Broadcast.toAllOnlinePlayers("TvT Event: Event cancelled due to lack of Participation.");
- _log.info("TvTEventEngine[TvTManager.run()]: Lack of registration, abort event.");
-
- scheduleEventStart();
- }
- else
- {
- TvTEvent.sysMsgToAllParticipants("TvT Event: Teleporting participants to an arena in " + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
- _task.setStartTime(System.currentTimeMillis() + (60000L * Config.TVT_EVENT_RUNNING_TIME));
- ThreadPoolManager.getInstance().executeGeneral(_task);
- }
- }
-
- /**
- * Method to end the event and reward
- */
- public void endEvent()
- {
- Broadcast.toAllOnlinePlayers(TvTEvent.calculateRewards());
- TvTEvent.sysMsgToAllParticipants("TvT Event: Teleporting back to the registration npc in " + Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY + " second(s).");
- TvTEvent.stopFight();
-
- scheduleEventStart();
- }
-
- public void skipDelay()
- {
- if (_task.nextRun.cancel(false))
- {
- _task.setStartTime(System.currentTimeMillis());
- ThreadPoolManager.getInstance().executeGeneral(_task);
- }
- }
-
- /**
- * Class for TvT cycles
- */
- class TvTStartTask implements Runnable
- {
- private long _startTime;
- public ScheduledFuture<?> nextRun;
-
- public TvTStartTask(long startTime)
- {
- _startTime = startTime;
- }
-
- public void setStartTime(long startTime)
- {
- _startTime = startTime;
- }
-
- @Override
- public void run()
- {
- int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
-
- if (delay > 0)
- {
- announce(delay);
- }
-
- int nextMsg = 0;
- if (delay > 3600)
- {
- nextMsg = delay - 3600;
- }
- else if (delay > 1800)
- {
- nextMsg = delay - 1800;
- }
- else if (delay > 900)
- {
- nextMsg = delay - 900;
- }
- else if (delay > 600)
- {
- nextMsg = delay - 600;
- }
- else if (delay > 300)
- {
- nextMsg = delay - 300;
- }
- else if (delay > 60)
- {
- nextMsg = delay - 60;
- }
- else if (delay > 5)
- {
- nextMsg = delay - 5;
- }
- else if (delay > 0)
- {
- nextMsg = delay;
- }
- else
- {
- // start
- if (TvTEvent.isInactive())
- {
- startReg();
- }
- else if (TvTEvent.isParticipating())
- {
- startEvent();
- }
- else
- {
- endEvent();
- }
- }
-
- if (delay > 0)
- {
- nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
- }
- }
-
- private void announce(long time)
- {
- if ((time >= 3600) && ((time % 3600) == 0))
- {
- if (TvTEvent.isParticipating())
- {
- Broadcast.toAllOnlinePlayers("TvT Event: " + (time / 60 / 60) + " hour(s) until registration is closed!");
- }
- else if (TvTEvent.isStarted())
- {
- TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
- }
- }
- else if (time >= 60)
- {
- if (TvTEvent.isParticipating())
- {
- Broadcast.toAllOnlinePlayers("TvT Event: " + (time / 60) + " minute(s) until registration is closed!");
- }
- else if (TvTEvent.isStarted())
- {
- TvTEvent.sysMsgToAllParticipants("TvT Event: " + (time / 60) + " minute(s) until the event is finished!");
- }
- }
- else
- {
- if (TvTEvent.isParticipating())
- {
- Broadcast.toAllOnlinePlayers("TvT Event: " + time + " second(s) until registration is closed!");
- }
- else if (TvTEvent.isStarted())
- {
- TvTEvent.sysMsgToAllParticipants("TvT Event: " + time + " second(s) until the event is finished!");
- }
- }
- }
- }
-
- private static class SingletonHolder
- {
- protected static final TvTManager _instance = new TvTManager();
- }
-}
Index: java/com/l2jserver/gameserver/model/events/EventType.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/EventType.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/events/EventType.java (working copy)
@@ -88,10 +88,18 @@
import com.l2jserver.gameserver.model.events.impl.character.trap.OnTrapAction;
import com.l2jserver.gameserver.model.events.impl.clan.OnClanWarFinish;
import com.l2jserver.gameserver.model.events.impl.clan.OnClanWarStart;
-import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventFinish;
-import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventKill;
-import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventRegistrationStart;
-import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventStart;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.ctf.OnCTFEventStart;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.dm.OnDMEventStart;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.tvt.OnTvTEventStart;
import com.l2jserver.gameserver.model.events.impl.item.OnItemBypassEvent;
import com.l2jserver.gameserver.model.events.impl.item.OnItemCreate;
import com.l2jserver.gameserver.model.events.impl.item.OnItemTalk;
@@ -217,11 +225,21 @@
// Trap events
ON_TRAP_ACTION(OnTrapAction.class, void.class),
- // TvT events.
+ // TODO: TvT Event
ON_TVT_EVENT_FINISH(OnTvTEventFinish.class, void.class),
ON_TVT_EVENT_KILL(OnTvTEventKill.class, void.class),
ON_TVT_EVENT_REGISTRATION_START(OnTvTEventRegistrationStart.class, void.class),
- ON_TVT_EVENT_START(OnTvTEventStart.class, void.class);
+ ON_TVT_EVENT_START(OnTvTEventStart.class, void.class),
+ // TODO: CTF Event
+ ON_CTF_EVENT_FINISH(OnCTFEventFinish.class, void.class),
+ ON_CTF_EVENT_KILL(OnCTFEventKill.class, void.class),
+ ON_CTF_EVENT_REGISTRATION_START(OnCTFEventRegistrationStart.class, void.class),
+ ON_CTF_EVENT_START(OnCTFEventStart.class, void.class),
+ // TODO: DM Event
+ ON_DM_EVENT_FINISH(OnDMEventFinish.class, void.class),
+ ON_DM_EVENT_KILL(OnDMEventKill.class, void.class),
+ ON_DM_EVENT_REGISTRATION_START(OnDMEventRegistrationStart.class, void.class),
+ ON_DM_EVENT_START(OnDMEventStart.class, void.class);
private final Class<? extends IBaseEvent> _eventClass;
private final Class<?>[] _returnClass;
Index: java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventFinish.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventFinish.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventFinish.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.ctf;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnCTFEventFinish implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_CTF_EVENT_FINISH;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventKill.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventKill.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventKill.java (working copy)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.ctf;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEventTeam;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnCTFEventKill implements IBaseEvent
+{
+ private final L2PcInstance _killer;
+ private final L2PcInstance _victim;
+ private final CTFEventTeam _killerTeam;
+
+ public OnCTFEventKill(L2PcInstance killer, L2PcInstance victim, CTFEventTeam killerTeam)
+ {
+ _killer = killer;
+ _victim = victim;
+ _killerTeam = killerTeam;
+ }
+
+ public L2PcInstance getKiller()
+ {
+ return _killer;
+ }
+
+ public L2PcInstance getVictim()
+ {
+ return _victim;
+ }
+
+ public CTFEventTeam getKillerTeam()
+ {
+ return _killerTeam;
+ }
+
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_CTF_EVENT_KILL;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventRegistrationStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventRegistrationStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventRegistrationStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.ctf;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnCTFEventRegistrationStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_CTF_EVENT_REGISTRATION_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.ctf;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnCTFEventStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_CTF_EVENT_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventFinish.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventFinish.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventFinish.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.ctf;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnCTFEventFinish implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_CTF_EVENT_FINISH;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventKill.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventKill.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventKill.java (working copy)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.ctf;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEventTeam;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnCTFEventKill implements IBaseEvent
+{
+ private final L2PcInstance _killer;
+ private final L2PcInstance _victim;
+ private final CTFEventTeam _killerTeam;
+
+ public OnCTFEventKill(L2PcInstance killer, L2PcInstance victim, CTFEventTeam killerTeam)
+ {
+ _killer = killer;
+ _victim = victim;
+ _killerTeam = killerTeam;
+ }
+
+ public L2PcInstance getKiller()
+ {
+ return _killer;
+ }
+
+ public L2PcInstance getVictim()
+ {
+ return _victim;
+ }
+
+ public CTFEventTeam getKillerTeam()
+ {
+ return _killerTeam;
+ }
+
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_CTF_EVENT_KILL;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventRegistrationStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventRegistrationStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventRegistrationStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.ctf;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnCTFEventRegistrationStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_CTF_EVENT_REGISTRATION_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/ctf/OnCTFEventStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.ctf;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnCTFEventStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_CTF_EVENT_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventFinish.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventFinish.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventFinish.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.dm;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnDMEventFinish implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_DM_EVENT_FINISH;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventKill.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventKill.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventKill.java (working copy)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.dm;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.events.dm.DMEventTeam;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnDMEventKill implements IBaseEvent
+{
+ private final L2PcInstance _killer;
+ private final L2PcInstance _victim;
+ private final DMEventTeam _killerTeam;
+
+ public OnDMEventKill(L2PcInstance killer, L2PcInstance victim, DMEventTeam killerTeam)
+ {
+ _killer = killer;
+ _victim = victim;
+ _killerTeam = killerTeam;
+ }
+
+ public L2PcInstance getKiller()
+ {
+ return _killer;
+ }
+
+ public L2PcInstance getVictim()
+ {
+ return _victim;
+ }
+
+ public DMEventTeam getKillerTeam()
+ {
+ return _killerTeam;
+ }
+
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_DM_EVENT_KILL;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventRegistrationStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventRegistrationStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventRegistrationStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.dm;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnDMEventRegistrationStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_DM_EVENT_REGISTRATION_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.dm;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnDMEventStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_DM_EVENT_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventFinish.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventFinish.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventFinish.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.dm;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnDMEventFinish implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_DM_EVENT_FINISH;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventKill.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventKill.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventKill.java (working copy)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.dm;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.events.dm.DMEventTeam;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnDMEventKill implements IBaseEvent
+{
+ private final L2PcInstance _killer;
+ private final L2PcInstance _victim;
+ private final DMEventTeam _killerTeam;
+
+ public OnDMEventKill(L2PcInstance killer, L2PcInstance victim, DMEventTeam killerTeam)
+ {
+ _killer = killer;
+ _victim = victim;
+ _killerTeam = killerTeam;
+ }
+
+ public L2PcInstance getKiller()
+ {
+ return _killer;
+ }
+
+ public L2PcInstance getVictim()
+ {
+ return _victim;
+ }
+
+ public DMEventTeam getKillerTeam()
+ {
+ return _killerTeam;
+ }
+
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_DM_EVENT_KILL;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventRegistrationStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventRegistrationStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventRegistrationStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.dm;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnDMEventRegistrationStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_DM_EVENT_REGISTRATION_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/dm/OnDMEventStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.dm;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnDMEventStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_DM_EVENT_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventFinish.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventFinish.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventFinish.java (working copy)
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2004-2015 L2J Server
- *
- * This file is part of L2J Server.
- *
- * L2J Server 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.
- *
- * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events;
-
-import com.l2jserver.gameserver.model.events.EventType;
-import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
-
-/**
- * @author UnAfraid
- */
-public class OnTvTEventFinish implements IBaseEvent
-{
- @Override
- public EventType getType()
- {
- return EventType.ON_TVT_EVENT_FINISH;
- }
-}
Index: java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventKill.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventKill.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventKill.java (working copy)
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2004-2015 L2J Server
- *
- * This file is part of L2J Server.
- *
- * L2J Server 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.
- *
- * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events;
-
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.entity.TvTEventTeam;
-import com.l2jserver.gameserver.model.events.EventType;
-import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
-
-/**
- * @author UnAfraid
- */
-public class OnTvTEventKill implements IBaseEvent
-{
- private final L2PcInstance _killer;
- private final L2PcInstance _victim;
- private final TvTEventTeam _killerTeam;
-
- public OnTvTEventKill(L2PcInstance killer, L2PcInstance victim, TvTEventTeam killerTeam)
- {
- _killer = killer;
- _victim = victim;
- _killerTeam = killerTeam;
- }
-
- public L2PcInstance getKiller()
- {
- return _killer;
- }
-
- public L2PcInstance getVictim()
- {
- return _victim;
- }
-
- public TvTEventTeam getKillerTeam()
- {
- return _killerTeam;
- }
-
- @Override
- public EventType getType()
- {
- return EventType.ON_TVT_EVENT_KILL;
- }
-}
Index: java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventRegistrationStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventRegistrationStart.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventRegistrationStart.java (working copy)
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2004-2015 L2J Server
- *
- * This file is part of L2J Server.
- *
- * L2J Server 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.
- *
- * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events;
-
-import com.l2jserver.gameserver.model.events.EventType;
-import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
-
-/**
- * @author UnAfraid
- */
-public class OnTvTEventRegistrationStart implements IBaseEvent
-{
- @Override
- public EventType getType()
- {
- return EventType.ON_TVT_EVENT_REGISTRATION_START;
- }
-}
Index: java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventStart.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/events/impl/events/OnTvTEventStart.java (working copy)
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2004-2015 L2J Server
- *
- * This file is part of L2J Server.
- *
- * L2J Server 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.
- *
- * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events;
-
-import com.l2jserver.gameserver.model.events.EventType;
-import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
-
-/**
- * @author UnAfraid
- */
-public class OnTvTEventStart implements IBaseEvent
-{
- @Override
- public EventType getType()
- {
- return EventType.ON_TVT_EVENT_START;
- }
-}
Index: java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventFinish.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventFinish.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventFinish.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.tvt;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnTvTEventFinish implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_TVT_EVENT_FINISH;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventKill.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventKill.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventKill.java (working copy)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.tvt;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEventTeam;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnTvTEventKill implements IBaseEvent
+{
+ private final L2PcInstance _killer;
+ private final L2PcInstance _victim;
+ private final TvTEventTeam _killerTeam;
+
+ public OnTvTEventKill(L2PcInstance killer, L2PcInstance victim, TvTEventTeam killerTeam)
+ {
+ _killer = killer;
+ _victim = victim;
+ _killerTeam = killerTeam;
+ }
+
+ public L2PcInstance getKiller()
+ {
+ return _killer;
+ }
+
+ public L2PcInstance getVictim()
+ {
+ return _victim;
+ }
+
+ public TvTEventTeam getKillerTeam()
+ {
+ return _killerTeam;
+ }
+
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_TVT_EVENT_KILL;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventRegistrationStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventRegistrationStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventRegistrationStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.tvt;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnTvTEventRegistrationStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_TVT_EVENT_REGISTRATION_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.tvt;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnTvTEventStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_TVT_EVENT_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventFinish.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventFinish.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventFinish.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.tvt;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnTvTEventFinish implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_TVT_EVENT_FINISH;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventKill.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventKill.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventKill.java (working copy)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.tvt;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEventTeam;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnTvTEventKill implements IBaseEvent
+{
+ private final L2PcInstance _killer;
+ private final L2PcInstance _victim;
+ private final TvTEventTeam _killerTeam;
+
+ public OnTvTEventKill(L2PcInstance killer, L2PcInstance victim, TvTEventTeam killerTeam)
+ {
+ _killer = killer;
+ _victim = victim;
+ _killerTeam = killerTeam;
+ }
+
+ public L2PcInstance getKiller()
+ {
+ return _killer;
+ }
+
+ public L2PcInstance getVictim()
+ {
+ return _victim;
+ }
+
+ public TvTEventTeam getKillerTeam()
+ {
+ return _killerTeam;
+ }
+
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_TVT_EVENT_KILL;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventRegistrationStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventRegistrationStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventRegistrationStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.tvt;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnTvTEventRegistrationStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_TVT_EVENT_REGISTRATION_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventStart.java
===================================================================
--- java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventStart.java (revision 0)
+++ java/com/l2jserver/gameserver/model/events/impl/events/tvt/OnTvTEventStart.java (working copy)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2004-2015 L2J Server
+ *
+ * This file is part of L2J Server.
+ *
+ * L2J Server 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.
+ *
+ * L2J Server 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 com.l2jserver.gameserver.model.events.impl.events.tvt;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnTvTEventStart implements IBaseEvent
+{
+ @Override
+ public EventType getType()
+ {
+ return EventType.ON_TVT_EVENT_START;
+ }
+}
Index: java/com/l2jserver/gameserver/model/olympiad/AbstractOlympiadGame.java
===================================================================
--- java/com/l2jserver/gameserver/model/olympiad/AbstractOlympiadGame.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/olympiad/AbstractOlympiadGame.java (working copy)
@@ -33,7 +33,9 @@
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEvent;
+import com.l2jserver.gameserver.model.entity.events.dm.DMEvent;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEvent;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.zone.type.L2OlympiadStadiumZone;
@@ -122,8 +124,8 @@
return SystemMessage.getSystemMessage(SystemMessageId.THE_GAME_HAS_BEEN_CANCELLED_BECAUSE_THE_OTHER_PARTY_ENDS_THE_GAME);
}
- // safety precautions
- if (player.inObserverMode() || TvTEvent.isPlayerParticipant(player.getObjectId()))
+ // TODO: TvT Event - CTF Event - DM Event - safety precautions
+ if (player.inObserverMode() || TvTEvent.isPlayerParticipant(player.getObjectId()) || DMEvent.isPlayerParticipant(player.getObjectId()) || CTFEvent.isPlayerParticipant(player.getObjectId()))
{
return SystemMessage.getSystemMessage(SystemMessageId.THE_GAME_HAS_BEEN_CANCELLED_BECAUSE_THE_OTHER_PARTY_DOES_NOT_MEET_THE_REQUIREMENTS_FOR_JOINING_THE_GAME);
}
Index: java/com/l2jserver/gameserver/model/olympiad/OlympiadManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/olympiad/OlympiadManager.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/olympiad/OlympiadManager.java (working copy)
@@ -492,7 +492,7 @@
final int charId = noble.getObjectId();
if (noble.isOnEvent())
{
- player.sendMessage("You can't join olympiad while participating on TvT Event.");
+ player.sendMessage("You can't join olympiad while participating on Event.");
return false;
}
Index: java/com/l2jserver/gameserver/model/skills/Skill.java
===================================================================
--- java/com/l2jserver/gameserver/model/skills/Skill.java (revision 10485)
+++ java/com/l2jserver/gameserver/model/skills/Skill.java (working copy)
@@ -53,7 +53,9 @@
import com.l2jserver.gameserver.model.conditions.Condition;
import com.l2jserver.gameserver.model.effects.AbstractEffect;
import com.l2jserver.gameserver.model.effects.L2EffectType;
-import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEvent;
+import com.l2jserver.gameserver.model.entity.events.dm.DMEvent;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEvent;
import com.l2jserver.gameserver.model.holders.ItemHolder;
import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
@@ -1191,11 +1193,24 @@
}
}
+ // TODO: TvT Event
if (!TvTEvent.checkForTvTSkill(player, targetPlayer, skill))
{
return false;
}
+ // TODO: CTF Event
+ if (!CTFEvent.checkForCTFSkill(player, targetPlayer, skill))
+ {
+ return false;
+ }
+
+ // TODO: DM Event
+ if (!DMEvent.checkForDMSkill(player, targetPlayer, skill))
+ {
+ return false;
+ }
+
if (!sourceInArena && !(targetPlayer.isInsideZone(ZoneId.PVP) && !targetPlayer.isInsideZone(ZoneId.SIEGE)))
{
if ((player.getAllyId() != 0) && (player.getAllyId() == targetPlayer.getAllyId()))
Index: java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java
===================================================================
--- java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java (revision 10485)
+++ java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java (working copy)
@@ -52,9 +52,11 @@
import com.l2jserver.gameserver.model.entity.FortSiege;
import com.l2jserver.gameserver.model.entity.L2Event;
import com.l2jserver.gameserver.model.entity.Siege;
-import com.l2jserver.gameserver.model.entity.TvTEvent;
import com.l2jserver.gameserver.model.entity.clanhall.AuctionableHall;
import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
+import com.l2jserver.gameserver.model.entity.events.ctf.CTFEvent;
+import com.l2jserver.gameserver.model.entity.events.dm.DMEvent;
+import com.l2jserver.gameserver.model.entity.events.tvt.TvTEvent;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.model.quest.QuestState;
@@ -538,7 +540,12 @@
}
}
+ // TODO: TvT Event
TvTEvent.onLogin(activeChar);
+ // TODO: CTF Event
+ CTFEvent.onLogin(activeChar);
+ // TODO: DM Event
+ DMEvent.onLogin(activeChar);
if (Config.WELCOME_MESSAGE_ENABLED)
{
Index: java/com/l2jserver/gameserver/network/NpcStringId.java
===================================================================
--- java/com/l2jserver/gameserver/network/NpcStringId.java (revision 10485)
+++ java/com/l2jserver/gameserver/network/NpcStringId.java (working copy)
@@ -49,6 +49,12 @@
public static final NpcStringId[] EMPTY_ARRAY = new NpcStringId[0];
/**
+ * ID: -1<br>
+ * Message: Dummy non-existent id used for broadcasting ExShowScreenMessage text.
+ */
+ public static final NpcStringId NONE;
+
+ /**
* ID: 1<br>
* Message: Hello! I am $s1. You are $s2, right? Hehehe
*/
@@ -21619,6 +21625,7 @@
static
{
+ NONE = new NpcStringId(-1);
HELLO_I_AM_S1_YOU_ARE_S2_RIGHT_HEHEHE = new NpcStringId(1);
S1_S2_S3_S4_S5_HEHEHE = new NpcStringId(2);
WITHDRAW_THE_FEE_FOR_THE_NEXT_TIME_AT_S1_S2_S4 = new NpcStringId(5);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment