Skip to content

Instantly share code, notes, and snippets.

@u3games
Created April 5, 2014 14:27
Show Gist options
  • Save u3games/9992679 to your computer and use it in GitHub Desktop.
Save u3games/9992679 to your computer and use it in GitHub Desktop.
Index: dist/game/config/L2JMods.properties
===================================================================
--- dist/game/config/L2JMods.properties (revision 6498)
+++ dist/game/config/L2JMods.properties (working copy)
@@ -127,7 +127,6 @@
# ---------------------------------------------------------------------------
# Team vs. Team Event Engine (by FBIagent)
# ---------------------------------------------------------------------------
-
# <u><b><font color="red">WARNING: this mod require custom NPC table support turned on !</font></b></u>
# CustomNpcTable = True in General.properties
# ---------------------------------------------------------------------------
@@ -226,6 +225,206 @@
# ---------------------------------------------------------------------------
+# 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
+CTFEventInInstance = False
+
+# Name of the instance file for CTF
+CTFEventInstanceFile = coliseum.xml
+
+# Times CTF will occur (24h format).
+CTFEventInterval = 10:00,16:00,22:00,4:00
+
+# Registration timer from start of event (in minutes).
+CTFEventParticipationTime = 60
+
+# Event running time (in minutes).
+CTFEventRunningTime = 20
+
+# CTF Event NPC (create a custom npc of type L2CTFEventNpc).
+CTFEventParticipationNpcId = 70010
+
+# CTF Event Participation Fee (itemId, number). Fee is not returned.
+# Example: 57,100000
+# Default = none
+CTFEventParticipationFee = 0,0
+
+# Location for CTFEvent NPC to spawn in form x,y,z[,heading]
+CTFEventParticipationNpcCoordinates = 83425,148585,-3406
+
+# Min/Max amount of players allowed in each team.
+CTFEventMinPlayersInTeams = 1
+CTFEventMaxPlayersInTeams = 20
+
+# Min/Max level of players that may join the event.
+CTFEventMinPlayerLevel = 1
+CTFEventMaxPlayerLevel = 85
+
+# Repsawn and exit delay timers (in seconds).
+CTFEventRespawnTeleportDelay = 10
+CTFEventStartLeaveTeleportDelay = 10
+
+# First Team - Name, Start/Death x,y,z location.
+CTFEventTeam1Name = Team1
+CTFEventTeam1Coordinates = 148695,46725,-3414
+
+# Second Team - Name, Start/Death x,y,z location.
+CTFEventTeam2Name = Team2
+CTFEventTeam2Coordinates = 149999,46728,-3414
+
+# 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
+
+# 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
+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
+
+
+# ---------------------------------------------------------------------------
+# Deathmatch 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
+DMEventEnabled = False
+
+# DM in instance
+DMEventInInstance = False
+
+# Name of the instance file for DM
+DMEventInstanceFile = coliseum.xml
+
+# Times DM will occur (24h format).
+DMEventInterval = 10:00,16:00,22:00,4:00
+
+# Registration timer from start of event (in minutes).
+DMEventParticipationTime = 60
+
+# Event running time (in minutes).
+DMEventRunningTime = 20
+
+# DM Event NPC (create a custom npc of type L2DMEventNpc).
+DMEventParticipationNpcId = 70010
+
+# DM Event Participation Fee (itemId, number). Fee is not returned.
+# Example: 57,100000
+# Default = none
+DMEventParticipationFee = 0,0
+
+# Location for DMEvent NPC to spawn in form x,y,z[,heading]
+DMEventParticipationNpcCoordinates = 83425,148585,-3406
+
+# Min/Max amount of players allowed in each team.
+DMEventMinPlayersInTeams = 1
+DMEventMaxPlayersInTeams = 20
+
+# Min/Max level of players that may join the event.
+DMEventMinPlayerLevel = 1
+DMEventMaxPlayerLevel = 85
+
+# Repsawn and exit delay timers (in seconds).
+DMEventRespawnTeleportDelay = 10
+DMEventStartLeaveTeleportDelay = 10
+
+# First Team - Name, Start/Death x,y,z location.
+DMEventTeam1Name = Team1
+DMEventTeam1Coordinates = 148695,46725,-3414
+
+# Second Team - Name, Start/Death x,y,z location.
+DMEventTeam2Name = Team2
+DMEventTeam2Coordinates = 149999,46728,-3414
+
+# Reward for winning team.
+# Example: DMEventReward = itemId,amount;itemId,amount;itemId,amount
+DMEventReward = 57,100000
+
+# 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 =
+
+# Should both teams get reward if there's a tie?
+DMRewardTeamTie = 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
+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 6498)
+++ java/com/l2jserver/Config.java (working copy)
@@ -730,6 +730,70 @@
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;
+ 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_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 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 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;
+ 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_IN_TEAMS;
+ public static int DM_EVENT_MAX_PLAYERS_IN_TEAMS;
+ public static int DM_EVENT_RESPAWN_TELEPORT_DELAY;
+ public static int DM_EVENT_START_LEAVE_TELEPORT_DELAY;
+ public static String DM_EVENT_TEAM_1_NAME;
+ public static int[] DM_EVENT_TEAM_1_COORDINATES = new int[3];
+ public static String DM_EVENT_TEAM_2_NAME;
+ public static int[] DM_EVENT_TEAM_2_COORDINATES = new int[3];
+ public static List<int[]> DM_EVENT_REWARDS;
+ public static boolean DM_EVENT_TARGET_TEAM_MEMBERS_ALLOWED;
+ 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_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;
@@ -2294,6 +2358,22 @@
TVT_EVENT_RUNNING_TIME = L2JModSettings.getInt("TvTEventRunningTime", 1800);
TVT_EVENT_PARTICIPATION_NPC_ID = L2JModSettings.getInt("TvTEventParticipationNpcId", 0);
+ 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);
+
+ 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", "20: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", 0);
+
L2JMOD_ALLOW_WEDDING = L2JModSettings.getBoolean("AllowWedding", false);
L2JMOD_WEDDING_PRICE = L2JModSettings.getInt("WeddingPrice", 250000000);
L2JMOD_WEDDING_PUNISH_INFIDELITY = L2JModSettings.getBoolean("WeddingPunishInfidelity", true);
@@ -2506,6 +2586,404 @@
}
}
+ 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);
+ 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("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, "\""));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ 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 ArrayList<>();
+ DM_DOORS_IDS_TO_OPEN = new ArrayList<>();
+ DM_DOORS_IDS_TO_CLOSE = new ArrayList<>();
+ DM_EVENT_PARTICIPATION_NPC_COORDINATES = new int[4];
+ DM_EVENT_TEAM_1_COORDINATES = new int[3];
+ DM_EVENT_TEAM_2_COORDINATES = new int[3];
+ 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_IN_TEAMS = L2JModSettings.getInt("DMEventMinPlayersInTeams", 1);
+ DM_EVENT_MAX_PLAYERS_IN_TEAMS = L2JModSettings.getInt("DMEventMaxPlayersInTeams", 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_TEAM_1_NAME = L2JModSettings.getString("DMEventTeam1Name", "Team1");
+ DMNpcCoords = L2JModSettings.getString("DMEventTeam1Coordinates", "0,0,0").split(",");
+ if (DMNpcCoords.length < 3)
+ {
+ DM_EVENT_ENABLED = false;
+ _log.warning("DMEventEngine[Config.load()]: invalid config property -> DMEventTeam1Coordinates");
+ }
+ else
+ {
+ DM_EVENT_TEAM_1_COORDINATES[0] = Integer.parseInt(DMNpcCoords[0]);
+ DM_EVENT_TEAM_1_COORDINATES[1] = Integer.parseInt(DMNpcCoords[1]);
+ DM_EVENT_TEAM_1_COORDINATES[2] = Integer.parseInt(DMNpcCoords[2]);
+ DM_EVENT_TEAM_2_NAME = L2JModSettings.getString("DMEventTeam2Name", "Team2");
+ DMNpcCoords = L2JModSettings.getString("DMEventTeam2Coordinates", "0,0,0").split(",");
+ if (DMNpcCoords.length < 3)
+ {
+ DM_EVENT_ENABLED = false;
+ _log.warning("DMEventEngine[Config.load()]: invalid config property -> DMEventTeam2Coordinates");
+ }
+ else
+ {
+ DM_EVENT_TEAM_2_COORDINATES[0] = Integer.parseInt(DMNpcCoords[0]);
+ DM_EVENT_TEAM_2_COORDINATES[1] = Integer.parseInt(DMNpcCoords[1]);
+ DM_EVENT_TEAM_2_COORDINATES[2] = Integer.parseInt(DMNpcCoords[2]);
+ 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");
+ }
+ }
+ DMNpcCoords = L2JModSettings.getString("DMEventReward", "57,100000").split(";");
+ for (String reward : DMNpcCoords)
+ {
+ String[] rewardSplit = reward.split(",");
+ if (rewardSplit.length != 2)
+ {
+ _log.warning(StringUtil.concat("DMEventEngine[Config.load()]: invalid config property -> DMEventReward \"", reward, "\""));
+ }
+ else
+ {
+ try
+ {
+ DM_EVENT_REWARDS.add(new int[]
+ {
+ Integer.parseInt(rewardSplit[0]),
+ Integer.parseInt(rewardSplit[1])
+ });
+ }
+ catch (NumberFormatException nfe)
+ {
+ if (!reward.isEmpty())
+ {
+ _log.warning(StringUtil.concat("DMEventEngine[Config.load()]: invalid config property -> DMEventReward \"", reward, "\""));
+ }
+ }
+ }
+ }
+
+ DM_EVENT_TARGET_TEAM_MEMBERS_ALLOWED = L2JModSettings.getBoolean("DMEventTargetTeamMembersAllowed", true);
+ 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_REWARD_TEAM_TIE = L2JModSettings.getBoolean("DMRewardTeamTie", 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);
@@ -3604,6 +4082,36 @@
case "tvteventparticipationnpcid":
TVT_EVENT_PARTICIPATION_NPC_ID = Integer.parseInt(pValue);
break;
+ 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;
+ 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;
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 6498)
+++ java/com/l2jserver/gameserver/engines/DocumentBase.java (working copy)
@@ -101,6 +101,8 @@
import com.l2jserver.gameserver.model.conditions.ConditionPlayerSubclass;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerTransformationId;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerTvTEvent;
+import com.l2jserver.gameserver.model.conditions.ConditionPlayerCTFEvent;
+import com.l2jserver.gameserver.model.conditions.ConditionPlayerDMEvent;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerVehicleMounted;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerWeight;
import com.l2jserver.gameserver.model.conditions.ConditionSiegeZone;
@@ -682,6 +684,18 @@
cond = joinAnd(cond, new ConditionPlayerTvTEvent(val));
break;
}
+ case "onctfevent":
+ {
+ boolean val = Boolean.parseBoolean(a.getNodeValue());
+ cond = joinAnd(cond, new ConditionPlayerCTFEvent(val));
+ break;
+ }
+ 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/enums/InstanceType.java
===================================================================
--- java/com/l2jserver/gameserver/enums/InstanceType.java (revision 6498)
+++ java/com/l2jserver/gameserver/enums/InstanceType.java (working copy)
@@ -108,6 +108,8 @@
L2ClassMasterInstance(L2NpcInstance),
L2NpcBufferInstance(L2Npc),
L2TvTEventNpcInstance(L2Npc),
+ L2CTFEventNpcInstance(L2Npc),
+ L2DMEventNpcInstance(L2Npc),
L2WeddingManagerInstance(L2Npc),
L2EventMobInstance(L2Npc);
Index: java/com/l2jserver/gameserver/GameServer.java
===================================================================
--- java/com/l2jserver/gameserver/GameServer.java (revision 6498)
+++ java/com/l2jserver/gameserver/GameServer.java (working copy)
@@ -129,6 +129,8 @@
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.CTFManager;
+import com.l2jserver.gameserver.model.entity.DMManager;
import com.l2jserver.gameserver.model.olympiad.Olympiad;
import com.l2jserver.gameserver.network.L2GameClient;
import com.l2jserver.gameserver.network.L2GamePacketHandler;
@@ -394,6 +396,8 @@
_log.info("IdFactory: Free ObjectID's remaining: " + IdFactory.getInstance().size());
TvTManager.getInstance();
+ CTFManager.getInstance();
+ 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 6498)
+++ java/com/l2jserver/gameserver/instancemanager/AntiFeedManager.java (working copy)
@@ -35,7 +35,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 L2FastMap<>(true);
private final L2HashMap<Integer, Map<Integer, Connections>> _eventIPs = new L2HashMap<>();
Index: java/com/l2jserver/gameserver/model/actor/instance/L2CTFEventNpcInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2CTFEventNpcInstance.java (revision 0)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2CTFEventNpcInstance.java (working copy)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2004-2014 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.actor.instance;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.enums.InstanceType;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.entity.CTFEvent;
+import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+
+public class L2CTFEventNpcInstance extends L2Npc
+{
+ private static final String htmlPath = "data/html/mods/CTFEvent/";
+
+ public L2CTFEventNpcInstance(int objectId, L2NpcTemplate template)
+ {
+ super(objectId, template);
+ setInstanceType(InstanceType.L2CTFEventNpcInstance);
+ }
+
+ @Override
+ public void onBypassFeedback(L2PcInstance playerInstance, String command)
+ {
+ CTFEvent.onBypass(command, playerInstance);
+ }
+
+ @Override
+ public void showChatWindow(L2PcInstance playerInstance, int val)
+ {
+ if (playerInstance == null)
+ {
+ return;
+ }
+
+ if (CTFEvent.isParticipating())
+ {
+ final boolean isParticipant = CTFEvent.isPlayerParticipant(playerInstance.getObjectId());
+ final String htmContent;
+
+ if (!isParticipant)
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Participation.htm");
+ }
+ else
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "RemoveParticipation.htm");
+ }
+
+ if (htmContent != null)
+ {
+ int[] teamsPlayerCounts = CTFEvent.getTeamsPlayerCounts();
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage(getObjectId());
+
+ npcHtmlMessage.setHtml(htmContent);
+ npcHtmlMessage.replace("%objectId%", String.valueOf(getObjectId()));
+ npcHtmlMessage.replace("%team1name%", Config.CTF_EVENT_TEAM_1_NAME);
+ npcHtmlMessage.replace("%team1playercount%", String.valueOf(teamsPlayerCounts[0]));
+ npcHtmlMessage.replace("%team2name%", Config.CTF_EVENT_TEAM_2_NAME);
+ npcHtmlMessage.replace("%team2playercount%", String.valueOf(teamsPlayerCounts[1]));
+ npcHtmlMessage.replace("%playercount%", String.valueOf(teamsPlayerCounts[0] + teamsPlayerCounts[1]));
+ if (!isParticipant)
+ {
+ npcHtmlMessage.replace("%fee%", CTFEvent.getParticipationFee());
+ }
+
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+ else if (CTFEvent.isStarting() || CTFEvent.isStarted())
+ {
+ final String htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Status.htm");
+
+ if (htmContent != null)
+ {
+ int[] teamsPlayerCounts = CTFEvent.getTeamsPlayerCounts();
+ int[] teamsPointsCounts = CTFEvent.getTeamsPoints();
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage(getObjectId());
+
+ npcHtmlMessage.setHtml(htmContent);
+ // npcHtmlMessage.replace("%objectId%", String.valueOf(getObjectId()));
+ npcHtmlMessage.replace("%team1name%", Config.CTF_EVENT_TEAM_1_NAME);
+ npcHtmlMessage.replace("%team1playercount%", String.valueOf(teamsPlayerCounts[0]));
+ npcHtmlMessage.replace("%team1points%", String.valueOf(teamsPointsCounts[0]));
+ npcHtmlMessage.replace("%team2name%", Config.CTF_EVENT_TEAM_2_NAME);
+ npcHtmlMessage.replace("%team2playercount%", String.valueOf(teamsPlayerCounts[1]));
+ npcHtmlMessage.replace("%team2points%", String.valueOf(teamsPointsCounts[1])); // <---- array index from 0 to 1 thx DaRkRaGe
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+
+ playerInstance.sendPacket(ActionFailed.STATIC_PACKET);
+ }
+}
Index: java/com/l2jserver/gameserver/model/actor/instance/L2CubicInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2CubicInstance.java (revision 6498)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2CubicInstance.java (working copy)
@@ -39,7 +39,11 @@
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.CTFEvent;
+import com.l2jserver.gameserver.model.entity.DMEvent;
import com.l2jserver.gameserver.model.entity.TvTEventTeam;
+import com.l2jserver.gameserver.model.entity.CTFEventTeam;
+import com.l2jserver.gameserver.model.entity.DMEventTeam;
import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.stats.Formulas;
@@ -275,6 +279,36 @@
}
return;
}
+ // 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;
+ }
+ // DM event targeting
+ if (DMEvent.isStarted() && DMEvent.isPlayerParticipant(_owner.getObjectId()))
+ {
+ DMEventTeam enemyTeam = DMEvent.getParticipantEnemyTeam(_owner.getObjectId());
+
+ if (ownerTarget.getActingPlayer() != null)
+ {
+ L2PcInstance target = ownerTarget.getActingPlayer();
+ if (enemyTeam.containsPlayer(target.getObjectId()) && !(target.isDead()))
+ {
+ _target = (L2Character) ownerTarget;
+ }
+ }
+ return;
+ }
// Duel targeting
if (_owner.isInDuel())
{
Index: java/com/l2jserver/gameserver/model/actor/instance/L2DMEventNpcInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2DMEventNpcInstance.java (revision 0)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2DMEventNpcInstance.java (working copy)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2004-2014 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.actor.instance;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.enums.InstanceType;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.entity.DMEvent;
+import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+
+public class L2DMEventNpcInstance extends L2Npc
+{
+ private static final String htmlPath = "data/html/mods/DMEvent/";
+
+ public L2DMEventNpcInstance(int objectId, L2NpcTemplate template)
+ {
+ super(objectId, template);
+ setInstanceType(InstanceType.L2DMEventNpcInstance);
+ }
+
+ @Override
+ public void onBypassFeedback(L2PcInstance playerInstance, String command)
+ {
+ DMEvent.onBypass(command, playerInstance);
+ }
+
+ @Override
+ public void showChatWindow(L2PcInstance playerInstance, int val)
+ {
+ if (playerInstance == null)
+ {
+ return;
+ }
+
+ if (DMEvent.isParticipating())
+ {
+ final boolean isParticipant = DMEvent.isPlayerParticipant(playerInstance.getObjectId());
+ final String htmContent;
+
+ if (!isParticipant)
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Participation.htm");
+ }
+ else
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "RemoveParticipation.htm");
+ }
+
+ if (htmContent != null)
+ {
+ int[] teamsPlayerCounts = DMEvent.getTeamsPlayerCounts();
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage(getObjectId());
+
+ npcHtmlMessage.setHtml(htmContent);
+ npcHtmlMessage.replace("%objectId%", String.valueOf(getObjectId()));
+ npcHtmlMessage.replace("%team1name%", Config.DM_EVENT_TEAM_1_NAME);
+ npcHtmlMessage.replace("%team1playercount%", String.valueOf(teamsPlayerCounts[0]));
+ npcHtmlMessage.replace("%team2name%", Config.DM_EVENT_TEAM_2_NAME);
+ npcHtmlMessage.replace("%team2playercount%", String.valueOf(teamsPlayerCounts[1]));
+ npcHtmlMessage.replace("%playercount%", String.valueOf(teamsPlayerCounts[0] + teamsPlayerCounts[1]));
+ if (!isParticipant)
+ {
+ npcHtmlMessage.replace("%fee%", DMEvent.getParticipationFee());
+ }
+
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+ else if (DMEvent.isStarting() || DMEvent.isStarted())
+ {
+ final String htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Status.htm");
+
+ if (htmContent != null)
+ {
+ int[] teamsPlayerCounts = DMEvent.getTeamsPlayerCounts();
+ int[] teamsPointsCounts = DMEvent.getTeamsPoints();
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage(getObjectId());
+
+ npcHtmlMessage.setHtml(htmContent);
+ // npcHtmlMessage.replace("%objectId%", String.valueOf(getObjectId()));
+ npcHtmlMessage.replace("%team1name%", Config.DM_EVENT_TEAM_1_NAME);
+ npcHtmlMessage.replace("%team1playercount%", String.valueOf(teamsPlayerCounts[0]));
+ npcHtmlMessage.replace("%team1points%", String.valueOf(teamsPointsCounts[0]));
+ npcHtmlMessage.replace("%team2name%", Config.DM_EVENT_TEAM_2_NAME);
+ npcHtmlMessage.replace("%team2playercount%", String.valueOf(teamsPlayerCounts[1]));
+ npcHtmlMessage.replace("%team2points%", String.valueOf(teamsPointsCounts[1])); // <---- array index from 0 to 1 thx DaRkRaGe
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+
+ playerInstance.sendPacket(ActionFailed.STATIC_PACKET);
+ }
+}
Index: java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java (revision 6498)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java (working copy)
@@ -200,6 +200,8 @@
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.CTFEvent;
+import com.l2jserver.gameserver.model.entity.DMEvent;
import com.l2jserver.gameserver.model.fishing.L2Fish;
import com.l2jserver.gameserver.model.fishing.L2Fishing;
import com.l2jserver.gameserver.model.holders.ItemHolder;
@@ -5357,6 +5359,8 @@
pk.getEvents().onPvPKill(this);
TvTEvent.onKill(killer, this);
+ CTFEvent.onKill(killer, this);
+ DMEvent.onKill(killer, this);
if (L2Event.isParticipant(pk))
{
@@ -11018,6 +11022,8 @@
}
TvTEvent.onTeleported(this);
+ CTFEvent.onTeleported(this);
+ DMEvent.onTeleported(this);
}
@Override
@@ -11701,6 +11707,26 @@
_log.log(Level.SEVERE, "deleteMe()", e);
}
+ // CTF Event removal
+ try
+ {
+ CTFEvent.onLogout(this);
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.SEVERE, "deleteMe()", e);
+ }
+
+ // 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 6498)
+++ java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCallPc.java (working copy)
@@ -20,6 +20,8 @@
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.CTFEvent;
+import com.l2jserver.gameserver.model.entity.DMEvent;
import com.l2jserver.gameserver.model.stats.Env;
import com.l2jserver.gameserver.model.zone.ZoneId;
import com.l2jserver.gameserver.network.SystemMessageId;
@@ -60,6 +62,16 @@
player.sendPacket(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING);
canCallPlayer = false;
}
+ else if (!CTFEvent.onEscapeUse(player.getObjectId()))
+ {
+ player.sendPacket(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING);
+ canCallPlayer = false;
+ }
+ 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 6498)
+++ java/com/l2jserver/gameserver/model/conditions/ConditionPlayerCanEscape.java (working copy)
@@ -22,6 +22,8 @@
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.CTFEvent;
+import com.l2jserver.gameserver.model.entity.DMEvent;
import com.l2jserver.gameserver.model.stats.Env;
/**
@@ -50,6 +52,14 @@
{
canTeleport = false;
}
+ else if (!CTFEvent.onEscapeUse(player.getObjectId()))
+ {
+ canTeleport = false;
+ }
+ 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,51 @@
+/*
+ * Copyright (C) 2004-2014 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.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.CTFEvent;
+import com.l2jserver.gameserver.model.stats.Env;
+
+/**
+ * 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(Env env)
+ {
+ final L2PcInstance player = env.getPlayer();
+ 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,51 @@
+/*
+ * Copyright (C) 2004-2014 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.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.DMEvent;
+import com.l2jserver.gameserver.model.stats.Env;
+
+/**
+ * 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(Env env)
+ {
+ final L2PcInstance player = env.getPlayer();
+ if ((player == null) || !DMEvent.isStarted())
+ {
+ return !_val;
+ }
+ return (DMEvent.isPlayerParticipant(player.getObjectId()) == _val);
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/CTFEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/CTFEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/CTFEvent.java (working copy)
@@ -0,0 +1,1374 @@
+/*
+ * Copyright (C) 2004-2014 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.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.FastList;
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.datatables.DoorTable;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.NpcData;
+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.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.olympiad.OlympiadManager;
+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.gameserver.scripting.scriptengine.events.CTFKillEvent;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2Script.EventStage;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.CTFListener;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author FBIagent
+ */
+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/html/mods/CTFEvent/";
+ /** 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;
+ /** Instance id<br> */
+ private static int _CTFEventInstance = 0;
+
+ private static FastList<CTFListener> CTFListeners = new FastList<CTFListener>().shared();
+
+ /**
+ * 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()
+ {
+ L2NpcTemplate tmpl = NpcData.getInstance().getTemplate(Config.CTF_EVENT_PARTICIPATION_NPC_ID);
+
+ if (tmpl == null)
+ {
+ _log.warning("CTFEventEngine[CTFEvent.startParticipation()]: L2NpcTemplate is a NullPointer -> Invalid npc id in configs?");
+ return false;
+ }
+
+ try
+ {
+ _npcSpawn = new L2Spawn(tmpl);
+
+ _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);
+ fireCTFEventListeners(EventStage.REGISTRATION_BEGIN);
+ 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);
+ }
+ }
+
+ // 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);
+ // Teleporter implements Runnable and starts itself
+ new CTFEventTeleporter(playerInstance, team.getCoordinates(), false, false);
+ }
+ }
+ }
+ fireCTFEventListeners(EventStage.START);
+
+ 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
+ return "CTF Event: Event has ended. No team won due to inactivity!";
+ }
+
+ // Both teams have equals points
+ 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);
+ fireCTFEventListeners(EventStage.END);
+ 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;
+ }
+
+ 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().createDummyItem(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.htm"));
+ 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);
+
+ // 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);
+ // 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 = DoorTable.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;
+ }
+
+ /**
+ * 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 bypass by npc of type L2CTFEventNpc<br>
+ * Needs synchronization cause of the max player check<br>
+ * <br>
+ * @param command as String<br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static synchronized void onBypass(String command, L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || !isParticipating())
+ {
+ return;
+ }
+
+ final String htmContent;
+
+ if (command.equals("CTF_event_participation"))
+ {
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+ int playerLevel = playerInstance.getLevel();
+
+ if (playerInstance.isCursedWeaponEquipped())
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "CursedWeaponEquipped.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ }
+ }
+ else if (OlympiadManager.getInstance().isRegistered(playerInstance))
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Olympiad.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ }
+ }
+ else if (playerInstance.getKarma() > 0)
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Karma.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ }
+ }
+ else if ((playerLevel < Config.CTF_EVENT_MIN_LVL) || (playerLevel > Config.CTF_EVENT_MAX_LVL))
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Level.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ npcHtmlMessage.replace("%min%", String.valueOf(Config.CTF_EVENT_MIN_LVL));
+ npcHtmlMessage.replace("%max%", String.valueOf(Config.CTF_EVENT_MAX_LVL));
+ }
+ }
+ else if ((_teams[0].getParticipatedPlayerCount() == Config.CTF_EVENT_MAX_PLAYERS_IN_TEAMS) && (_teams[1].getParticipatedPlayerCount() == Config.CTF_EVENT_MAX_PLAYERS_IN_TEAMS))
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "TeamsFull.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ npcHtmlMessage.replace("%max%", String.valueOf(Config.CTF_EVENT_MAX_PLAYERS_IN_TEAMS));
+ }
+ }
+ else if ((Config.CTF_EVENT_MAX_PARTICIPANTS_PER_IP > 0) && !AntiFeedManager.getInstance().tryAddPlayer(AntiFeedManager.CTF_ID, playerInstance, Config.CTF_EVENT_MAX_PARTICIPANTS_PER_IP))
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "IPRestriction.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ npcHtmlMessage.replace("%max%", String.valueOf(AntiFeedManager.getInstance().getLimit(playerInstance, Config.CTF_EVENT_MAX_PARTICIPANTS_PER_IP)));
+ }
+ }
+ else if (needParticipationFee() && !hasParticipationFee(playerInstance))
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "ParticipationFee.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ npcHtmlMessage.replace("%fee%", getParticipationFee());
+ }
+ }
+ else if (addParticipant(playerInstance))
+ {
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Registered.htm"));
+ }
+ else
+ {
+ return;
+ }
+
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ else if (command.equals("CTF_event_remove_participation"))
+ {
+ removeParticipant(playerInstance.getObjectId());
+ if (Config.CTF_EVENT_MAX_PARTICIPANTS_PER_IP > 0)
+ {
+ AntiFeedManager.getInstance().removePlayer(AntiFeedManager.CTF_ID, playerInstance);
+ }
+
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Unregistered.htm"));
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+
+ /**
+ * 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];
+
+ 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);
+ }
+ }
+ fireCTFKillListeners(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.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()
+ };
+ }
+
+ public static int getCTFEventInstance()
+ {
+ return _CTFEventInstance;
+ }
+
+ // Listeners
+ /**
+ * Fires all the CTFListener.onKill() methods, if any
+ * @param killer
+ * @param victim
+ * @param killerTeam
+ */
+ private static void fireCTFKillListeners(L2PcInstance killer, L2PcInstance victim, CTFEventTeam killerTeam)
+ {
+ if (!CTFListeners.isEmpty() && (killer != null) && (victim != null) && (killerTeam != null))
+ {
+ CTFKillEvent event = new CTFKillEvent();
+ event.setKiller(killer);
+ event.setVictim(victim);
+ event.setKillerTeam(killerTeam);
+ for (CTFListener listener : CTFListeners)
+ {
+ listener.onKill(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the appropriate CTFEventListeners, if any
+ * @param stage
+ */
+ private static void fireCTFEventListeners(EventStage stage)
+ {
+ if (!CTFListeners.isEmpty())
+ {
+ switch (stage)
+ {
+ case REGISTRATION_BEGIN:
+ {
+ for (CTFListener listener : CTFListeners)
+ {
+ listener.onRegistrationStart();
+ }
+ break;
+ }
+ case START:
+ {
+ for (CTFListener listener : CTFListeners)
+ {
+ listener.onBegin();
+ }
+ break;
+ }
+ case END:
+ {
+ for (CTFListener listener : CTFListeners)
+ {
+ listener.onEnd();
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds a CTF listener
+ * @param listener
+ */
+ public static void addCTFListener(CTFListener listener)
+ {
+ if (!CTFListeners.contains(listener))
+ {
+ CTFListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a CTF listener
+ * @param listener
+ */
+ public static void removeCTFListener(CTFListener listener)
+ {
+ CTFListeners.remove(listener);
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/CTFEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/CTFEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/CTFEventListener.java (working copy)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2004-2014 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.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.EventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class CTFEventListener extends EventListener
+{
+ protected CTFEventListener(L2PcInstance player)
+ {
+ super(player);
+ }
+
+ @Override
+ public void unregister()
+ {
+ super.unregister();
+ getPlayer().setCanRevive(true);
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return CTFEvent.isStarted() && CTFEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/CTFEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/CTFEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/CTFEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2014 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 FBIagent
+ */
+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/CTFEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/CTFEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/CTFEventTeleporter.java (working copy)
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2004-2014 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 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);
+
+ 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/CTFManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/CTFManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/CTFManager.java (working copy)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2004-2014 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.Announcements;
+import com.l2jserver.gameserver.ThreadPoolManager;
+
+/**
+ * @author FBIagent
+ */
+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)
+ {
+ CTFEvent.init();
+
+ scheduleEventStart();
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Started.");
+ }
+ 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())
+ {
+ Announcements.getInstance().announceToAll("CTF Event: Event was cancelled.");
+ _log.warning("CTFEventEngine[CTFManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Announcements.getInstance().announceToAll("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())
+ {
+ Announcements.getInstance().announceToAll("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()
+ {
+ Announcements.getInstance().announceToAll(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())
+ {
+ Announcements.getInstance().announceToAll("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())
+ {
+ Announcements.getInstance().announceToAll("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())
+ {
+ Announcements.getInstance().announceToAll("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/DMEvent.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/DMEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/DMEvent.java (working copy)
@@ -0,0 +1,1374 @@
+/*
+ * Copyright (C) 2004-2014 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.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.FastList;
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.datatables.DoorTable;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.NpcData;
+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.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.olympiad.OlympiadManager;
+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.gameserver.scripting.scriptengine.events.CTFKillEvent;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2Script.EventStage;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.CTFListener;
+import com.l2jserver.util.Rnd;
+import com.l2jserver.util.StringUtil;
+
+/**
+ * @author FBIagent
+ */
+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/html/mods/CTFEvent/";
+ /** 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;
+ /** Instance id<br> */
+ private static int _CTFEventInstance = 0;
+
+ private static FastList<CTFListener> CTFListeners = new FastList<CTFListener>().shared();
+
+ /**
+ * 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()
+ {
+ L2NpcTemplate tmpl = NpcData.getInstance().getTemplate(Config.CTF_EVENT_PARTICIPATION_NPC_ID);
+
+ if (tmpl == null)
+ {
+ _log.warning("CTFEventEngine[CTFEvent.startParticipation()]: L2NpcTemplate is a NullPointer -> Invalid npc id in configs?");
+ return false;
+ }
+
+ try
+ {
+ _npcSpawn = new L2Spawn(tmpl);
+
+ _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);
+ fireCTFEventListeners(EventStage.REGISTRATION_BEGIN);
+ 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);
+ }
+ }
+
+ // 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);
+ // Teleporter implements Runnable and starts itself
+ new CTFEventTeleporter(playerInstance, team.getCoordinates(), false, false);
+ }
+ }
+ }
+ fireCTFEventListeners(EventStage.START);
+
+ 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
+ return "CTF Event: Event has ended. No team won due to inactivity!";
+ }
+
+ // Both teams have equals points
+ 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);
+ fireCTFEventListeners(EventStage.END);
+ 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;
+ }
+
+ 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().createDummyItem(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.htm"));
+ 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);
+
+ // 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);
+ // 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 = DoorTable.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;
+ }
+
+ /**
+ * 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 bypass by npc of type L2CTFEventNpc<br>
+ * Needs synchronization cause of the max player check<br>
+ * <br>
+ * @param command as String<br>
+ * @param playerInstance as L2PcInstance<br>
+ */
+ public static synchronized void onBypass(String command, L2PcInstance playerInstance)
+ {
+ if ((playerInstance == null) || !isParticipating())
+ {
+ return;
+ }
+
+ final String htmContent;
+
+ if (command.equals("CTF_event_participation"))
+ {
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+ int playerLevel = playerInstance.getLevel();
+
+ if (playerInstance.isCursedWeaponEquipped())
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "CursedWeaponEquipped.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ }
+ }
+ else if (OlympiadManager.getInstance().isRegistered(playerInstance))
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Olympiad.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ }
+ }
+ else if (playerInstance.getKarma() > 0)
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Karma.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ }
+ }
+ else if ((playerLevel < Config.CTF_EVENT_MIN_LVL) || (playerLevel > Config.CTF_EVENT_MAX_LVL))
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Level.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ npcHtmlMessage.replace("%min%", String.valueOf(Config.CTF_EVENT_MIN_LVL));
+ npcHtmlMessage.replace("%max%", String.valueOf(Config.CTF_EVENT_MAX_LVL));
+ }
+ }
+ else if ((_teams[0].getParticipatedPlayerCount() == Config.CTF_EVENT_MAX_PLAYERS_IN_TEAMS) && (_teams[1].getParticipatedPlayerCount() == Config.CTF_EVENT_MAX_PLAYERS_IN_TEAMS))
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "TeamsFull.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ npcHtmlMessage.replace("%max%", String.valueOf(Config.CTF_EVENT_MAX_PLAYERS_IN_TEAMS));
+ }
+ }
+ else if ((Config.CTF_EVENT_MAX_PARTICIPANTS_PER_IP > 0) && !AntiFeedManager.getInstance().tryAddPlayer(AntiFeedManager.CTF_ID, playerInstance, Config.CTF_EVENT_MAX_PARTICIPANTS_PER_IP))
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "IPRestriction.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ npcHtmlMessage.replace("%max%", String.valueOf(AntiFeedManager.getInstance().getLimit(playerInstance, Config.CTF_EVENT_MAX_PARTICIPANTS_PER_IP)));
+ }
+ }
+ else if (needParticipationFee() && !hasParticipationFee(playerInstance))
+ {
+ htmContent = HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "ParticipationFee.htm");
+ if (htmContent != null)
+ {
+ npcHtmlMessage.setHtml(htmContent);
+ npcHtmlMessage.replace("%fee%", getParticipationFee());
+ }
+ }
+ else if (addParticipant(playerInstance))
+ {
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Registered.htm"));
+ }
+ else
+ {
+ return;
+ }
+
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ else if (command.equals("CTF_event_remove_participation"))
+ {
+ removeParticipant(playerInstance.getObjectId());
+ if (Config.CTF_EVENT_MAX_PARTICIPANTS_PER_IP > 0)
+ {
+ AntiFeedManager.getInstance().removePlayer(AntiFeedManager.CTF_ID, playerInstance);
+ }
+
+ final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
+
+ npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Unregistered.htm"));
+ playerInstance.sendPacket(npcHtmlMessage);
+ }
+ }
+
+ /**
+ * 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];
+
+ 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);
+ }
+ }
+ fireCTFKillListeners(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.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()
+ };
+ }
+
+ public static int getCTFEventInstance()
+ {
+ return _CTFEventInstance;
+ }
+
+ // Listeners
+ /**
+ * Fires all the CTFListener.onKill() methods, if any
+ * @param killer
+ * @param victim
+ * @param killerTeam
+ */
+ private static void fireCTFKillListeners(L2PcInstance killer, L2PcInstance victim, CTFEventTeam killerTeam)
+ {
+ if (!CTFListeners.isEmpty() && (killer != null) && (victim != null) && (killerTeam != null))
+ {
+ CTFKillEvent event = new CTFKillEvent();
+ event.setKiller(killer);
+ event.setVictim(victim);
+ event.setKillerTeam(killerTeam);
+ for (CTFListener listener : CTFListeners)
+ {
+ listener.onKill(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the appropriate CTFEventListeners, if any
+ * @param stage
+ */
+ private static void fireCTFEventListeners(EventStage stage)
+ {
+ if (!CTFListeners.isEmpty())
+ {
+ switch (stage)
+ {
+ case REGISTRATION_BEGIN:
+ {
+ for (CTFListener listener : CTFListeners)
+ {
+ listener.onRegistrationStart();
+ }
+ break;
+ }
+ case START:
+ {
+ for (CTFListener listener : CTFListeners)
+ {
+ listener.onBegin();
+ }
+ break;
+ }
+ case END:
+ {
+ for (CTFListener listener : CTFListeners)
+ {
+ listener.onEnd();
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds a CTF listener
+ * @param listener
+ */
+ public static void addCTFListener(CTFListener listener)
+ {
+ if (!CTFListeners.contains(listener))
+ {
+ CTFListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a CTF listener
+ * @param listener
+ */
+ public static void removeCTFListener(CTFListener listener)
+ {
+ CTFListeners.remove(listener);
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/DMEventListener.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/DMEventListener.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/DMEventListener.java (working copy)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2004-2014 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.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.EventListener;
+
+/**
+ * @author UnAfraid
+ */
+public final class CTFEventListener extends EventListener
+{
+ protected CTFEventListener(L2PcInstance player)
+ {
+ super(player);
+ }
+
+ @Override
+ public void unregister()
+ {
+ super.unregister();
+ getPlayer().setCanRevive(true);
+ }
+
+ @Override
+ public boolean isOnEvent()
+ {
+ return CTFEvent.isStarted() && CTFEvent.isPlayerParticipant(getPlayer().getObjectId());
+ }
+
+ @Override
+ public boolean isBlockingExit()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isBlockingDeathPenalty()
+ {
+ return true;
+ }
+}
Index: java/com/l2jserver/gameserver/model/entity/DMEventTeam.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/DMEventTeam.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/DMEventTeam.java (working copy)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2014 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 FBIagent
+ */
+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/DMEventTeleporter.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/DMEventTeleporter.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/DMEventTeleporter.java (working copy)
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2004-2014 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 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);
+
+ 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/DMManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/DMManager.java (revision 0)
+++ java/com/l2jserver/gameserver/model/entity/DMManager.java (working copy)
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2004-2014 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.Announcements;
+import com.l2jserver.gameserver.ThreadPoolManager;
+
+/**
+ * @author FBIagent
+ */
+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)
+ {
+ CTFEvent.init();
+
+ scheduleEventStart();
+ _log.info("CTFEventEngine[CTFManager.CTFManager()]: Started.");
+ }
+ 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())
+ {
+ Announcements.getInstance().announceToAll("CTF Event: Event was cancelled.");
+ _log.warning("CTFEventEngine[CTFManager.run()]: Error spawning event npc for participation.");
+
+ scheduleEventStart();
+ }
+ else
+ {
+ Announcements.getInstance().announceToAll("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())
+ {
+ Announcements.getInstance().announceToAll("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()
+ {
+ Announcements.getInstance().announceToAll(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())
+ {
+ Announcements.getInstance().announceToAll("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())
+ {
+ Announcements.getInstance().announceToAll("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())
+ {
+ Announcements.getInstance().announceToAll("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/L2Event.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/L2Event.java (revision 6498)
+++ java/com/l2jserver/gameserver/model/entity/L2Event.java (working copy)
@@ -531,6 +531,8 @@
eventState = EventState.OFF;
AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.CTF_ID);
+ AntiFeedManager.getInstance().clear(AntiFeedManager.DM_ID);
unspawnEventNpcs(); // Just in case
// _npcs.clear();
_registeredPlayers.clear();
Index: java/com/l2jserver/gameserver/model/olympiad/AbstractOlympiadGame.java
===================================================================
--- java/com/l2jserver/gameserver/model/olympiad/AbstractOlympiadGame.java (revision 6498)
+++ java/com/l2jserver/gameserver/model/olympiad/AbstractOlympiadGame.java (working copy)
@@ -36,6 +36,8 @@
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.CTFEvent;
+import com.l2jserver.gameserver.model.entity.DMEvent;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.model.skills.Skill;
@@ -142,7 +144,7 @@
}
// safety precautions
- if (player.inObserverMode() || TvTEvent.isPlayerParticipant(player.getObjectId()))
+ if (player.inObserverMode() || TvTEvent.isPlayerParticipant(player.getObjectId()) || CTFEvent.isPlayerParticipant(player.getObjectId()) || DMEvent.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 6498)
+++ 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 other event.");
return false;
}
Index: java/com/l2jserver/gameserver/model/skills/Skill.java
===================================================================
--- java/com/l2jserver/gameserver/model/skills/Skill.java (revision 6498)
+++ java/com/l2jserver/gameserver/model/skills/Skill.java (working copy)
@@ -55,6 +55,8 @@
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.CTFEvent;
+import com.l2jserver.gameserver.model.entity.DMEvent;
import com.l2jserver.gameserver.model.holders.ItemHolder;
import com.l2jserver.gameserver.model.interfaces.IChanceSkillTrigger;
import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
@@ -1160,6 +1162,16 @@
return false;
}
+ if (!CTFEvent.checkForCTFSkill(player, targetPlayer, skill))
+ {
+ return false;
+ }
+
+ 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 6498)
+++ java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java (working copy)
@@ -54,6 +54,8 @@
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.CTFEvent;
+import com.l2jserver.gameserver.model.entity.DMEvent;
import com.l2jserver.gameserver.model.entity.clanhall.AuctionableHall;
import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
@@ -571,6 +573,8 @@
CommunityServerThread.getInstance().sendPacket(new WorldInfo(activeChar, null, WorldInfo.TYPE_UPDATE_PLAYER_STATUS));
TvTEvent.onLogin(activeChar);
+ CTFEvent.onLogin(activeChar);
+ DMEvent.onLogin(activeChar);
if (Config.WELCOME_MESSAGE_ENABLED)
{
Index: java/com/l2jserver/gameserver/scripting/scriptengine/events/CTFKillEvent.java
===================================================================
--- java/com/l2jserver/gameserver/scripting/scriptengine/events/CTFKillEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/scripting/scriptengine/events/CTFKillEvent.java (working copy)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2004-2014 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.scripting.scriptengine.events;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.CTFEventTeam;
+import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
+
+/**
+ * @author TheOne
+ */
+public class CTFKillEvent implements L2Event
+{
+ private L2PcInstance killer;
+ private L2PcInstance victim;
+ private CTFEventTeam killerTeam;
+
+ /**
+ * @return the killer
+ */
+ public L2PcInstance getKiller()
+ {
+ return killer;
+ }
+
+ /**
+ * @param killer the killer to set
+ */
+ public void setKiller(L2PcInstance killer)
+ {
+ this.killer = killer;
+ }
+
+ /**
+ * @return the victim
+ */
+ public L2PcInstance getVictim()
+ {
+ return victim;
+ }
+
+ /**
+ * @param victim the victim to set
+ */
+ public void setVictim(L2PcInstance victim)
+ {
+ this.victim = victim;
+ }
+
+ /**
+ * @return the killerTeam
+ */
+ public CTFEventTeam getKillerTeam()
+ {
+ return killerTeam;
+ }
+
+ /**
+ * @param killerTeam the killerTeam to set
+ */
+ public void setKillerTeam(CTFEventTeam killerTeam)
+ {
+ this.killerTeam = killerTeam;
+ }
+}
Index: java/com/l2jserver/gameserver/scripting/scriptengine/events/DMKillEvent.java
===================================================================
--- java/com/l2jserver/gameserver/scripting/scriptengine/events/DMKillEvent.java (revision 0)
+++ java/com/l2jserver/gameserver/scripting/scriptengine/events/DMKillEvent.java (working copy)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2004-2014 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.scripting.scriptengine.events;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.DMEventTeam;
+import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
+
+/**
+ * @author TheOne
+ */
+public class DMKillEvent implements L2Event
+{
+ private L2PcInstance killer;
+ private L2PcInstance victim;
+ private DMEventTeam killerTeam;
+
+ /**
+ * @return the killer
+ */
+ public L2PcInstance getKiller()
+ {
+ return killer;
+ }
+
+ /**
+ * @param killer the killer to set
+ */
+ public void setKiller(L2PcInstance killer)
+ {
+ this.killer = killer;
+ }
+
+ /**
+ * @return the victim
+ */
+ public L2PcInstance getVictim()
+ {
+ return victim;
+ }
+
+ /**
+ * @param victim the victim to set
+ */
+ public void setVictim(L2PcInstance victim)
+ {
+ this.victim = victim;
+ }
+
+ /**
+ * @return the killerTeam
+ */
+ public DMEventTeam getKillerTeam()
+ {
+ return killerTeam;
+ }
+
+ /**
+ * @param killerTeam the killerTeam to set
+ */
+ public void setKillerTeam(DMEventTeam killerTeam)
+ {
+ this.killerTeam = killerTeam;
+ }
+}
Index: java/com/l2jserver/gameserver/scripting/scriptengine/impl/L2Script.java
===================================================================
--- java/com/l2jserver/gameserver/scripting/scriptengine/impl/L2Script.java (revision 6498)
+++ java/com/l2jserver/gameserver/scripting/scriptengine/impl/L2Script.java (working copy)
@@ -59,6 +59,8 @@
import com.l2jserver.gameserver.scripting.scriptengine.events.SkillUseEvent;
import com.l2jserver.gameserver.scripting.scriptengine.events.TransformEvent;
import com.l2jserver.gameserver.scripting.scriptengine.events.TvtKillEvent;
+import com.l2jserver.gameserver.scripting.scriptengine.events.CTFKillEvent;
+import com.l2jserver.gameserver.scripting.scriptengine.events.DMKillEvent;
import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
import com.l2jserver.gameserver.scripting.scriptengine.listeners.character.AttackListener;
import com.l2jserver.gameserver.scripting.scriptengine.listeners.character.DeathListener;
@@ -70,6 +72,8 @@
import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.FortSiegeListener;
import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.SiegeListener;
import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.TvTListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.CTFListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.DMListener;
import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.AugmentListener;
import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.DropListener;
import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.EquipmentListener;
@@ -629,6 +633,116 @@
}
/**
+ * Notifies of events on CTF:<br>
+ * start<br>
+ * end<br>
+ * registion begin<br>
+ * event stopped<br>
+ * player killed<br>
+ */
+ public void addCTFNotify()
+ {
+ CTFListener listener = new CTFListener()
+ {
+ @Override
+ public void onBegin()
+ {
+ onCTFEvent(EventStage.START);
+ }
+
+ @Override
+ public void onKill(CTFKillEvent event)
+ {
+ onCTFKill(event);
+ }
+
+ @Override
+ public void onEnd()
+ {
+ onCTFEvent(EventStage.END);
+ }
+
+ @Override
+ public void onRegistrationStart()
+ {
+ onCTFEvent(EventStage.REGISTRATION_BEGIN);
+ }
+ };
+ _listeners.add(listener);
+ }
+
+ /**
+ * Removes the CTF notifications
+ */
+ public void removeCTFNotify()
+ {
+ List<L2JListener> removeList = new ArrayList<>();
+ for (L2JListener listener : _listeners)
+ {
+ if (listener instanceof CTFListener)
+ {
+ removeList.add(listener);
+ }
+ }
+ removeListeners(removeList);
+ }
+
+ /**
+ * Notifies of events on DM:<br>
+ * start<br>
+ * end<br>
+ * registion begin<br>
+ * event stopped<br>
+ * player killed<br>
+ */
+ public void addDMNotify()
+ {
+ DMListener listener = new DMListener()
+ {
+ @Override
+ public void onBegin()
+ {
+ onDMEvent(EventStage.START);
+ }
+
+ @Override
+ public void onKill(DMKillEvent event)
+ {
+ onDMKill(event);
+ }
+
+ @Override
+ public void onEnd()
+ {
+ onDMEvent(EventStage.END);
+ }
+
+ @Override
+ public void onRegistrationStart()
+ {
+ onDMEvent(EventStage.REGISTRATION_BEGIN);
+ }
+ };
+ _listeners.add(listener);
+ }
+
+ /**
+ * Removes the DM notifications
+ */
+ public void removeDMNotify()
+ {
+ List<L2JListener> removeList = new ArrayList<>();
+ for (L2JListener listener : _listeners)
+ {
+ if (listener instanceof DMListener)
+ {
+ removeList.add(listener);
+ }
+ }
+ removeListeners(removeList);
+ }
+
+ /**
* Adds a notifier for when items get augmented
*/
public void addItemAugmentNotify()
@@ -1385,7 +1499,7 @@
*/
public void onTvtEvent(EventStage stage)
{
-
+ // Empty
}
/**
@@ -1395,10 +1509,50 @@
*/
public void onTvtKill(TvtKillEvent event)
{
-
+ // Empty
}
/**
+ * Notifies of CTF events<br>
+ * Register using addCTFNotify()
+ * @param stage
+ */
+ public void onCTFEvent(EventStage stage)
+ {
+ // Empty
+ }
+
+ /**
+ * Notifies that a player was killed during CTF<br>
+ * Register using addCTFNotify()
+ * @param event
+ */
+ public void onCTFKill(CTFKillEvent event)
+ {
+ // Empty
+ }
+
+ /**
+ * Notifies of DM events<br>
+ * Register using addDMNotify()
+ * @param stage
+ */
+ public void onDMEvent(EventStage stage)
+ {
+ // Empty
+ }
+
+ /**
+ * Notifies that a player was killed during DM<br>
+ * Register using addDMNotify()
+ * @param event
+ */
+ public void onDMKill(DMKillEvent event)
+ {
+ // Empty
+ }
+
+ /**
* triggered when an item is augmented or when the augmentation is removed<br>
* Register using addItemAugmentNotify()
* @param event
Index: java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/CTFListener.java
===================================================================
--- java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/CTFListener.java (revision 0)
+++ java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/CTFListener.java (working copy)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004-2014 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.scripting.scriptengine.listeners.events;
+
+import com.l2jserver.gameserver.model.entity.CTFEvent;
+import com.l2jserver.gameserver.scripting.scriptengine.events.CTFKillEvent;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Notifies when a CTF event starts
+ * @author TheOne
+ */
+public abstract class CTFListener extends L2JListener
+{
+ public CTFListener()
+ {
+ register();
+ }
+
+ /**
+ * Fired when a CTF event starts
+ */
+ public abstract void onBegin();
+
+ /**
+ * A player has been killed
+ * @param event
+ */
+ public abstract void onKill(CTFKillEvent event);
+
+ /**
+ * Fired when a CTF event ends
+ */
+ public abstract void onEnd();
+
+ /**
+ * Fired when CTF registration starts
+ */
+ public abstract void onRegistrationStart();
+
+ @Override
+ public void register()
+ {
+ CTFEvent.addCTFListener(this);
+ }
+
+ @Override
+ public void unregister()
+ {
+ CTFEvent.removeCTFListener(this);
+ }
+}
Index: java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/DMListener.java
===================================================================
--- java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/DMListener.java (revision 0)
+++ java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/DMListener.java (working copy)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004-2014 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.scripting.scriptengine.listeners.events;
+
+import com.l2jserver.gameserver.model.entity.DMEvent;
+import com.l2jserver.gameserver.scripting.scriptengine.events.DMKillEvent;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Notifies when a DM event starts
+ * @author TheOne
+ */
+public abstract class DMListener extends L2JListener
+{
+ public DMListener()
+ {
+ register();
+ }
+
+ /**
+ * Fired when a DM event starts
+ */
+ public abstract void onBegin();
+
+ /**
+ * A player has been killed
+ * @param event
+ */
+ public abstract void onKill(DMKillEvent event);
+
+ /**
+ * Fired when a DM event ends
+ */
+ public abstract void onEnd();
+
+ /**
+ * Fired when DM registration starts
+ */
+ public abstract void onRegistrationStart();
+
+ @Override
+ public void register()
+ {
+ DMEvent.addDMListener(this);
+ }
+
+ @Override
+ public void unregister()
+ {
+ DMEvent.removeDMListener(this);
+ }
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment