From 2747c3fa29f18d8e6beebebd1e5a2fe9894ad07f Mon Sep 17 00:00:00 2001 From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com> Date: Mon, 11 Dec 2017 06:15:57 +0000 Subject: [PATCH] Addition of Team vs Team event. --- .../game/data/instances/custom/coliseum.xml | 22 +- .../scripts/custom/events/TeamVsTeam/TvT.java | 871 +++++++++++++++++ .../events/TeamVsTeam/manager-buffheal.html | 36 + .../events/TeamVsTeam/manager-cancel.html | 36 + .../events/TeamVsTeam/manager-combat.html | 33 + .../events/TeamVsTeam/manager-register.html | 36 + .../TeamVsTeam/registration-canceled.html | 33 + .../TeamVsTeam/registration-failed.html | 33 + .../TeamVsTeam/registration-success.html | 33 + .../admincommandhandlers/AdminZone.java | 30 +- .../game/data/stats/npcs/custom/custom.xml | 18 - .../game/data/stats/npcs/custom/tvt_event.xml | 22 + .../model/actor/instance/L2PcInstance.java | 30 +- .../conditions/ConditionPlayerCanEscape.java | 4 + .../ConditionPlayerCanTransform.java | 5 + .../model/instancezone/Instance.java | 25 +- .../model/instancezone/InstanceTemplate.java | 1 + .../gameserver/network/ExIncomingPackets.java | 4 +- .../clientpackets/RequestRestartPoint.java | 16 + .../RequestStartShowKrateisCubeRank.java | 39 + .../RequestStopShowKrateisCubeRank.java | 39 + .../serverpackets/ExPVPMatchCCMyRecord.java | 41 + .../serverpackets/ExPVPMatchCCRecord.java | 57 ++ .../com/l2jmobius/gameserver/util/Util.java | 13 + .../gameserver/util/ValueComparator.java | 46 + .../game/data/instances/custom/coliseum.xml | 22 +- .../scripts/custom/events/TeamVsTeam/TvT.java | 871 +++++++++++++++++ .../events/TeamVsTeam/manager-buffheal.html | 36 + .../events/TeamVsTeam/manager-cancel.html | 36 + .../events/TeamVsTeam/manager-combat.html | 33 + .../events/TeamVsTeam/manager-register.html | 36 + .../TeamVsTeam/registration-canceled.html | 33 + .../TeamVsTeam/registration-failed.html | 33 + .../TeamVsTeam/registration-success.html | 33 + .../admincommandhandlers/AdminZone.java | 30 +- .../game/data/stats/npcs/custom/custom.xml | 18 - .../game/data/stats/npcs/custom/tvt_event.xml | 22 + .../model/actor/instance/L2PcInstance.java | 30 +- .../conditions/ConditionPlayerCanEscape.java | 4 + .../ConditionPlayerCanTransform.java | 5 + .../model/instancezone/Instance.java | 25 +- .../model/instancezone/InstanceTemplate.java | 1 + .../gameserver/network/ExIncomingPackets.java | 4 +- .../clientpackets/RequestRestartPoint.java | 16 + .../RequestStartShowKrateisCubeRank.java | 39 + .../RequestStopShowKrateisCubeRank.java | 39 + .../serverpackets/ExPVPMatchCCMyRecord.java | 41 + .../serverpackets/ExPVPMatchCCRecord.java | 57 ++ .../com/l2jmobius/gameserver/util/Util.java | 13 + .../gameserver/util/ValueComparator.java | 46 + .../game/data/instances/custom/coliseum.xml | 22 +- .../scripts/custom/events/TeamVsTeam/TvT.java | 871 +++++++++++++++++ .../events/TeamVsTeam/manager-buffheal.html | 36 + .../events/TeamVsTeam/manager-cancel.html | 36 + .../events/TeamVsTeam/manager-combat.html | 33 + .../events/TeamVsTeam/manager-register.html | 36 + .../TeamVsTeam/registration-canceled.html | 33 + .../TeamVsTeam/registration-failed.html | 33 + .../TeamVsTeam/registration-success.html | 33 + .../admincommandhandlers/AdminZone.java | 30 +- .../game/data/stats/npcs/custom/custom.xml | 18 - .../game/data/stats/npcs/custom/tvt_event.xml | 22 + .../model/actor/instance/L2PcInstance.java | 30 +- .../conditions/ConditionPlayerCanEscape.java | 4 + .../ConditionPlayerCanTransform.java | 5 + .../model/instancezone/Instance.java | 25 +- .../model/instancezone/InstanceTemplate.java | 1 + .../gameserver/network/ExIncomingPackets.java | 4 +- .../clientpackets/RequestRestartPoint.java | 16 + .../RequestStartShowKrateisCubeRank.java | 39 + .../RequestStopShowKrateisCubeRank.java | 39 + .../serverpackets/ExPVPMatchCCMyRecord.java | 41 + .../serverpackets/ExPVPMatchCCRecord.java | 57 ++ .../com/l2jmobius/gameserver/util/Util.java | 13 + .../gameserver/util/ValueComparator.java | 46 + .../game/data/instances/custom/coliseum.xml | 22 +- .../scripts/custom/events/TeamVsTeam/TvT.java | 871 +++++++++++++++++ .../events/TeamVsTeam/manager-buffheal.html | 36 + .../events/TeamVsTeam/manager-cancel.html | 36 + .../events/TeamVsTeam/manager-combat.html | 33 + .../events/TeamVsTeam/manager-register.html | 36 + .../TeamVsTeam/registration-canceled.html | 33 + .../TeamVsTeam/registration-failed.html | 33 + .../TeamVsTeam/registration-success.html | 33 + .../admincommandhandlers/AdminZone.java | 30 +- .../game/data/stats/npcs/custom/custom.xml | 18 - .../game/data/stats/npcs/custom/tvt_event.xml | 22 + .../model/actor/instance/L2PcInstance.java | 30 +- .../conditions/ConditionPlayerCanEscape.java | 4 + .../ConditionPlayerCanTransform.java | 5 + .../model/instancezone/Instance.java | 25 +- .../model/instancezone/InstanceTemplate.java | 1 + .../gameserver/network/ExIncomingPackets.java | 4 +- .../clientpackets/RequestRestartPoint.java | 16 + .../RequestStartShowKrateisCubeRank.java | 39 + .../RequestStopShowKrateisCubeRank.java | 39 + .../serverpackets/ExPVPMatchCCMyRecord.java | 41 + .../serverpackets/ExPVPMatchCCRecord.java | 57 ++ .../com/l2jmobius/gameserver/util/Util.java | 13 + .../gameserver/util/ValueComparator.java | 46 + .../game/data/instances/custom/coliseum.xml | 22 +- .../scripts/custom/events/TeamVsTeam/TvT.java | 873 ++++++++++++++++++ .../events/TeamVsTeam/manager-buffheal.html | 36 + .../events/TeamVsTeam/manager-cancel.html | 36 + .../events/TeamVsTeam/manager-combat.html | 33 + .../events/TeamVsTeam/manager-register.html | 36 + .../TeamVsTeam/registration-canceled.html | 33 + .../TeamVsTeam/registration-failed.html | 33 + .../TeamVsTeam/registration-success.html | 33 + .../admincommandhandlers/AdminZone.java | 30 +- .../game/data/stats/npcs/custom/custom.xml | 18 - .../game/data/stats/npcs/custom/tvt_event.xml | 22 + .../model/actor/instance/L2PcInstance.java | 30 +- .../conditions/ConditionPlayerCanEscape.java | 4 + .../ConditionPlayerCanTransform.java | 5 + .../model/instancezone/Instance.java | 25 +- .../model/instancezone/InstanceTemplate.java | 1 + .../gameserver/network/ExIncomingPackets.java | 4 +- .../clientpackets/RequestRestartPoint.java | 16 + .../RequestStartShowKrateisCubeRank.java | 39 + .../RequestStopShowKrateisCubeRank.java | 39 + .../serverpackets/ExPVPMatchCCMyRecord.java | 41 + .../serverpackets/ExPVPMatchCCRecord.java | 57 ++ .../com/l2jmobius/gameserver/util/Util.java | 13 + .../gameserver/util/ValueComparator.java | 46 + 125 files changed, 7372 insertions(+), 245 deletions(-) create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/tvt_event.xml create mode 100644 L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java create mode 100644 L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java create mode 100644 L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java create mode 100644 L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java create mode 100644 L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/util/ValueComparator.java create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/tvt_event.xml create mode 100644 L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java create mode 100644 L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java create mode 100644 L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java create mode 100644 L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java create mode 100644 L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/util/ValueComparator.java create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/stats/npcs/custom/tvt_event.xml create mode 100644 L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java create mode 100644 L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java create mode 100644 L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java create mode 100644 L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java create mode 100644 L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/util/ValueComparator.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/npcs/custom/tvt_event.xml create mode 100644 L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/util/ValueComparator.java create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/custom/tvt_event.xml create mode 100644 L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java create mode 100644 L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java create mode 100644 L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java create mode 100644 L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java create mode 100644 L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/util/ValueComparator.java diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/instances/custom/coliseum.xml b/L2J_Mobius_1.0_Ertheia/dist/game/data/instances/custom/coliseum.xml index 6c8eb9385c..27a7498e9b 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/instances/custom/coliseum.xml +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/instances/custom/coliseum.xml @@ -1,9 +1,23 @@ + diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java new file mode 100644 index 0000000000..f31b220207 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java @@ -0,0 +1,871 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package custom.events.TeamVsTeam; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.l2jmobius.gameserver.enums.CategoryType; +import com.l2jmobius.gameserver.enums.PartyDistributionType; +import com.l2jmobius.gameserver.enums.Team; +import com.l2jmobius.gameserver.instancemanager.InstanceManager; +import com.l2jmobius.gameserver.instancemanager.ZoneManager; +import com.l2jmobius.gameserver.model.L2CommandChannel; +import com.l2jmobius.gameserver.model.L2Party; +import com.l2jmobius.gameserver.model.Location; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.L2Npc; +import com.l2jmobius.gameserver.model.actor.L2Summon; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.events.EventType; +import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent; +import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDeath; +import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout; +import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; +import com.l2jmobius.gameserver.model.events.listeners.ConsumerEventListener; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.SkillHolder; +import com.l2jmobius.gameserver.model.instancezone.Instance; +import com.l2jmobius.gameserver.model.instancezone.InstanceTemplate; +import com.l2jmobius.gameserver.model.olympiad.OlympiadManager; +import com.l2jmobius.gameserver.model.quest.Event; +import com.l2jmobius.gameserver.model.quest.QuestTimer; +import com.l2jmobius.gameserver.model.skills.CommonSkill; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.skills.SkillCaster; +import com.l2jmobius.gameserver.model.zone.L2ZoneType; +import com.l2jmobius.gameserver.model.zone.ZoneId; +import com.l2jmobius.gameserver.network.serverpackets.ExPVPMatchCCRecord; +import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; +import com.l2jmobius.gameserver.util.Broadcast; +import com.l2jmobius.gameserver.util.Util; + +/** + * Team vs Team event. + * @author Mobius + */ +public class TvT extends Event +{ + // NPC + private static final int MANAGER = 70010; + // Skills + private static final SkillHolder KNIGHT = new SkillHolder(15648, 1); // Knight's Harmony (Adventurer) + private static final SkillHolder WARRIOR = new SkillHolder(15649, 1); // Warrior's Harmony (Adventurer) + private static final SkillHolder WIZARD = new SkillHolder(15650, 1); // Wizard's Harmony (Adventurer) + private static final SkillHolder[] GROUP_BUFFS = + { + new SkillHolder(15642, 1), // Horn Melody (Adventurer) + new SkillHolder(15643, 1), // Drum Melody (Adventurer) + new SkillHolder(15644, 1), // Pipe Organ Melody (Adventurer) + new SkillHolder(15645, 1), // Guitar Melody (Adventurer) + new SkillHolder(15646, 1), // Harp Melody (Adventurer) + new SkillHolder(15647, 1), // Lute Melody (Adventurer) + new SkillHolder(15651, 1), // Prevailing Sonata (Adventurer) + new SkillHolder(15652, 1), // Daring Sonata (Adventurer) + new SkillHolder(15653, 1), // Refreshing Sonata (Adventurer) + }; + // Others + private static final int INSTANCE_ID = 3049; + private static final int BLUE_DOOR_ID = 24190002; + private static final int RED_DOOR_ID = 24190003; + private static final Location MANAGER_SPAWN_LOC = new Location(83425, 148585, -3406, 32938); + private static final Location BLUE_BUFFER_SPAWN_LOC = new Location(147450, 46913, -3400, 49000); + private static final Location RED_BUFFER_SPAWN_LOC = new Location(151545, 46528, -3400, 16000); + private static final Location BLUE_SPAWN_LOC = new Location(147447, 46722, -3416); + private static final Location RED_SPAWN_LOC = new Location(151536, 46722, -3416); + private static final L2ZoneType BLUE_PEACE_ZONE = ZoneManager.getInstance().getZoneByName("colosseum_peace1"); + private static final L2ZoneType RED_PEACE_ZONE = ZoneManager.getInstance().getZoneByName("colosseum_peace2"); + // Settings + private static final int REGISTRATION_TIME = 10; // Minutes + private static final int WAIT_TIME = 1; // Minutes + private static final int FIGHT_TIME = 20; // Minutes + private static final int INACTIVITY_TIME = 2; // Minutes + private static final int MINIMUM_PARTICIPANT_LEVEL = 85; + private static final int MAXIMUM_PARTICIPANT_LEVEL = 200; + private static final int MINIMUM_PARTICIPANT_COUNT = 4; + private static final int MAXIMUM_PARTICIPANT_COUNT = 24; // Scoreboard has 25 slots + private static final int PARTY_MEMBER_COUNT = 7; + private static final ItemHolder REWARD = new ItemHolder(57, 1000000); // Adena + // Misc + private static final Map PLAYER_SCORES = new ConcurrentHashMap<>(); + private static final List PLAYER_LIST = new ArrayList<>(); + private static final List BLUE_TEAM = new ArrayList<>(); + private static final List RED_TEAM = new ArrayList<>(); + private static volatile int BLUE_SCORE; + private static volatile int RED_SCORE; + private static Instance PVP_WORLD = null; + private static L2Npc MANAGER_NPC_INSTANCE = null; + private static boolean EVENT_ACTIVE = false; + + private TvT() + { + addTalkId(MANAGER); + addFirstTalkId(MANAGER); + addExitZoneId(BLUE_PEACE_ZONE.getId(), RED_PEACE_ZONE.getId()); + addEnterZoneId(BLUE_PEACE_ZONE.getId(), RED_PEACE_ZONE.getId()); + } + + @Override + public String onAdvEvent(String event, L2Npc npc, L2PcInstance player) + { + if (!EVENT_ACTIVE) + { + return null; + } + + String htmltext = null; + switch (event) + { + case "Participate": + { + if (canRegister(player)) + { + PLAYER_LIST.add(player); + PLAYER_SCORES.put(player, 0); + player.setOnCustomEvent(true); + addLogoutListener(player); + htmltext = "registration-success.html"; + } + else + { + htmltext = "registration-failed.html"; + } + break; + } + case "CancelParticipation": + { + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + removeListeners(player); + player.setOnCustomEvent(false); + htmltext = "registration-canceled.html"; + break; + } + case "BuffHeal": + { + if (player.isOnCustomEvent() || player.isGM()) + { + if (player.isInCombat()) + { + htmltext = "manager-combat.html"; + } + else + { + for (SkillHolder holder : GROUP_BUFFS) + { + SkillCaster.triggerCast(npc, player, holder.getSkill()); + } + if (player.isMageClass()) + { + SkillCaster.triggerCast(npc, player, WIZARD.getSkill()); + } + else if (player.isInCategory(CategoryType.KNIGHT_GROUP)) + { + SkillCaster.triggerCast(npc, player, KNIGHT.getSkill()); + } + else + { + SkillCaster.triggerCast(npc, player, WARRIOR.getSkill()); + } + player.setCurrentHp(player.getMaxHp()); + player.setCurrentMp(player.getMaxMp()); + player.setCurrentCp(player.getMaxCp()); + } + } + break; + } + case "TeleportToArena": + { + // Remove offline players. + for (L2PcInstance participant : PLAYER_LIST) + { + if ((participant == null) || (participant.isOnlineInt() != 1)) + { + PLAYER_LIST.remove(participant); + PLAYER_SCORES.remove(participant); + } + } + // Check if there are enough players to start the event. + if (PLAYER_LIST.size() < MINIMUM_PARTICIPANT_COUNT) + { + Broadcast.toAllOnlinePlayers("TvT Event: Event was canceled, not enough participants."); + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setOnCustomEvent(false); + } + EVENT_ACTIVE = false; + return null; + } + // Create the instance. + final InstanceManager manager = InstanceManager.getInstance(); + final InstanceTemplate template = manager.getInstanceTemplate(INSTANCE_ID); + PVP_WORLD = manager.createInstance(template, null); + // Randomize player list and separate teams. + Collections.shuffle(PLAYER_LIST); + boolean team = getRandomBoolean(); // If teams are not even, randomize where extra player goes. + for (L2PcInstance participant : PLAYER_LIST) + { + if (team) + { + BLUE_TEAM.add(participant); + PVP_WORLD.addAllowed(participant); + participant.leaveParty(); + participant.setTeam(Team.BLUE); + participant.teleToLocation(BLUE_SPAWN_LOC, PVP_WORLD); + team = false; + } + else + { + RED_TEAM.add(participant); + PVP_WORLD.addAllowed(participant); + participant.leaveParty(); + participant.setTeam(Team.RED); + participant.teleToLocation(RED_SPAWN_LOC, PVP_WORLD); + team = true; + } + addDeathListener(participant); + } + // Make Blue CC. + if (BLUE_TEAM.size() > 1) + { + L2CommandChannel blueCC = null; + L2Party lastBlueParty = null; + int blueParticipantCounter = 0; + for (L2PcInstance participant : BLUE_TEAM) + { + blueParticipantCounter++; + if (blueParticipantCounter == 1) + { + lastBlueParty = new L2Party(participant, PartyDistributionType.FINDERS_KEEPERS); + participant.joinParty(lastBlueParty); + if (BLUE_TEAM.size() > PARTY_MEMBER_COUNT) + { + if (blueCC == null) + { + blueCC = new L2CommandChannel(participant); + } + else + { + blueCC.addParty(lastBlueParty); + } + } + } + else if (lastBlueParty != null) + { + participant.joinParty(lastBlueParty); + } + if (blueParticipantCounter == PARTY_MEMBER_COUNT) + { + blueParticipantCounter = 0; + } + } + } + // Make Red CC. + if (RED_TEAM.size() > 1) + { + L2CommandChannel redCC = null; + L2Party lastRedParty = null; + int redParticipantCounter = 0; + for (L2PcInstance participant : RED_TEAM) + { + redParticipantCounter++; + if (redParticipantCounter == 1) + { + lastRedParty = new L2Party(participant, PartyDistributionType.FINDERS_KEEPERS); + participant.joinParty(lastRedParty); + if (RED_TEAM.size() > PARTY_MEMBER_COUNT) + { + if (redCC == null) + { + redCC = new L2CommandChannel(participant); + } + else + { + redCC.addParty(lastRedParty); + } + } + } + else if (lastRedParty != null) + { + participant.joinParty(lastRedParty); + } + if (redParticipantCounter == PARTY_MEMBER_COUNT) + { + redParticipantCounter = 0; + } + } + } + // Spawn managers. + addSpawn(MANAGER, BLUE_BUFFER_SPAWN_LOC, false, (WAIT_TIME + FIGHT_TIME) * 60000, false, PVP_WORLD.getId()); + addSpawn(MANAGER, RED_BUFFER_SPAWN_LOC, false, (WAIT_TIME + FIGHT_TIME) * 60000, false, PVP_WORLD.getId()); + // Initialize scores. + BLUE_SCORE = 0; + RED_SCORE = 0; + // Initialize scoreboard. + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.INITIALIZE, Util.sortByValue(PLAYER_SCORES))); + // Schedule start. + startQuestTimer("5", (WAIT_TIME * 60000) - 5000, null, null); + startQuestTimer("4", (WAIT_TIME * 60000) - 4000, null, null); + startQuestTimer("3", (WAIT_TIME * 60000) - 3000, null, null); + startQuestTimer("2", (WAIT_TIME * 60000) - 2000, null, null); + startQuestTimer("1", (WAIT_TIME * 60000) - 1000, null, null); + startQuestTimer("StartFight", WAIT_TIME * 60000, null, null); + break; + } + case "StartFight": + { + // Open doors. + openDoor(BLUE_DOOR_ID, PVP_WORLD.getId()); + openDoor(RED_DOOR_ID, PVP_WORLD.getId()); + // Send message. + broadcastScreenMessageWithEffect("The fight has began!", 5); + // Schedule finish. + startQuestTimer("10", (FIGHT_TIME * 60000) - 10000, null, null); + startQuestTimer("9", (FIGHT_TIME * 60000) - 9000, null, null); + startQuestTimer("8", (FIGHT_TIME * 60000) - 8000, null, null); + startQuestTimer("7", (FIGHT_TIME * 60000) - 7000, null, null); + startQuestTimer("6", (FIGHT_TIME * 60000) - 6000, null, null); + startQuestTimer("5", (FIGHT_TIME * 60000) - 5000, null, null); + startQuestTimer("4", (FIGHT_TIME * 60000) - 4000, null, null); + startQuestTimer("3", (FIGHT_TIME * 60000) - 3000, null, null); + startQuestTimer("2", (FIGHT_TIME * 60000) - 2000, null, null); + startQuestTimer("1", (FIGHT_TIME * 60000) - 1000, null, null); + startQuestTimer("EndFight", FIGHT_TIME * 60000, null, null); + break; + } + case "EndFight": + { + // Close doors. + closeDoor(BLUE_DOOR_ID, PVP_WORLD.getId()); + closeDoor(RED_DOOR_ID, PVP_WORLD.getId()); + // Disable players. + for (L2PcInstance participant : PLAYER_LIST) + { + participant.setIsInvul(true); + participant.setIsImmobilized(true); + participant.disableAllSkills(); + for (L2Summon summon : participant.getServitors().values()) + { + summon.setIsInvul(true); + summon.setIsImmobilized(true); + summon.disableAllSkills(); + } + } + // Make sure noone is dead. + for (L2PcInstance participant : PLAYER_LIST) + { + if (participant.isDead()) + { + participant.doRevive(); + } + } + // Team Blue wins. + if (BLUE_SCORE > RED_SCORE) + { + final Skill skill = CommonSkill.FIREWORK.getSkill(); + broadcastScreenMessageWithEffect("Team Blue won the event!", 7); + for (L2PcInstance participant : BLUE_TEAM) + { + if ((participant != null) && (participant.getInstanceWorld() == PVP_WORLD)) + { + participant.broadcastPacket(new MagicSkillUse(participant, participant, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay())); + participant.broadcastSocialAction(3); + giveItems(participant, REWARD); + } + } + } + // Team Red wins. + else if (RED_SCORE > BLUE_SCORE) + { + final Skill skill = CommonSkill.FIREWORK.getSkill(); + broadcastScreenMessageWithEffect("Team Red won the event!", 7); + for (L2PcInstance participant : RED_TEAM) + { + if ((participant != null) && (participant.getInstanceWorld() == PVP_WORLD)) + { + participant.broadcastPacket(new MagicSkillUse(participant, participant, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay())); + participant.broadcastSocialAction(3); + giveItems(participant, REWARD); + } + } + } + // Tie. + else + { + broadcastScreenMessageWithEffect("The event ended with a tie!", 7); + for (L2PcInstance participant : PLAYER_LIST) + { + participant.broadcastSocialAction(13); + } + } + startQuestTimer("ScoreBoard", 3500, null, null); + startQuestTimer("TeleportOut", 7000, null, null); + break; + } + case "ScoreBoard": + { + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.FINISH, Util.sortByValue(PLAYER_SCORES))); + break; + } + case "TeleportOut": + { + // Remove event listeners. + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setTeam(Team.NONE); + participant.setOnCustomEvent(false); + participant.leaveParty(); + } + // Destroy world. + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + // Enable players. + for (L2PcInstance participant : PLAYER_LIST) + { + participant.setIsInvul(false); + participant.setIsImmobilized(false); + participant.enableAllSkills(); + for (L2Summon summon : participant.getServitors().values()) + { + summon.setIsInvul(true); + summon.setIsImmobilized(true); + summon.disableAllSkills(); + } + } + EVENT_ACTIVE = false; + break; + } + case "ResurrectPlayer": + { + if (player.isDead() && player.isOnCustomEvent()) + { + if (BLUE_TEAM.contains(player)) + { + player.setIsPendingRevive(true); + player.teleToLocation(BLUE_SPAWN_LOC, false, PVP_WORLD); + } + else if (RED_TEAM.contains(player)) + { + player.setIsPendingRevive(true); + player.teleToLocation(RED_SPAWN_LOC, false, PVP_WORLD); + } + } + break; + } + case "10": + { + broadcastScreenMessage("10", 4); + break; + } + case "9": + { + broadcastScreenMessage("9", 4); + break; + } + case "8": + { + broadcastScreenMessage("8", 4); + break; + } + case "7": + { + broadcastScreenMessage("7", 4); + break; + } + case "6": + { + broadcastScreenMessage("6", 4); + break; + } + case "5": + { + broadcastScreenMessage("5", 4); + break; + } + case "4": + { + broadcastScreenMessage("4", 4); + break; + } + case "3": + { + broadcastScreenMessage("3", 4); + break; + } + case "2": + { + broadcastScreenMessage("2", 4); + break; + } + case "1": + { + broadcastScreenMessage("1", 4); + break; + } + } + // Activity timer. + if (event.startsWith("KickPlayer") && (player != null) && (player.getInstanceWorld() == PVP_WORLD)) + { + player.setTeam(Team.NONE); + PVP_WORLD.ejectPlayer(player); + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + BLUE_TEAM.remove(player); + RED_TEAM.remove(player); + player.setOnCustomEvent(false); + removeListeners(player); + player.sendMessage("You have been kicked for been inactive."); + if (PVP_WORLD != null) + { + broadcastScreenMessageWithEffect("Player " + player.getName() + " was kicked for been inactive.", 7); + } + } + return htmltext; + } + + @Override + public String onFirstTalk(L2Npc npc, L2PcInstance player) + { + // Event not active. + if (!EVENT_ACTIVE) + { + return null; + } + + // Player has already registered. + if (PLAYER_LIST.contains(player)) + { + // Npc is in instance. + if (npc.getInstanceWorld() != null) + { + return "manager-buffheal.html"; + } + return "manager-cancel.html"; + } + // Player is not registered. + return "manager-register.html"; + } + + @Override + public String onEnterZone(L2Character character, L2ZoneType zone) + { + if (character.isPlayable() && character.getActingPlayer().isOnCustomEvent()) + { + // Kick enemy players. + if ((zone == BLUE_PEACE_ZONE) && (character.getTeam() == Team.RED)) + { + character.teleToLocation(RED_SPAWN_LOC, PVP_WORLD); + character.getActingPlayer().sendPacket(new ExShowScreenMessage("Entering the enemy headquarters is prohibited!", ExShowScreenMessage.TOP_CENTER, 10000, 0, true, false)); + } + if ((zone == RED_PEACE_ZONE) && (character.getTeam() == Team.BLUE)) + { + character.teleToLocation(BLUE_SPAWN_LOC, PVP_WORLD); + character.getActingPlayer().sendPacket(new ExShowScreenMessage("Entering the enemy headquarters is prohibited!", ExShowScreenMessage.TOP_CENTER, 10000, 0, true, false)); + } + // Start inactivity check. + if (character.isPlayer() && // + ((((zone == BLUE_PEACE_ZONE) && (character.getTeam() == Team.BLUE)) || // + ((zone == RED_PEACE_ZONE) && (character.getTeam() == Team.RED))))) + { + startQuestTimer("KickPlayer" + character.getObjectId(), PVP_WORLD.getDoor(BLUE_DOOR_ID).isOpen() ? INACTIVITY_TIME * 60000 : (INACTIVITY_TIME * 60000) + (WAIT_TIME * 60000), null, character.getActingPlayer()); + } + } + return null; + } + + @Override + public String onExitZone(L2Character character, L2ZoneType zone) + { + if (character.isPlayer() && character.getActingPlayer().isOnCustomEvent()) + { + cancelQuestTimer("KickPlayer" + character.getObjectId(), null, character.getActingPlayer()); + } + return super.onExitZone(character, zone); + } + + private boolean canRegister(L2PcInstance player) + { + if (PLAYER_LIST.contains(player)) + { + player.sendMessage("You are already registered on this event."); + return false; + } + if (player.getLevel() < MINIMUM_PARTICIPANT_LEVEL) + { + player.sendMessage("Your level is too low to participate."); + return false; + } + if (player.getLevel() > MAXIMUM_PARTICIPANT_LEVEL) + { + player.sendMessage("Your level is too high to participate."); + return false; + } + if (player.isOnEvent() || (player.getBlockCheckerArena() > -1)) + { + player.sendMessage("You are already registered on an event."); + return false; + } + if (PLAYER_LIST.size() >= MAXIMUM_PARTICIPANT_COUNT) + { + player.sendMessage("There are too many players registered on the event."); + return false; + } + if (player.isFlyingMounted()) + { + player.sendMessage("You cannot register on the event while flying."); + return false; + } + if (player.isTransformed()) + { + player.sendMessage("You cannot register on the event while on a transformed state."); + return false; + } + if (!player.isInventoryUnder80(false)) + { + player.sendMessage("There are too many items in your inventory."); + player.sendMessage("Try removing some items."); + return false; + } + if ((player.getWeightPenalty() != 0)) + { + player.sendMessage("Your invetory weight has exceeded the normal limit."); + player.sendMessage("Try removing some items."); + return false; + } + if (player.isCursedWeaponEquipped() || (player.getReputation() < 0)) + { + player.sendMessage("People with bad reputation can't register."); + return false; + } + if (player.isInDuel()) + { + player.sendMessage("You cannot register while on a duel."); + return false; + } + if (player.isInOlympiadMode() || OlympiadManager.getInstance().isRegistered(player)) + { + player.sendMessage("You cannot participate while registered on the Olympiad."); + return false; + } + if (player.isInInstance()) + { + player.sendMessage("You cannot register while in an instance."); + return false; + } + if (player.isInSiege() || player.isInsideZone(ZoneId.SIEGE)) + { + player.sendMessage("You cannot register while on a siege."); + return false; + } + if (player.isFishing()) + { + player.sendMessage("You cannot register while fishing."); + return false; + } + return true; + } + + private void broadcastScreenMessageWithEffect(String message, int duration) + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage(message, ExShowScreenMessage.TOP_CENTER, duration * 1000, 0, true, true)); + } + + private void broadcastScreenMessage(String message, int duration) + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage(message, ExShowScreenMessage.TOP_CENTER, duration * 1000, 0, true, false)); + } + + private void broadcastScoreMessage() + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage("Blue: " + BLUE_SCORE + " - Red: " + RED_SCORE, ExShowScreenMessage.BOTTOM_RIGHT, 15000, 0, true, false)); + } + + private void addLogoutListener(L2PcInstance player) + { + player.addListener(new ConsumerEventListener(player, EventType.ON_PLAYER_LOGOUT, (OnPlayerLogout event) -> OnPlayerLogout(event), this)); + } + + private void addDeathListener(L2PcInstance player) + { + player.addListener(new ConsumerEventListener(player, EventType.ON_CREATURE_DEATH, (OnCreatureDeath event) -> onPlayerDeath(event), this)); + } + + private void removeListeners(L2PcInstance player) + { + for (AbstractEventListener listener : player.getListeners(EventType.ON_PLAYER_LOGOUT)) + { + if (listener.getOwner() == this) + { + listener.unregisterMe(); + } + } + for (AbstractEventListener listener : player.getListeners(EventType.ON_CREATURE_DEATH)) + { + if (listener.getOwner() == this) + { + listener.unregisterMe(); + } + } + } + + @RegisterEvent(EventType.ON_PLAYER_LOGOUT) + private void OnPlayerLogout(OnPlayerLogout event) + { + final L2PcInstance player = event.getActiveChar(); + if (player != null) + { + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + BLUE_TEAM.remove(player); + RED_TEAM.remove(player); + } + // If all players left instance end the event. + if (PLAYER_LIST.isEmpty()) + { + // Stop timers. + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Destroy world. + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + } + } + + @RegisterEvent(EventType.ON_CREATURE_DEATH) + public void onPlayerDeath(OnCreatureDeath event) + { + if (event.getTarget().isPlayer()) + { + final L2PcInstance killedPlayer = event.getTarget().getActingPlayer(); + final L2PcInstance killer = event.getAttacker().getActingPlayer(); + // Confirm Blue team kill. + if ((killer.getTeam() == Team.BLUE) && (killedPlayer.getTeam() == Team.RED)) + { + PLAYER_SCORES.put(killer, PLAYER_SCORES.get(killer) + 1); + BLUE_SCORE++; + broadcastScoreMessage(); + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.UPDATE, Util.sortByValue(PLAYER_SCORES))); + } + // Confirm Red team kill. + if ((killer.getTeam() == Team.RED) && (killedPlayer.getTeam() == Team.BLUE)) + { + PLAYER_SCORES.put(killer, PLAYER_SCORES.get(killer) + 1); + RED_SCORE++; + broadcastScoreMessage(); + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.UPDATE, Util.sortByValue(PLAYER_SCORES))); + } + // Auto release after 10 seconds. + startQuestTimer("ResurrectPlayer", 10000, null, killedPlayer); + } + } + + @Override + public boolean eventStart(L2PcInstance eventMaker) + { + if (EVENT_ACTIVE) + { + return false; + } + EVENT_ACTIVE = true; + + // Cancel timers. (In case event started immediately after another event finished.) + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Clear player lists. + PLAYER_LIST.clear(); + PLAYER_SCORES.clear(); + BLUE_TEAM.clear(); + RED_TEAM.clear(); + // Spawn event manager. + MANAGER_NPC_INSTANCE = addSpawn(MANAGER, MANAGER_SPAWN_LOC, false, REGISTRATION_TIME * 60000); + startQuestTimer("TeleportToArena", REGISTRATION_TIME * 60000, null, null); + // Send message to players. + Broadcast.toAllOnlinePlayers("TvT Event: Registration opened for " + REGISTRATION_TIME + " minutes."); + Broadcast.toAllOnlinePlayers("TvT Event: You can register at Giran TvT Event Manager."); + + return true; + } + + @Override + public boolean eventStop() + { + if (!EVENT_ACTIVE) + { + return false; + } + EVENT_ACTIVE = false; + + // Despawn event manager. + MANAGER_NPC_INSTANCE.deleteMe(); + // Cancel timers. + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Remove participants. + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setTeam(Team.NONE); + participant.setOnCustomEvent(false); + } + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + // Send message to players. + Broadcast.toAllOnlinePlayers("TvT Event: Event was canceled."); + return true; + } + + @Override + public boolean eventBypass(L2PcInstance activeChar, String bypass) + { + return false; + } + + public static void main(String[] args) + { + new TvT(); + } +} diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html new file mode 100644 index 0000000000..54bbd53443 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Need assistance?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html new file mode 100644 index 0000000000..6c9101990c --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Cancel your participation?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html new file mode 100644 index 0000000000..2b72e551d8 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
You are in combat, calm down...
+
+
+
+
+
+ + diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html new file mode 100644 index 0000000000..c5d7eb5d12 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Do you want to join the event?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html new file mode 100644 index 0000000000..5b21728486 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration canceled.
+
+
+
+
+
+ + diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html new file mode 100644 index 0000000000..2f3b31f9f6 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration failed.
+
+
+
+
+
+ + diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html new file mode 100644 index 0000000000..548a8a1750 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration successful!
+
+
+
+
+
+ + diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java index d17921338b..e06f9e07fd 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java @@ -63,19 +63,23 @@ public class AdminZone implements IAdminCommandHandler getGeoRegionXY(activeChar); activeChar.sendMessage("Closest Town: " + MapRegionManager.getInstance().getClosestTownName(activeChar)); - Location loc; - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CASTLE); - activeChar.sendMessage("TeleToLocation (Castle): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CLANHALL); - activeChar.sendMessage("TeleToLocation (ClanHall): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.SIEGEFLAG); - activeChar.sendMessage("TeleToLocation (SiegeFlag): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.TOWN); - activeChar.sendMessage("TeleToLocation (Town): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + // Prevent exit instance variable deletion. + if (!activeChar.isInInstance()) + { + Location loc; + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CASTLE); + activeChar.sendMessage("TeleToLocation (Castle): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CLANHALL); + activeChar.sendMessage("TeleToLocation (ClanHall): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.SIEGEFLAG); + activeChar.sendMessage("TeleToLocation (SiegeFlag): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.TOWN); + activeChar.sendMessage("TeleToLocation (Town): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + } } else if (actualCommand.equalsIgnoreCase("admin_zone_visual")) { diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/custom.xml b/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/custom.xml index 5b2d3489b1..c9b6b84f6c 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/custom.xml +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/custom.xml @@ -1,23 +1,5 @@ - - ELEMENTAL - FEMALE - - - - - - - - - - - - - - - ANIMAL MALE diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/tvt_event.xml b/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/tvt_event.xml new file mode 100644 index 0000000000..a867441b79 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/tvt_event.xml @@ -0,0 +1,22 @@ + + + + HUMAN + MALE + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 7163ac783b..4e61159d0b 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -674,6 +674,7 @@ public final class L2PcInstance extends L2Playable @SuppressWarnings("rawtypes") private volatile Map, AbstractEvent> _events; + private boolean _isOnCustomEvent = false; public boolean isSpawnProtected() { @@ -8149,7 +8150,12 @@ public final class L2PcInstance extends L2Playable return false; } - // Check if the attacker is in TvT and TvT is started + if (isOnCustomEvent() && (getTeam() == attacker.getTeam())) + { + return false; + } + + // CoC needs this check? if (isOnEvent()) { return true; @@ -13116,12 +13122,26 @@ public final class L2PcInstance extends L2Playable _canRevive = val; } + public boolean isOnCustomEvent() + { + return _isOnCustomEvent; + } + + public void setOnCustomEvent(boolean value) + { + _isOnCustomEvent = value; + } + /** * @return {@code true} if player is on event, {@code false} otherwise. */ @Override public boolean isOnEvent() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) @@ -13137,6 +13157,10 @@ public final class L2PcInstance extends L2Playable public boolean isBlockedFromExit() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) @@ -13152,6 +13176,10 @@ public final class L2PcInstance extends L2Playable public boolean isBlockedFromDeathPenalty() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java index c3686c67be..d1bb6ffa75 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java @@ -63,6 +63,10 @@ public class ConditionPlayerCanEscape extends Condition { canTeleport = false; } + else if (player.isOnCustomEvent()) + { + canTeleport = false; + } return (_val == canTeleport); } } \ No newline at end of file diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java index 4ed6708e7f..679e38bdb6 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java @@ -64,6 +64,11 @@ public class ConditionPlayerCanTransform extends Condition player.sendPacket(SystemMessageId.YOU_CANNOT_TRANSFORM_WHILE_RIDING_A_PET); canTransform = false; } + else if (player.isOnCustomEvent()) + { + player.sendMessage("You cannot transform while registered on an event."); + canTransform = false; + } return (_val == canTransform); } } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/Instance.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/Instance.java index 77c2468437..70464afd7c 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/Instance.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/Instance.java @@ -888,19 +888,22 @@ public final class Instance implements IIdentifiable, INamable */ public void onDeath(L2PcInstance player) { - // Send message - final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IF_YOU_ARE_NOT_RESURRECTED_WITHIN_S1_MINUTE_S_YOU_WILL_BE_EXPELLED_FROM_THE_INSTANT_ZONE); - sm.addInt(_template.getEjectTime()); - player.sendPacket(sm); - - // Start eject task - _ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.schedule(() -> + if (!player.isOnCustomEvent()) { - if (player.isDead()) + // Send message + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IF_YOU_ARE_NOT_RESURRECTED_WITHIN_S1_MINUTE_S_YOU_WILL_BE_EXPELLED_FROM_THE_INSTANT_ZONE); + sm.addInt(_template.getEjectTime()); + player.sendPacket(sm); + + // Start eject task + _ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.schedule(() -> { - ejectPlayer(player.getActingPlayer()); - } - }, _template.getEjectTime() * 60 * 1000)); // minutes to milliseconds + if (player.isDead()) + { + ejectPlayer(player.getActingPlayer()); + } + }, _template.getEjectTime() * 60 * 1000)); // minutes to milliseconds + } } /** diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java index f4fa7592ad..409678ea5a 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java @@ -365,6 +365,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl public Location getExitLocation(L2PcInstance player) { Location location = null; + switch (_exitLocationType) { case RANDOM: diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java index 13d16edd56..07d3e538f9 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java @@ -173,8 +173,8 @@ public enum ExIncomingPackets implements IIncomingPackets EX_BOOKMARK_PACKET(0x4E, ExBookmarkPacket::new, ConnectionState.IN_GAME), REQUEST_WITHDRAW_PREMIUM_ITEM(0x4F, RequestWithDrawPremiumItem::new, ConnectionState.IN_GAME), REQUEST_EX_JUMP(0x50, null, ConnectionState.IN_GAME), - REQUEST_EX_START_SHOW_CRATAE_CUBE_RANK(0x51, null, ConnectionState.IN_GAME), - REQUEST_EX_STOP_SHOW_CRATAE_CUBE_RANK(0x52, null, ConnectionState.IN_GAME), + REQUEST_EX_START_SHOW_CRATAE_CUBE_RANK(0x51, RequestStartShowKrateisCubeRank::new, ConnectionState.IN_GAME), + REQUEST_EX_STOP_SHOW_CRATAE_CUBE_RANK(0x52, RequestStopShowKrateisCubeRank::new, ConnectionState.IN_GAME), NOTIFY_START_MINI_GAME(0x53, null, ConnectionState.IN_GAME), REQUEST_EX_JOIN_DOMINION_WAR(0x54, null, ConnectionState.IN_GAME), REQUEST_EX_DOMINION_INFO(0x55, null, ConnectionState.IN_GAME), diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java index 6c7ebff02e..31e80f64fb 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java @@ -29,7 +29,10 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.entity.Castle; import com.l2jmobius.gameserver.model.entity.ClanHall; import com.l2jmobius.gameserver.model.entity.Fort; +import com.l2jmobius.gameserver.model.events.EventType; +import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; import com.l2jmobius.gameserver.model.instancezone.Instance; +import com.l2jmobius.gameserver.model.quest.Event; import com.l2jmobius.gameserver.model.residences.AbstractResidence; import com.l2jmobius.gameserver.model.residences.ResidenceFunctionType; import com.l2jmobius.gameserver.network.L2GameClient; @@ -92,6 +95,19 @@ public final class RequestRestartPoint implements IClientIncomingPacket return; } + // Custom event resurrection management. + if (activeChar.isOnCustomEvent()) + { + for (AbstractEventListener listener : activeChar.getListeners(EventType.ON_CREATURE_DEATH)) + { + if (listener.getOwner() instanceof Event) + { + ((Event) listener.getOwner()).notifyEvent("ResurrectPlayer", null, activeChar); + return; + } + } + } + final Castle castle = CastleManager.getInstance().getCastle(activeChar.getX(), activeChar.getY(), activeChar.getZ()); if ((castle != null) && castle.getSiege().isInProgress()) { diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java new file mode 100644 index 0000000000..d2213e55b6 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java @@ -0,0 +1,39 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.clientpackets; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; + +/** + * @author Mobius + */ +public class RequestStartShowKrateisCubeRank implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return false; + } + + @Override + public void run(L2GameClient client) + { + // TODO: Implement. + System.out.println("RequestStartShowKrateisCubeRank"); + } +} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java new file mode 100644 index 0000000000..51ca3ea99b --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java @@ -0,0 +1,39 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.clientpackets; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; + +/** + * @author Mobius + */ +public class RequestStopShowKrateisCubeRank implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return false; + } + + @Override + public void run(L2GameClient client) + { + // TODO: Implement. + System.out.println("RequestStopShowKrateisCubeRank"); + } +} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java new file mode 100644 index 0000000000..57547b985e --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java @@ -0,0 +1,41 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.serverpackets; + +import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.network.OutgoingPackets; + +/** + * @author Mobius + */ +public class ExPVPMatchCCMyRecord implements IClientOutgoingPacket +{ + private final int _points; + + public ExPVPMatchCCMyRecord(int points) + { + _points = points; + } + + @Override + public boolean write(PacketWriter packet) + { + OutgoingPackets.EX_PVP_MATCH_CCMY_RECORD.writeId(packet); + packet.writeD(_points); + return true; + } +} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java new file mode 100644 index 0000000000..b199a7443c --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java @@ -0,0 +1,57 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.serverpackets; + +import java.util.Map; +import java.util.Map.Entry; + +import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.network.OutgoingPackets; + +/** + * @author Mobius + */ +public class ExPVPMatchCCRecord implements IClientOutgoingPacket +{ + public static final int INITIALIZE = 0; + public static final int UPDATE = 1; + public static final int FINISH = 2; + + private final int _state; + private final Map _players; + + public ExPVPMatchCCRecord(int state, Map players) + { + _state = state; + _players = players; + } + + @Override + public boolean write(PacketWriter packet) + { + OutgoingPackets.EX_PVP_MATCH_CCRECORD.writeId(packet); + packet.writeD(_state); // 0 - initialize, 1 - update, 2 - finish + packet.writeD(_players.size()); + for (Entry entry : _players.entrySet()) + { + packet.writeS(entry.getKey().getName()); + packet.writeD(entry.getValue()); + } + return true; + } +} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/util/Util.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/util/Util.java index e551224ab8..850ae469e6 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/util/Util.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/util/Util.java @@ -31,6 +31,8 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; import java.util.logging.Logger; import com.l2jmobius.Config; @@ -788,4 +790,15 @@ public final class Util return (input < min) ? min : (input > max) ? max : input; } + /** + * Short an map by its integer values. + * @param unsortedMap + * @return + */ + public static Map sortByValue(Map unsortedMap) + { + Map sortedMap = new TreeMap<>(new ValueComparator(unsortedMap)); + sortedMap.putAll(unsortedMap); + return sortedMap; + } } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/util/ValueComparator.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/util/ValueComparator.java new file mode 100644 index 0000000000..32c494218d --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/util/ValueComparator.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.util; + +import java.util.Comparator; +import java.util.Map; + +/** + * @author Mobius + */ +public class ValueComparator implements Comparator +{ + Map _map; + + public ValueComparator(Map map) + { + _map = map; + } + + @SuppressWarnings( + { + "rawtypes", + "unchecked" + }) + @Override + public int compare(Object keyA, Object keyB) + { + Comparable valueA = (Comparable) _map.get(keyA); + Comparable valueB = (Comparable) _map.get(keyB); + return valueB.compareTo(valueA); + } +} diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/instances/custom/coliseum.xml b/L2J_Mobius_2.5_Underground/dist/game/data/instances/custom/coliseum.xml index 6c8eb9385c..27a7498e9b 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/instances/custom/coliseum.xml +++ b/L2J_Mobius_2.5_Underground/dist/game/data/instances/custom/coliseum.xml @@ -1,9 +1,23 @@ + diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java new file mode 100644 index 0000000000..f31b220207 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java @@ -0,0 +1,871 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package custom.events.TeamVsTeam; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.l2jmobius.gameserver.enums.CategoryType; +import com.l2jmobius.gameserver.enums.PartyDistributionType; +import com.l2jmobius.gameserver.enums.Team; +import com.l2jmobius.gameserver.instancemanager.InstanceManager; +import com.l2jmobius.gameserver.instancemanager.ZoneManager; +import com.l2jmobius.gameserver.model.L2CommandChannel; +import com.l2jmobius.gameserver.model.L2Party; +import com.l2jmobius.gameserver.model.Location; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.L2Npc; +import com.l2jmobius.gameserver.model.actor.L2Summon; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.events.EventType; +import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent; +import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDeath; +import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout; +import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; +import com.l2jmobius.gameserver.model.events.listeners.ConsumerEventListener; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.SkillHolder; +import com.l2jmobius.gameserver.model.instancezone.Instance; +import com.l2jmobius.gameserver.model.instancezone.InstanceTemplate; +import com.l2jmobius.gameserver.model.olympiad.OlympiadManager; +import com.l2jmobius.gameserver.model.quest.Event; +import com.l2jmobius.gameserver.model.quest.QuestTimer; +import com.l2jmobius.gameserver.model.skills.CommonSkill; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.skills.SkillCaster; +import com.l2jmobius.gameserver.model.zone.L2ZoneType; +import com.l2jmobius.gameserver.model.zone.ZoneId; +import com.l2jmobius.gameserver.network.serverpackets.ExPVPMatchCCRecord; +import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; +import com.l2jmobius.gameserver.util.Broadcast; +import com.l2jmobius.gameserver.util.Util; + +/** + * Team vs Team event. + * @author Mobius + */ +public class TvT extends Event +{ + // NPC + private static final int MANAGER = 70010; + // Skills + private static final SkillHolder KNIGHT = new SkillHolder(15648, 1); // Knight's Harmony (Adventurer) + private static final SkillHolder WARRIOR = new SkillHolder(15649, 1); // Warrior's Harmony (Adventurer) + private static final SkillHolder WIZARD = new SkillHolder(15650, 1); // Wizard's Harmony (Adventurer) + private static final SkillHolder[] GROUP_BUFFS = + { + new SkillHolder(15642, 1), // Horn Melody (Adventurer) + new SkillHolder(15643, 1), // Drum Melody (Adventurer) + new SkillHolder(15644, 1), // Pipe Organ Melody (Adventurer) + new SkillHolder(15645, 1), // Guitar Melody (Adventurer) + new SkillHolder(15646, 1), // Harp Melody (Adventurer) + new SkillHolder(15647, 1), // Lute Melody (Adventurer) + new SkillHolder(15651, 1), // Prevailing Sonata (Adventurer) + new SkillHolder(15652, 1), // Daring Sonata (Adventurer) + new SkillHolder(15653, 1), // Refreshing Sonata (Adventurer) + }; + // Others + private static final int INSTANCE_ID = 3049; + private static final int BLUE_DOOR_ID = 24190002; + private static final int RED_DOOR_ID = 24190003; + private static final Location MANAGER_SPAWN_LOC = new Location(83425, 148585, -3406, 32938); + private static final Location BLUE_BUFFER_SPAWN_LOC = new Location(147450, 46913, -3400, 49000); + private static final Location RED_BUFFER_SPAWN_LOC = new Location(151545, 46528, -3400, 16000); + private static final Location BLUE_SPAWN_LOC = new Location(147447, 46722, -3416); + private static final Location RED_SPAWN_LOC = new Location(151536, 46722, -3416); + private static final L2ZoneType BLUE_PEACE_ZONE = ZoneManager.getInstance().getZoneByName("colosseum_peace1"); + private static final L2ZoneType RED_PEACE_ZONE = ZoneManager.getInstance().getZoneByName("colosseum_peace2"); + // Settings + private static final int REGISTRATION_TIME = 10; // Minutes + private static final int WAIT_TIME = 1; // Minutes + private static final int FIGHT_TIME = 20; // Minutes + private static final int INACTIVITY_TIME = 2; // Minutes + private static final int MINIMUM_PARTICIPANT_LEVEL = 85; + private static final int MAXIMUM_PARTICIPANT_LEVEL = 200; + private static final int MINIMUM_PARTICIPANT_COUNT = 4; + private static final int MAXIMUM_PARTICIPANT_COUNT = 24; // Scoreboard has 25 slots + private static final int PARTY_MEMBER_COUNT = 7; + private static final ItemHolder REWARD = new ItemHolder(57, 1000000); // Adena + // Misc + private static final Map PLAYER_SCORES = new ConcurrentHashMap<>(); + private static final List PLAYER_LIST = new ArrayList<>(); + private static final List BLUE_TEAM = new ArrayList<>(); + private static final List RED_TEAM = new ArrayList<>(); + private static volatile int BLUE_SCORE; + private static volatile int RED_SCORE; + private static Instance PVP_WORLD = null; + private static L2Npc MANAGER_NPC_INSTANCE = null; + private static boolean EVENT_ACTIVE = false; + + private TvT() + { + addTalkId(MANAGER); + addFirstTalkId(MANAGER); + addExitZoneId(BLUE_PEACE_ZONE.getId(), RED_PEACE_ZONE.getId()); + addEnterZoneId(BLUE_PEACE_ZONE.getId(), RED_PEACE_ZONE.getId()); + } + + @Override + public String onAdvEvent(String event, L2Npc npc, L2PcInstance player) + { + if (!EVENT_ACTIVE) + { + return null; + } + + String htmltext = null; + switch (event) + { + case "Participate": + { + if (canRegister(player)) + { + PLAYER_LIST.add(player); + PLAYER_SCORES.put(player, 0); + player.setOnCustomEvent(true); + addLogoutListener(player); + htmltext = "registration-success.html"; + } + else + { + htmltext = "registration-failed.html"; + } + break; + } + case "CancelParticipation": + { + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + removeListeners(player); + player.setOnCustomEvent(false); + htmltext = "registration-canceled.html"; + break; + } + case "BuffHeal": + { + if (player.isOnCustomEvent() || player.isGM()) + { + if (player.isInCombat()) + { + htmltext = "manager-combat.html"; + } + else + { + for (SkillHolder holder : GROUP_BUFFS) + { + SkillCaster.triggerCast(npc, player, holder.getSkill()); + } + if (player.isMageClass()) + { + SkillCaster.triggerCast(npc, player, WIZARD.getSkill()); + } + else if (player.isInCategory(CategoryType.KNIGHT_GROUP)) + { + SkillCaster.triggerCast(npc, player, KNIGHT.getSkill()); + } + else + { + SkillCaster.triggerCast(npc, player, WARRIOR.getSkill()); + } + player.setCurrentHp(player.getMaxHp()); + player.setCurrentMp(player.getMaxMp()); + player.setCurrentCp(player.getMaxCp()); + } + } + break; + } + case "TeleportToArena": + { + // Remove offline players. + for (L2PcInstance participant : PLAYER_LIST) + { + if ((participant == null) || (participant.isOnlineInt() != 1)) + { + PLAYER_LIST.remove(participant); + PLAYER_SCORES.remove(participant); + } + } + // Check if there are enough players to start the event. + if (PLAYER_LIST.size() < MINIMUM_PARTICIPANT_COUNT) + { + Broadcast.toAllOnlinePlayers("TvT Event: Event was canceled, not enough participants."); + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setOnCustomEvent(false); + } + EVENT_ACTIVE = false; + return null; + } + // Create the instance. + final InstanceManager manager = InstanceManager.getInstance(); + final InstanceTemplate template = manager.getInstanceTemplate(INSTANCE_ID); + PVP_WORLD = manager.createInstance(template, null); + // Randomize player list and separate teams. + Collections.shuffle(PLAYER_LIST); + boolean team = getRandomBoolean(); // If teams are not even, randomize where extra player goes. + for (L2PcInstance participant : PLAYER_LIST) + { + if (team) + { + BLUE_TEAM.add(participant); + PVP_WORLD.addAllowed(participant); + participant.leaveParty(); + participant.setTeam(Team.BLUE); + participant.teleToLocation(BLUE_SPAWN_LOC, PVP_WORLD); + team = false; + } + else + { + RED_TEAM.add(participant); + PVP_WORLD.addAllowed(participant); + participant.leaveParty(); + participant.setTeam(Team.RED); + participant.teleToLocation(RED_SPAWN_LOC, PVP_WORLD); + team = true; + } + addDeathListener(participant); + } + // Make Blue CC. + if (BLUE_TEAM.size() > 1) + { + L2CommandChannel blueCC = null; + L2Party lastBlueParty = null; + int blueParticipantCounter = 0; + for (L2PcInstance participant : BLUE_TEAM) + { + blueParticipantCounter++; + if (blueParticipantCounter == 1) + { + lastBlueParty = new L2Party(participant, PartyDistributionType.FINDERS_KEEPERS); + participant.joinParty(lastBlueParty); + if (BLUE_TEAM.size() > PARTY_MEMBER_COUNT) + { + if (blueCC == null) + { + blueCC = new L2CommandChannel(participant); + } + else + { + blueCC.addParty(lastBlueParty); + } + } + } + else if (lastBlueParty != null) + { + participant.joinParty(lastBlueParty); + } + if (blueParticipantCounter == PARTY_MEMBER_COUNT) + { + blueParticipantCounter = 0; + } + } + } + // Make Red CC. + if (RED_TEAM.size() > 1) + { + L2CommandChannel redCC = null; + L2Party lastRedParty = null; + int redParticipantCounter = 0; + for (L2PcInstance participant : RED_TEAM) + { + redParticipantCounter++; + if (redParticipantCounter == 1) + { + lastRedParty = new L2Party(participant, PartyDistributionType.FINDERS_KEEPERS); + participant.joinParty(lastRedParty); + if (RED_TEAM.size() > PARTY_MEMBER_COUNT) + { + if (redCC == null) + { + redCC = new L2CommandChannel(participant); + } + else + { + redCC.addParty(lastRedParty); + } + } + } + else if (lastRedParty != null) + { + participant.joinParty(lastRedParty); + } + if (redParticipantCounter == PARTY_MEMBER_COUNT) + { + redParticipantCounter = 0; + } + } + } + // Spawn managers. + addSpawn(MANAGER, BLUE_BUFFER_SPAWN_LOC, false, (WAIT_TIME + FIGHT_TIME) * 60000, false, PVP_WORLD.getId()); + addSpawn(MANAGER, RED_BUFFER_SPAWN_LOC, false, (WAIT_TIME + FIGHT_TIME) * 60000, false, PVP_WORLD.getId()); + // Initialize scores. + BLUE_SCORE = 0; + RED_SCORE = 0; + // Initialize scoreboard. + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.INITIALIZE, Util.sortByValue(PLAYER_SCORES))); + // Schedule start. + startQuestTimer("5", (WAIT_TIME * 60000) - 5000, null, null); + startQuestTimer("4", (WAIT_TIME * 60000) - 4000, null, null); + startQuestTimer("3", (WAIT_TIME * 60000) - 3000, null, null); + startQuestTimer("2", (WAIT_TIME * 60000) - 2000, null, null); + startQuestTimer("1", (WAIT_TIME * 60000) - 1000, null, null); + startQuestTimer("StartFight", WAIT_TIME * 60000, null, null); + break; + } + case "StartFight": + { + // Open doors. + openDoor(BLUE_DOOR_ID, PVP_WORLD.getId()); + openDoor(RED_DOOR_ID, PVP_WORLD.getId()); + // Send message. + broadcastScreenMessageWithEffect("The fight has began!", 5); + // Schedule finish. + startQuestTimer("10", (FIGHT_TIME * 60000) - 10000, null, null); + startQuestTimer("9", (FIGHT_TIME * 60000) - 9000, null, null); + startQuestTimer("8", (FIGHT_TIME * 60000) - 8000, null, null); + startQuestTimer("7", (FIGHT_TIME * 60000) - 7000, null, null); + startQuestTimer("6", (FIGHT_TIME * 60000) - 6000, null, null); + startQuestTimer("5", (FIGHT_TIME * 60000) - 5000, null, null); + startQuestTimer("4", (FIGHT_TIME * 60000) - 4000, null, null); + startQuestTimer("3", (FIGHT_TIME * 60000) - 3000, null, null); + startQuestTimer("2", (FIGHT_TIME * 60000) - 2000, null, null); + startQuestTimer("1", (FIGHT_TIME * 60000) - 1000, null, null); + startQuestTimer("EndFight", FIGHT_TIME * 60000, null, null); + break; + } + case "EndFight": + { + // Close doors. + closeDoor(BLUE_DOOR_ID, PVP_WORLD.getId()); + closeDoor(RED_DOOR_ID, PVP_WORLD.getId()); + // Disable players. + for (L2PcInstance participant : PLAYER_LIST) + { + participant.setIsInvul(true); + participant.setIsImmobilized(true); + participant.disableAllSkills(); + for (L2Summon summon : participant.getServitors().values()) + { + summon.setIsInvul(true); + summon.setIsImmobilized(true); + summon.disableAllSkills(); + } + } + // Make sure noone is dead. + for (L2PcInstance participant : PLAYER_LIST) + { + if (participant.isDead()) + { + participant.doRevive(); + } + } + // Team Blue wins. + if (BLUE_SCORE > RED_SCORE) + { + final Skill skill = CommonSkill.FIREWORK.getSkill(); + broadcastScreenMessageWithEffect("Team Blue won the event!", 7); + for (L2PcInstance participant : BLUE_TEAM) + { + if ((participant != null) && (participant.getInstanceWorld() == PVP_WORLD)) + { + participant.broadcastPacket(new MagicSkillUse(participant, participant, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay())); + participant.broadcastSocialAction(3); + giveItems(participant, REWARD); + } + } + } + // Team Red wins. + else if (RED_SCORE > BLUE_SCORE) + { + final Skill skill = CommonSkill.FIREWORK.getSkill(); + broadcastScreenMessageWithEffect("Team Red won the event!", 7); + for (L2PcInstance participant : RED_TEAM) + { + if ((participant != null) && (participant.getInstanceWorld() == PVP_WORLD)) + { + participant.broadcastPacket(new MagicSkillUse(participant, participant, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay())); + participant.broadcastSocialAction(3); + giveItems(participant, REWARD); + } + } + } + // Tie. + else + { + broadcastScreenMessageWithEffect("The event ended with a tie!", 7); + for (L2PcInstance participant : PLAYER_LIST) + { + participant.broadcastSocialAction(13); + } + } + startQuestTimer("ScoreBoard", 3500, null, null); + startQuestTimer("TeleportOut", 7000, null, null); + break; + } + case "ScoreBoard": + { + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.FINISH, Util.sortByValue(PLAYER_SCORES))); + break; + } + case "TeleportOut": + { + // Remove event listeners. + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setTeam(Team.NONE); + participant.setOnCustomEvent(false); + participant.leaveParty(); + } + // Destroy world. + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + // Enable players. + for (L2PcInstance participant : PLAYER_LIST) + { + participant.setIsInvul(false); + participant.setIsImmobilized(false); + participant.enableAllSkills(); + for (L2Summon summon : participant.getServitors().values()) + { + summon.setIsInvul(true); + summon.setIsImmobilized(true); + summon.disableAllSkills(); + } + } + EVENT_ACTIVE = false; + break; + } + case "ResurrectPlayer": + { + if (player.isDead() && player.isOnCustomEvent()) + { + if (BLUE_TEAM.contains(player)) + { + player.setIsPendingRevive(true); + player.teleToLocation(BLUE_SPAWN_LOC, false, PVP_WORLD); + } + else if (RED_TEAM.contains(player)) + { + player.setIsPendingRevive(true); + player.teleToLocation(RED_SPAWN_LOC, false, PVP_WORLD); + } + } + break; + } + case "10": + { + broadcastScreenMessage("10", 4); + break; + } + case "9": + { + broadcastScreenMessage("9", 4); + break; + } + case "8": + { + broadcastScreenMessage("8", 4); + break; + } + case "7": + { + broadcastScreenMessage("7", 4); + break; + } + case "6": + { + broadcastScreenMessage("6", 4); + break; + } + case "5": + { + broadcastScreenMessage("5", 4); + break; + } + case "4": + { + broadcastScreenMessage("4", 4); + break; + } + case "3": + { + broadcastScreenMessage("3", 4); + break; + } + case "2": + { + broadcastScreenMessage("2", 4); + break; + } + case "1": + { + broadcastScreenMessage("1", 4); + break; + } + } + // Activity timer. + if (event.startsWith("KickPlayer") && (player != null) && (player.getInstanceWorld() == PVP_WORLD)) + { + player.setTeam(Team.NONE); + PVP_WORLD.ejectPlayer(player); + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + BLUE_TEAM.remove(player); + RED_TEAM.remove(player); + player.setOnCustomEvent(false); + removeListeners(player); + player.sendMessage("You have been kicked for been inactive."); + if (PVP_WORLD != null) + { + broadcastScreenMessageWithEffect("Player " + player.getName() + " was kicked for been inactive.", 7); + } + } + return htmltext; + } + + @Override + public String onFirstTalk(L2Npc npc, L2PcInstance player) + { + // Event not active. + if (!EVENT_ACTIVE) + { + return null; + } + + // Player has already registered. + if (PLAYER_LIST.contains(player)) + { + // Npc is in instance. + if (npc.getInstanceWorld() != null) + { + return "manager-buffheal.html"; + } + return "manager-cancel.html"; + } + // Player is not registered. + return "manager-register.html"; + } + + @Override + public String onEnterZone(L2Character character, L2ZoneType zone) + { + if (character.isPlayable() && character.getActingPlayer().isOnCustomEvent()) + { + // Kick enemy players. + if ((zone == BLUE_PEACE_ZONE) && (character.getTeam() == Team.RED)) + { + character.teleToLocation(RED_SPAWN_LOC, PVP_WORLD); + character.getActingPlayer().sendPacket(new ExShowScreenMessage("Entering the enemy headquarters is prohibited!", ExShowScreenMessage.TOP_CENTER, 10000, 0, true, false)); + } + if ((zone == RED_PEACE_ZONE) && (character.getTeam() == Team.BLUE)) + { + character.teleToLocation(BLUE_SPAWN_LOC, PVP_WORLD); + character.getActingPlayer().sendPacket(new ExShowScreenMessage("Entering the enemy headquarters is prohibited!", ExShowScreenMessage.TOP_CENTER, 10000, 0, true, false)); + } + // Start inactivity check. + if (character.isPlayer() && // + ((((zone == BLUE_PEACE_ZONE) && (character.getTeam() == Team.BLUE)) || // + ((zone == RED_PEACE_ZONE) && (character.getTeam() == Team.RED))))) + { + startQuestTimer("KickPlayer" + character.getObjectId(), PVP_WORLD.getDoor(BLUE_DOOR_ID).isOpen() ? INACTIVITY_TIME * 60000 : (INACTIVITY_TIME * 60000) + (WAIT_TIME * 60000), null, character.getActingPlayer()); + } + } + return null; + } + + @Override + public String onExitZone(L2Character character, L2ZoneType zone) + { + if (character.isPlayer() && character.getActingPlayer().isOnCustomEvent()) + { + cancelQuestTimer("KickPlayer" + character.getObjectId(), null, character.getActingPlayer()); + } + return super.onExitZone(character, zone); + } + + private boolean canRegister(L2PcInstance player) + { + if (PLAYER_LIST.contains(player)) + { + player.sendMessage("You are already registered on this event."); + return false; + } + if (player.getLevel() < MINIMUM_PARTICIPANT_LEVEL) + { + player.sendMessage("Your level is too low to participate."); + return false; + } + if (player.getLevel() > MAXIMUM_PARTICIPANT_LEVEL) + { + player.sendMessage("Your level is too high to participate."); + return false; + } + if (player.isOnEvent() || (player.getBlockCheckerArena() > -1)) + { + player.sendMessage("You are already registered on an event."); + return false; + } + if (PLAYER_LIST.size() >= MAXIMUM_PARTICIPANT_COUNT) + { + player.sendMessage("There are too many players registered on the event."); + return false; + } + if (player.isFlyingMounted()) + { + player.sendMessage("You cannot register on the event while flying."); + return false; + } + if (player.isTransformed()) + { + player.sendMessage("You cannot register on the event while on a transformed state."); + return false; + } + if (!player.isInventoryUnder80(false)) + { + player.sendMessage("There are too many items in your inventory."); + player.sendMessage("Try removing some items."); + return false; + } + if ((player.getWeightPenalty() != 0)) + { + player.sendMessage("Your invetory weight has exceeded the normal limit."); + player.sendMessage("Try removing some items."); + return false; + } + if (player.isCursedWeaponEquipped() || (player.getReputation() < 0)) + { + player.sendMessage("People with bad reputation can't register."); + return false; + } + if (player.isInDuel()) + { + player.sendMessage("You cannot register while on a duel."); + return false; + } + if (player.isInOlympiadMode() || OlympiadManager.getInstance().isRegistered(player)) + { + player.sendMessage("You cannot participate while registered on the Olympiad."); + return false; + } + if (player.isInInstance()) + { + player.sendMessage("You cannot register while in an instance."); + return false; + } + if (player.isInSiege() || player.isInsideZone(ZoneId.SIEGE)) + { + player.sendMessage("You cannot register while on a siege."); + return false; + } + if (player.isFishing()) + { + player.sendMessage("You cannot register while fishing."); + return false; + } + return true; + } + + private void broadcastScreenMessageWithEffect(String message, int duration) + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage(message, ExShowScreenMessage.TOP_CENTER, duration * 1000, 0, true, true)); + } + + private void broadcastScreenMessage(String message, int duration) + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage(message, ExShowScreenMessage.TOP_CENTER, duration * 1000, 0, true, false)); + } + + private void broadcastScoreMessage() + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage("Blue: " + BLUE_SCORE + " - Red: " + RED_SCORE, ExShowScreenMessage.BOTTOM_RIGHT, 15000, 0, true, false)); + } + + private void addLogoutListener(L2PcInstance player) + { + player.addListener(new ConsumerEventListener(player, EventType.ON_PLAYER_LOGOUT, (OnPlayerLogout event) -> OnPlayerLogout(event), this)); + } + + private void addDeathListener(L2PcInstance player) + { + player.addListener(new ConsumerEventListener(player, EventType.ON_CREATURE_DEATH, (OnCreatureDeath event) -> onPlayerDeath(event), this)); + } + + private void removeListeners(L2PcInstance player) + { + for (AbstractEventListener listener : player.getListeners(EventType.ON_PLAYER_LOGOUT)) + { + if (listener.getOwner() == this) + { + listener.unregisterMe(); + } + } + for (AbstractEventListener listener : player.getListeners(EventType.ON_CREATURE_DEATH)) + { + if (listener.getOwner() == this) + { + listener.unregisterMe(); + } + } + } + + @RegisterEvent(EventType.ON_PLAYER_LOGOUT) + private void OnPlayerLogout(OnPlayerLogout event) + { + final L2PcInstance player = event.getActiveChar(); + if (player != null) + { + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + BLUE_TEAM.remove(player); + RED_TEAM.remove(player); + } + // If all players left instance end the event. + if (PLAYER_LIST.isEmpty()) + { + // Stop timers. + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Destroy world. + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + } + } + + @RegisterEvent(EventType.ON_CREATURE_DEATH) + public void onPlayerDeath(OnCreatureDeath event) + { + if (event.getTarget().isPlayer()) + { + final L2PcInstance killedPlayer = event.getTarget().getActingPlayer(); + final L2PcInstance killer = event.getAttacker().getActingPlayer(); + // Confirm Blue team kill. + if ((killer.getTeam() == Team.BLUE) && (killedPlayer.getTeam() == Team.RED)) + { + PLAYER_SCORES.put(killer, PLAYER_SCORES.get(killer) + 1); + BLUE_SCORE++; + broadcastScoreMessage(); + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.UPDATE, Util.sortByValue(PLAYER_SCORES))); + } + // Confirm Red team kill. + if ((killer.getTeam() == Team.RED) && (killedPlayer.getTeam() == Team.BLUE)) + { + PLAYER_SCORES.put(killer, PLAYER_SCORES.get(killer) + 1); + RED_SCORE++; + broadcastScoreMessage(); + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.UPDATE, Util.sortByValue(PLAYER_SCORES))); + } + // Auto release after 10 seconds. + startQuestTimer("ResurrectPlayer", 10000, null, killedPlayer); + } + } + + @Override + public boolean eventStart(L2PcInstance eventMaker) + { + if (EVENT_ACTIVE) + { + return false; + } + EVENT_ACTIVE = true; + + // Cancel timers. (In case event started immediately after another event finished.) + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Clear player lists. + PLAYER_LIST.clear(); + PLAYER_SCORES.clear(); + BLUE_TEAM.clear(); + RED_TEAM.clear(); + // Spawn event manager. + MANAGER_NPC_INSTANCE = addSpawn(MANAGER, MANAGER_SPAWN_LOC, false, REGISTRATION_TIME * 60000); + startQuestTimer("TeleportToArena", REGISTRATION_TIME * 60000, null, null); + // Send message to players. + Broadcast.toAllOnlinePlayers("TvT Event: Registration opened for " + REGISTRATION_TIME + " minutes."); + Broadcast.toAllOnlinePlayers("TvT Event: You can register at Giran TvT Event Manager."); + + return true; + } + + @Override + public boolean eventStop() + { + if (!EVENT_ACTIVE) + { + return false; + } + EVENT_ACTIVE = false; + + // Despawn event manager. + MANAGER_NPC_INSTANCE.deleteMe(); + // Cancel timers. + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Remove participants. + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setTeam(Team.NONE); + participant.setOnCustomEvent(false); + } + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + // Send message to players. + Broadcast.toAllOnlinePlayers("TvT Event: Event was canceled."); + return true; + } + + @Override + public boolean eventBypass(L2PcInstance activeChar, String bypass) + { + return false; + } + + public static void main(String[] args) + { + new TvT(); + } +} diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html new file mode 100644 index 0000000000..54bbd53443 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Need assistance?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html new file mode 100644 index 0000000000..6c9101990c --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Cancel your participation?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html new file mode 100644 index 0000000000..2b72e551d8 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
You are in combat, calm down...
+
+
+
+
+
+ + diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html new file mode 100644 index 0000000000..c5d7eb5d12 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Do you want to join the event?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html new file mode 100644 index 0000000000..5b21728486 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration canceled.
+
+
+
+
+
+ + diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html new file mode 100644 index 0000000000..2f3b31f9f6 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration failed.
+
+
+
+
+
+ + diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html new file mode 100644 index 0000000000..548a8a1750 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration successful!
+
+
+
+
+
+ + diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java index d17921338b..e06f9e07fd 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java @@ -63,19 +63,23 @@ public class AdminZone implements IAdminCommandHandler getGeoRegionXY(activeChar); activeChar.sendMessage("Closest Town: " + MapRegionManager.getInstance().getClosestTownName(activeChar)); - Location loc; - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CASTLE); - activeChar.sendMessage("TeleToLocation (Castle): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CLANHALL); - activeChar.sendMessage("TeleToLocation (ClanHall): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.SIEGEFLAG); - activeChar.sendMessage("TeleToLocation (SiegeFlag): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.TOWN); - activeChar.sendMessage("TeleToLocation (Town): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + // Prevent exit instance variable deletion. + if (!activeChar.isInInstance()) + { + Location loc; + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CASTLE); + activeChar.sendMessage("TeleToLocation (Castle): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CLANHALL); + activeChar.sendMessage("TeleToLocation (ClanHall): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.SIEGEFLAG); + activeChar.sendMessage("TeleToLocation (SiegeFlag): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.TOWN); + activeChar.sendMessage("TeleToLocation (Town): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + } } else if (actualCommand.equalsIgnoreCase("admin_zone_visual")) { diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/custom.xml b/L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/custom.xml index 5b2d3489b1..c9b6b84f6c 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/custom.xml +++ b/L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/custom.xml @@ -1,23 +1,5 @@ - - ELEMENTAL - FEMALE - - - - - - - - - - - - - - - ANIMAL MALE diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/tvt_event.xml b/L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/tvt_event.xml new file mode 100644 index 0000000000..a867441b79 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/tvt_event.xml @@ -0,0 +1,22 @@ + + + + HUMAN + MALE + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index ca78d727a7..469e35937a 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -674,6 +674,7 @@ public final class L2PcInstance extends L2Playable @SuppressWarnings("rawtypes") private volatile Map, AbstractEvent> _events; + private boolean _isOnCustomEvent = false; public boolean isSpawnProtected() { @@ -8150,7 +8151,12 @@ public final class L2PcInstance extends L2Playable return false; } - // Check if the attacker is in TvT and TvT is started + if (isOnCustomEvent() && (getTeam() == attacker.getTeam())) + { + return false; + } + + // CoC needs this check? if (isOnEvent()) { return true; @@ -13117,12 +13123,26 @@ public final class L2PcInstance extends L2Playable _canRevive = val; } + public boolean isOnCustomEvent() + { + return _isOnCustomEvent; + } + + public void setOnCustomEvent(boolean value) + { + _isOnCustomEvent = value; + } + /** * @return {@code true} if player is on event, {@code false} otherwise. */ @Override public boolean isOnEvent() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) @@ -13138,6 +13158,10 @@ public final class L2PcInstance extends L2Playable public boolean isBlockedFromExit() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) @@ -13153,6 +13177,10 @@ public final class L2PcInstance extends L2Playable public boolean isBlockedFromDeathPenalty() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java index c3686c67be..d1bb6ffa75 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java @@ -63,6 +63,10 @@ public class ConditionPlayerCanEscape extends Condition { canTeleport = false; } + else if (player.isOnCustomEvent()) + { + canTeleport = false; + } return (_val == canTeleport); } } \ No newline at end of file diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java index 4ed6708e7f..679e38bdb6 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java @@ -64,6 +64,11 @@ public class ConditionPlayerCanTransform extends Condition player.sendPacket(SystemMessageId.YOU_CANNOT_TRANSFORM_WHILE_RIDING_A_PET); canTransform = false; } + else if (player.isOnCustomEvent()) + { + player.sendMessage("You cannot transform while registered on an event."); + canTransform = false; + } return (_val == canTransform); } } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/Instance.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/Instance.java index 77c2468437..70464afd7c 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/Instance.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/Instance.java @@ -888,19 +888,22 @@ public final class Instance implements IIdentifiable, INamable */ public void onDeath(L2PcInstance player) { - // Send message - final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IF_YOU_ARE_NOT_RESURRECTED_WITHIN_S1_MINUTE_S_YOU_WILL_BE_EXPELLED_FROM_THE_INSTANT_ZONE); - sm.addInt(_template.getEjectTime()); - player.sendPacket(sm); - - // Start eject task - _ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.schedule(() -> + if (!player.isOnCustomEvent()) { - if (player.isDead()) + // Send message + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IF_YOU_ARE_NOT_RESURRECTED_WITHIN_S1_MINUTE_S_YOU_WILL_BE_EXPELLED_FROM_THE_INSTANT_ZONE); + sm.addInt(_template.getEjectTime()); + player.sendPacket(sm); + + // Start eject task + _ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.schedule(() -> { - ejectPlayer(player.getActingPlayer()); - } - }, _template.getEjectTime() * 60 * 1000)); // minutes to milliseconds + if (player.isDead()) + { + ejectPlayer(player.getActingPlayer()); + } + }, _template.getEjectTime() * 60 * 1000)); // minutes to milliseconds + } } /** diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java index f4fa7592ad..409678ea5a 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java @@ -365,6 +365,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl public Location getExitLocation(L2PcInstance player) { Location location = null; + switch (_exitLocationType) { case RANDOM: diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java index a5817ae1bf..23db544038 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java @@ -179,8 +179,8 @@ public enum ExIncomingPackets implements IIncomingPackets EX_BOOKMARK_PACKET(0x4E, ExBookmarkPacket::new, ConnectionState.IN_GAME), REQUEST_WITHDRAW_PREMIUM_ITEM(0x4F, RequestWithDrawPremiumItem::new, ConnectionState.IN_GAME), REQUEST_EX_JUMP(0x50, null, ConnectionState.IN_GAME), - REQUEST_EX_START_SHOW_CRATAE_CUBE_RANK(0x51, null, ConnectionState.IN_GAME), - REQUEST_EX_STOP_SHOW_CRATAE_CUBE_RANK(0x52, null, ConnectionState.IN_GAME), + REQUEST_EX_START_SHOW_CRATAE_CUBE_RANK(0x51, RequestStartShowKrateisCubeRank::new, ConnectionState.IN_GAME), + REQUEST_EX_STOP_SHOW_CRATAE_CUBE_RANK(0x52, RequestStopShowKrateisCubeRank::new, ConnectionState.IN_GAME), NOTIFY_START_MINI_GAME(0x53, null, ConnectionState.IN_GAME), REQUEST_EX_JOIN_DOMINION_WAR(0x54, null, ConnectionState.IN_GAME), REQUEST_EX_DOMINION_INFO(0x55, null, ConnectionState.IN_GAME), diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java index 6c7ebff02e..31e80f64fb 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java @@ -29,7 +29,10 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.entity.Castle; import com.l2jmobius.gameserver.model.entity.ClanHall; import com.l2jmobius.gameserver.model.entity.Fort; +import com.l2jmobius.gameserver.model.events.EventType; +import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; import com.l2jmobius.gameserver.model.instancezone.Instance; +import com.l2jmobius.gameserver.model.quest.Event; import com.l2jmobius.gameserver.model.residences.AbstractResidence; import com.l2jmobius.gameserver.model.residences.ResidenceFunctionType; import com.l2jmobius.gameserver.network.L2GameClient; @@ -92,6 +95,19 @@ public final class RequestRestartPoint implements IClientIncomingPacket return; } + // Custom event resurrection management. + if (activeChar.isOnCustomEvent()) + { + for (AbstractEventListener listener : activeChar.getListeners(EventType.ON_CREATURE_DEATH)) + { + if (listener.getOwner() instanceof Event) + { + ((Event) listener.getOwner()).notifyEvent("ResurrectPlayer", null, activeChar); + return; + } + } + } + final Castle castle = CastleManager.getInstance().getCastle(activeChar.getX(), activeChar.getY(), activeChar.getZ()); if ((castle != null) && castle.getSiege().isInProgress()) { diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java new file mode 100644 index 0000000000..d2213e55b6 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java @@ -0,0 +1,39 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.clientpackets; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; + +/** + * @author Mobius + */ +public class RequestStartShowKrateisCubeRank implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return false; + } + + @Override + public void run(L2GameClient client) + { + // TODO: Implement. + System.out.println("RequestStartShowKrateisCubeRank"); + } +} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java new file mode 100644 index 0000000000..51ca3ea99b --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java @@ -0,0 +1,39 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.clientpackets; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; + +/** + * @author Mobius + */ +public class RequestStopShowKrateisCubeRank implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return false; + } + + @Override + public void run(L2GameClient client) + { + // TODO: Implement. + System.out.println("RequestStopShowKrateisCubeRank"); + } +} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java new file mode 100644 index 0000000000..57547b985e --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java @@ -0,0 +1,41 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.serverpackets; + +import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.network.OutgoingPackets; + +/** + * @author Mobius + */ +public class ExPVPMatchCCMyRecord implements IClientOutgoingPacket +{ + private final int _points; + + public ExPVPMatchCCMyRecord(int points) + { + _points = points; + } + + @Override + public boolean write(PacketWriter packet) + { + OutgoingPackets.EX_PVP_MATCH_CCMY_RECORD.writeId(packet); + packet.writeD(_points); + return true; + } +} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java new file mode 100644 index 0000000000..b199a7443c --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java @@ -0,0 +1,57 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.serverpackets; + +import java.util.Map; +import java.util.Map.Entry; + +import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.network.OutgoingPackets; + +/** + * @author Mobius + */ +public class ExPVPMatchCCRecord implements IClientOutgoingPacket +{ + public static final int INITIALIZE = 0; + public static final int UPDATE = 1; + public static final int FINISH = 2; + + private final int _state; + private final Map _players; + + public ExPVPMatchCCRecord(int state, Map players) + { + _state = state; + _players = players; + } + + @Override + public boolean write(PacketWriter packet) + { + OutgoingPackets.EX_PVP_MATCH_CCRECORD.writeId(packet); + packet.writeD(_state); // 0 - initialize, 1 - update, 2 - finish + packet.writeD(_players.size()); + for (Entry entry : _players.entrySet()) + { + packet.writeS(entry.getKey().getName()); + packet.writeD(entry.getValue()); + } + return true; + } +} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/util/Util.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/util/Util.java index e551224ab8..850ae469e6 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/util/Util.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/util/Util.java @@ -31,6 +31,8 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; import java.util.logging.Logger; import com.l2jmobius.Config; @@ -788,4 +790,15 @@ public final class Util return (input < min) ? min : (input > max) ? max : input; } + /** + * Short an map by its integer values. + * @param unsortedMap + * @return + */ + public static Map sortByValue(Map unsortedMap) + { + Map sortedMap = new TreeMap<>(new ValueComparator(unsortedMap)); + sortedMap.putAll(unsortedMap); + return sortedMap; + } } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/util/ValueComparator.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/util/ValueComparator.java new file mode 100644 index 0000000000..32c494218d --- /dev/null +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/util/ValueComparator.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.util; + +import java.util.Comparator; +import java.util.Map; + +/** + * @author Mobius + */ +public class ValueComparator implements Comparator +{ + Map _map; + + public ValueComparator(Map map) + { + _map = map; + } + + @SuppressWarnings( + { + "rawtypes", + "unchecked" + }) + @Override + public int compare(Object keyA, Object keyB) + { + Comparable valueA = (Comparable) _map.get(keyA); + Comparable valueB = (Comparable) _map.get(keyB); + return valueB.compareTo(valueA); + } +} diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/instances/custom/coliseum.xml b/L2J_Mobius_3.0_Helios/dist/game/data/instances/custom/coliseum.xml index 6c8eb9385c..27a7498e9b 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/instances/custom/coliseum.xml +++ b/L2J_Mobius_3.0_Helios/dist/game/data/instances/custom/coliseum.xml @@ -1,9 +1,23 @@ + diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java new file mode 100644 index 0000000000..f31b220207 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java @@ -0,0 +1,871 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package custom.events.TeamVsTeam; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.l2jmobius.gameserver.enums.CategoryType; +import com.l2jmobius.gameserver.enums.PartyDistributionType; +import com.l2jmobius.gameserver.enums.Team; +import com.l2jmobius.gameserver.instancemanager.InstanceManager; +import com.l2jmobius.gameserver.instancemanager.ZoneManager; +import com.l2jmobius.gameserver.model.L2CommandChannel; +import com.l2jmobius.gameserver.model.L2Party; +import com.l2jmobius.gameserver.model.Location; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.L2Npc; +import com.l2jmobius.gameserver.model.actor.L2Summon; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.events.EventType; +import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent; +import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDeath; +import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout; +import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; +import com.l2jmobius.gameserver.model.events.listeners.ConsumerEventListener; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.SkillHolder; +import com.l2jmobius.gameserver.model.instancezone.Instance; +import com.l2jmobius.gameserver.model.instancezone.InstanceTemplate; +import com.l2jmobius.gameserver.model.olympiad.OlympiadManager; +import com.l2jmobius.gameserver.model.quest.Event; +import com.l2jmobius.gameserver.model.quest.QuestTimer; +import com.l2jmobius.gameserver.model.skills.CommonSkill; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.skills.SkillCaster; +import com.l2jmobius.gameserver.model.zone.L2ZoneType; +import com.l2jmobius.gameserver.model.zone.ZoneId; +import com.l2jmobius.gameserver.network.serverpackets.ExPVPMatchCCRecord; +import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; +import com.l2jmobius.gameserver.util.Broadcast; +import com.l2jmobius.gameserver.util.Util; + +/** + * Team vs Team event. + * @author Mobius + */ +public class TvT extends Event +{ + // NPC + private static final int MANAGER = 70010; + // Skills + private static final SkillHolder KNIGHT = new SkillHolder(15648, 1); // Knight's Harmony (Adventurer) + private static final SkillHolder WARRIOR = new SkillHolder(15649, 1); // Warrior's Harmony (Adventurer) + private static final SkillHolder WIZARD = new SkillHolder(15650, 1); // Wizard's Harmony (Adventurer) + private static final SkillHolder[] GROUP_BUFFS = + { + new SkillHolder(15642, 1), // Horn Melody (Adventurer) + new SkillHolder(15643, 1), // Drum Melody (Adventurer) + new SkillHolder(15644, 1), // Pipe Organ Melody (Adventurer) + new SkillHolder(15645, 1), // Guitar Melody (Adventurer) + new SkillHolder(15646, 1), // Harp Melody (Adventurer) + new SkillHolder(15647, 1), // Lute Melody (Adventurer) + new SkillHolder(15651, 1), // Prevailing Sonata (Adventurer) + new SkillHolder(15652, 1), // Daring Sonata (Adventurer) + new SkillHolder(15653, 1), // Refreshing Sonata (Adventurer) + }; + // Others + private static final int INSTANCE_ID = 3049; + private static final int BLUE_DOOR_ID = 24190002; + private static final int RED_DOOR_ID = 24190003; + private static final Location MANAGER_SPAWN_LOC = new Location(83425, 148585, -3406, 32938); + private static final Location BLUE_BUFFER_SPAWN_LOC = new Location(147450, 46913, -3400, 49000); + private static final Location RED_BUFFER_SPAWN_LOC = new Location(151545, 46528, -3400, 16000); + private static final Location BLUE_SPAWN_LOC = new Location(147447, 46722, -3416); + private static final Location RED_SPAWN_LOC = new Location(151536, 46722, -3416); + private static final L2ZoneType BLUE_PEACE_ZONE = ZoneManager.getInstance().getZoneByName("colosseum_peace1"); + private static final L2ZoneType RED_PEACE_ZONE = ZoneManager.getInstance().getZoneByName("colosseum_peace2"); + // Settings + private static final int REGISTRATION_TIME = 10; // Minutes + private static final int WAIT_TIME = 1; // Minutes + private static final int FIGHT_TIME = 20; // Minutes + private static final int INACTIVITY_TIME = 2; // Minutes + private static final int MINIMUM_PARTICIPANT_LEVEL = 85; + private static final int MAXIMUM_PARTICIPANT_LEVEL = 200; + private static final int MINIMUM_PARTICIPANT_COUNT = 4; + private static final int MAXIMUM_PARTICIPANT_COUNT = 24; // Scoreboard has 25 slots + private static final int PARTY_MEMBER_COUNT = 7; + private static final ItemHolder REWARD = new ItemHolder(57, 1000000); // Adena + // Misc + private static final Map PLAYER_SCORES = new ConcurrentHashMap<>(); + private static final List PLAYER_LIST = new ArrayList<>(); + private static final List BLUE_TEAM = new ArrayList<>(); + private static final List RED_TEAM = new ArrayList<>(); + private static volatile int BLUE_SCORE; + private static volatile int RED_SCORE; + private static Instance PVP_WORLD = null; + private static L2Npc MANAGER_NPC_INSTANCE = null; + private static boolean EVENT_ACTIVE = false; + + private TvT() + { + addTalkId(MANAGER); + addFirstTalkId(MANAGER); + addExitZoneId(BLUE_PEACE_ZONE.getId(), RED_PEACE_ZONE.getId()); + addEnterZoneId(BLUE_PEACE_ZONE.getId(), RED_PEACE_ZONE.getId()); + } + + @Override + public String onAdvEvent(String event, L2Npc npc, L2PcInstance player) + { + if (!EVENT_ACTIVE) + { + return null; + } + + String htmltext = null; + switch (event) + { + case "Participate": + { + if (canRegister(player)) + { + PLAYER_LIST.add(player); + PLAYER_SCORES.put(player, 0); + player.setOnCustomEvent(true); + addLogoutListener(player); + htmltext = "registration-success.html"; + } + else + { + htmltext = "registration-failed.html"; + } + break; + } + case "CancelParticipation": + { + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + removeListeners(player); + player.setOnCustomEvent(false); + htmltext = "registration-canceled.html"; + break; + } + case "BuffHeal": + { + if (player.isOnCustomEvent() || player.isGM()) + { + if (player.isInCombat()) + { + htmltext = "manager-combat.html"; + } + else + { + for (SkillHolder holder : GROUP_BUFFS) + { + SkillCaster.triggerCast(npc, player, holder.getSkill()); + } + if (player.isMageClass()) + { + SkillCaster.triggerCast(npc, player, WIZARD.getSkill()); + } + else if (player.isInCategory(CategoryType.KNIGHT_GROUP)) + { + SkillCaster.triggerCast(npc, player, KNIGHT.getSkill()); + } + else + { + SkillCaster.triggerCast(npc, player, WARRIOR.getSkill()); + } + player.setCurrentHp(player.getMaxHp()); + player.setCurrentMp(player.getMaxMp()); + player.setCurrentCp(player.getMaxCp()); + } + } + break; + } + case "TeleportToArena": + { + // Remove offline players. + for (L2PcInstance participant : PLAYER_LIST) + { + if ((participant == null) || (participant.isOnlineInt() != 1)) + { + PLAYER_LIST.remove(participant); + PLAYER_SCORES.remove(participant); + } + } + // Check if there are enough players to start the event. + if (PLAYER_LIST.size() < MINIMUM_PARTICIPANT_COUNT) + { + Broadcast.toAllOnlinePlayers("TvT Event: Event was canceled, not enough participants."); + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setOnCustomEvent(false); + } + EVENT_ACTIVE = false; + return null; + } + // Create the instance. + final InstanceManager manager = InstanceManager.getInstance(); + final InstanceTemplate template = manager.getInstanceTemplate(INSTANCE_ID); + PVP_WORLD = manager.createInstance(template, null); + // Randomize player list and separate teams. + Collections.shuffle(PLAYER_LIST); + boolean team = getRandomBoolean(); // If teams are not even, randomize where extra player goes. + for (L2PcInstance participant : PLAYER_LIST) + { + if (team) + { + BLUE_TEAM.add(participant); + PVP_WORLD.addAllowed(participant); + participant.leaveParty(); + participant.setTeam(Team.BLUE); + participant.teleToLocation(BLUE_SPAWN_LOC, PVP_WORLD); + team = false; + } + else + { + RED_TEAM.add(participant); + PVP_WORLD.addAllowed(participant); + participant.leaveParty(); + participant.setTeam(Team.RED); + participant.teleToLocation(RED_SPAWN_LOC, PVP_WORLD); + team = true; + } + addDeathListener(participant); + } + // Make Blue CC. + if (BLUE_TEAM.size() > 1) + { + L2CommandChannel blueCC = null; + L2Party lastBlueParty = null; + int blueParticipantCounter = 0; + for (L2PcInstance participant : BLUE_TEAM) + { + blueParticipantCounter++; + if (blueParticipantCounter == 1) + { + lastBlueParty = new L2Party(participant, PartyDistributionType.FINDERS_KEEPERS); + participant.joinParty(lastBlueParty); + if (BLUE_TEAM.size() > PARTY_MEMBER_COUNT) + { + if (blueCC == null) + { + blueCC = new L2CommandChannel(participant); + } + else + { + blueCC.addParty(lastBlueParty); + } + } + } + else if (lastBlueParty != null) + { + participant.joinParty(lastBlueParty); + } + if (blueParticipantCounter == PARTY_MEMBER_COUNT) + { + blueParticipantCounter = 0; + } + } + } + // Make Red CC. + if (RED_TEAM.size() > 1) + { + L2CommandChannel redCC = null; + L2Party lastRedParty = null; + int redParticipantCounter = 0; + for (L2PcInstance participant : RED_TEAM) + { + redParticipantCounter++; + if (redParticipantCounter == 1) + { + lastRedParty = new L2Party(participant, PartyDistributionType.FINDERS_KEEPERS); + participant.joinParty(lastRedParty); + if (RED_TEAM.size() > PARTY_MEMBER_COUNT) + { + if (redCC == null) + { + redCC = new L2CommandChannel(participant); + } + else + { + redCC.addParty(lastRedParty); + } + } + } + else if (lastRedParty != null) + { + participant.joinParty(lastRedParty); + } + if (redParticipantCounter == PARTY_MEMBER_COUNT) + { + redParticipantCounter = 0; + } + } + } + // Spawn managers. + addSpawn(MANAGER, BLUE_BUFFER_SPAWN_LOC, false, (WAIT_TIME + FIGHT_TIME) * 60000, false, PVP_WORLD.getId()); + addSpawn(MANAGER, RED_BUFFER_SPAWN_LOC, false, (WAIT_TIME + FIGHT_TIME) * 60000, false, PVP_WORLD.getId()); + // Initialize scores. + BLUE_SCORE = 0; + RED_SCORE = 0; + // Initialize scoreboard. + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.INITIALIZE, Util.sortByValue(PLAYER_SCORES))); + // Schedule start. + startQuestTimer("5", (WAIT_TIME * 60000) - 5000, null, null); + startQuestTimer("4", (WAIT_TIME * 60000) - 4000, null, null); + startQuestTimer("3", (WAIT_TIME * 60000) - 3000, null, null); + startQuestTimer("2", (WAIT_TIME * 60000) - 2000, null, null); + startQuestTimer("1", (WAIT_TIME * 60000) - 1000, null, null); + startQuestTimer("StartFight", WAIT_TIME * 60000, null, null); + break; + } + case "StartFight": + { + // Open doors. + openDoor(BLUE_DOOR_ID, PVP_WORLD.getId()); + openDoor(RED_DOOR_ID, PVP_WORLD.getId()); + // Send message. + broadcastScreenMessageWithEffect("The fight has began!", 5); + // Schedule finish. + startQuestTimer("10", (FIGHT_TIME * 60000) - 10000, null, null); + startQuestTimer("9", (FIGHT_TIME * 60000) - 9000, null, null); + startQuestTimer("8", (FIGHT_TIME * 60000) - 8000, null, null); + startQuestTimer("7", (FIGHT_TIME * 60000) - 7000, null, null); + startQuestTimer("6", (FIGHT_TIME * 60000) - 6000, null, null); + startQuestTimer("5", (FIGHT_TIME * 60000) - 5000, null, null); + startQuestTimer("4", (FIGHT_TIME * 60000) - 4000, null, null); + startQuestTimer("3", (FIGHT_TIME * 60000) - 3000, null, null); + startQuestTimer("2", (FIGHT_TIME * 60000) - 2000, null, null); + startQuestTimer("1", (FIGHT_TIME * 60000) - 1000, null, null); + startQuestTimer("EndFight", FIGHT_TIME * 60000, null, null); + break; + } + case "EndFight": + { + // Close doors. + closeDoor(BLUE_DOOR_ID, PVP_WORLD.getId()); + closeDoor(RED_DOOR_ID, PVP_WORLD.getId()); + // Disable players. + for (L2PcInstance participant : PLAYER_LIST) + { + participant.setIsInvul(true); + participant.setIsImmobilized(true); + participant.disableAllSkills(); + for (L2Summon summon : participant.getServitors().values()) + { + summon.setIsInvul(true); + summon.setIsImmobilized(true); + summon.disableAllSkills(); + } + } + // Make sure noone is dead. + for (L2PcInstance participant : PLAYER_LIST) + { + if (participant.isDead()) + { + participant.doRevive(); + } + } + // Team Blue wins. + if (BLUE_SCORE > RED_SCORE) + { + final Skill skill = CommonSkill.FIREWORK.getSkill(); + broadcastScreenMessageWithEffect("Team Blue won the event!", 7); + for (L2PcInstance participant : BLUE_TEAM) + { + if ((participant != null) && (participant.getInstanceWorld() == PVP_WORLD)) + { + participant.broadcastPacket(new MagicSkillUse(participant, participant, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay())); + participant.broadcastSocialAction(3); + giveItems(participant, REWARD); + } + } + } + // Team Red wins. + else if (RED_SCORE > BLUE_SCORE) + { + final Skill skill = CommonSkill.FIREWORK.getSkill(); + broadcastScreenMessageWithEffect("Team Red won the event!", 7); + for (L2PcInstance participant : RED_TEAM) + { + if ((participant != null) && (participant.getInstanceWorld() == PVP_WORLD)) + { + participant.broadcastPacket(new MagicSkillUse(participant, participant, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay())); + participant.broadcastSocialAction(3); + giveItems(participant, REWARD); + } + } + } + // Tie. + else + { + broadcastScreenMessageWithEffect("The event ended with a tie!", 7); + for (L2PcInstance participant : PLAYER_LIST) + { + participant.broadcastSocialAction(13); + } + } + startQuestTimer("ScoreBoard", 3500, null, null); + startQuestTimer("TeleportOut", 7000, null, null); + break; + } + case "ScoreBoard": + { + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.FINISH, Util.sortByValue(PLAYER_SCORES))); + break; + } + case "TeleportOut": + { + // Remove event listeners. + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setTeam(Team.NONE); + participant.setOnCustomEvent(false); + participant.leaveParty(); + } + // Destroy world. + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + // Enable players. + for (L2PcInstance participant : PLAYER_LIST) + { + participant.setIsInvul(false); + participant.setIsImmobilized(false); + participant.enableAllSkills(); + for (L2Summon summon : participant.getServitors().values()) + { + summon.setIsInvul(true); + summon.setIsImmobilized(true); + summon.disableAllSkills(); + } + } + EVENT_ACTIVE = false; + break; + } + case "ResurrectPlayer": + { + if (player.isDead() && player.isOnCustomEvent()) + { + if (BLUE_TEAM.contains(player)) + { + player.setIsPendingRevive(true); + player.teleToLocation(BLUE_SPAWN_LOC, false, PVP_WORLD); + } + else if (RED_TEAM.contains(player)) + { + player.setIsPendingRevive(true); + player.teleToLocation(RED_SPAWN_LOC, false, PVP_WORLD); + } + } + break; + } + case "10": + { + broadcastScreenMessage("10", 4); + break; + } + case "9": + { + broadcastScreenMessage("9", 4); + break; + } + case "8": + { + broadcastScreenMessage("8", 4); + break; + } + case "7": + { + broadcastScreenMessage("7", 4); + break; + } + case "6": + { + broadcastScreenMessage("6", 4); + break; + } + case "5": + { + broadcastScreenMessage("5", 4); + break; + } + case "4": + { + broadcastScreenMessage("4", 4); + break; + } + case "3": + { + broadcastScreenMessage("3", 4); + break; + } + case "2": + { + broadcastScreenMessage("2", 4); + break; + } + case "1": + { + broadcastScreenMessage("1", 4); + break; + } + } + // Activity timer. + if (event.startsWith("KickPlayer") && (player != null) && (player.getInstanceWorld() == PVP_WORLD)) + { + player.setTeam(Team.NONE); + PVP_WORLD.ejectPlayer(player); + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + BLUE_TEAM.remove(player); + RED_TEAM.remove(player); + player.setOnCustomEvent(false); + removeListeners(player); + player.sendMessage("You have been kicked for been inactive."); + if (PVP_WORLD != null) + { + broadcastScreenMessageWithEffect("Player " + player.getName() + " was kicked for been inactive.", 7); + } + } + return htmltext; + } + + @Override + public String onFirstTalk(L2Npc npc, L2PcInstance player) + { + // Event not active. + if (!EVENT_ACTIVE) + { + return null; + } + + // Player has already registered. + if (PLAYER_LIST.contains(player)) + { + // Npc is in instance. + if (npc.getInstanceWorld() != null) + { + return "manager-buffheal.html"; + } + return "manager-cancel.html"; + } + // Player is not registered. + return "manager-register.html"; + } + + @Override + public String onEnterZone(L2Character character, L2ZoneType zone) + { + if (character.isPlayable() && character.getActingPlayer().isOnCustomEvent()) + { + // Kick enemy players. + if ((zone == BLUE_PEACE_ZONE) && (character.getTeam() == Team.RED)) + { + character.teleToLocation(RED_SPAWN_LOC, PVP_WORLD); + character.getActingPlayer().sendPacket(new ExShowScreenMessage("Entering the enemy headquarters is prohibited!", ExShowScreenMessage.TOP_CENTER, 10000, 0, true, false)); + } + if ((zone == RED_PEACE_ZONE) && (character.getTeam() == Team.BLUE)) + { + character.teleToLocation(BLUE_SPAWN_LOC, PVP_WORLD); + character.getActingPlayer().sendPacket(new ExShowScreenMessage("Entering the enemy headquarters is prohibited!", ExShowScreenMessage.TOP_CENTER, 10000, 0, true, false)); + } + // Start inactivity check. + if (character.isPlayer() && // + ((((zone == BLUE_PEACE_ZONE) && (character.getTeam() == Team.BLUE)) || // + ((zone == RED_PEACE_ZONE) && (character.getTeam() == Team.RED))))) + { + startQuestTimer("KickPlayer" + character.getObjectId(), PVP_WORLD.getDoor(BLUE_DOOR_ID).isOpen() ? INACTIVITY_TIME * 60000 : (INACTIVITY_TIME * 60000) + (WAIT_TIME * 60000), null, character.getActingPlayer()); + } + } + return null; + } + + @Override + public String onExitZone(L2Character character, L2ZoneType zone) + { + if (character.isPlayer() && character.getActingPlayer().isOnCustomEvent()) + { + cancelQuestTimer("KickPlayer" + character.getObjectId(), null, character.getActingPlayer()); + } + return super.onExitZone(character, zone); + } + + private boolean canRegister(L2PcInstance player) + { + if (PLAYER_LIST.contains(player)) + { + player.sendMessage("You are already registered on this event."); + return false; + } + if (player.getLevel() < MINIMUM_PARTICIPANT_LEVEL) + { + player.sendMessage("Your level is too low to participate."); + return false; + } + if (player.getLevel() > MAXIMUM_PARTICIPANT_LEVEL) + { + player.sendMessage("Your level is too high to participate."); + return false; + } + if (player.isOnEvent() || (player.getBlockCheckerArena() > -1)) + { + player.sendMessage("You are already registered on an event."); + return false; + } + if (PLAYER_LIST.size() >= MAXIMUM_PARTICIPANT_COUNT) + { + player.sendMessage("There are too many players registered on the event."); + return false; + } + if (player.isFlyingMounted()) + { + player.sendMessage("You cannot register on the event while flying."); + return false; + } + if (player.isTransformed()) + { + player.sendMessage("You cannot register on the event while on a transformed state."); + return false; + } + if (!player.isInventoryUnder80(false)) + { + player.sendMessage("There are too many items in your inventory."); + player.sendMessage("Try removing some items."); + return false; + } + if ((player.getWeightPenalty() != 0)) + { + player.sendMessage("Your invetory weight has exceeded the normal limit."); + player.sendMessage("Try removing some items."); + return false; + } + if (player.isCursedWeaponEquipped() || (player.getReputation() < 0)) + { + player.sendMessage("People with bad reputation can't register."); + return false; + } + if (player.isInDuel()) + { + player.sendMessage("You cannot register while on a duel."); + return false; + } + if (player.isInOlympiadMode() || OlympiadManager.getInstance().isRegistered(player)) + { + player.sendMessage("You cannot participate while registered on the Olympiad."); + return false; + } + if (player.isInInstance()) + { + player.sendMessage("You cannot register while in an instance."); + return false; + } + if (player.isInSiege() || player.isInsideZone(ZoneId.SIEGE)) + { + player.sendMessage("You cannot register while on a siege."); + return false; + } + if (player.isFishing()) + { + player.sendMessage("You cannot register while fishing."); + return false; + } + return true; + } + + private void broadcastScreenMessageWithEffect(String message, int duration) + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage(message, ExShowScreenMessage.TOP_CENTER, duration * 1000, 0, true, true)); + } + + private void broadcastScreenMessage(String message, int duration) + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage(message, ExShowScreenMessage.TOP_CENTER, duration * 1000, 0, true, false)); + } + + private void broadcastScoreMessage() + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage("Blue: " + BLUE_SCORE + " - Red: " + RED_SCORE, ExShowScreenMessage.BOTTOM_RIGHT, 15000, 0, true, false)); + } + + private void addLogoutListener(L2PcInstance player) + { + player.addListener(new ConsumerEventListener(player, EventType.ON_PLAYER_LOGOUT, (OnPlayerLogout event) -> OnPlayerLogout(event), this)); + } + + private void addDeathListener(L2PcInstance player) + { + player.addListener(new ConsumerEventListener(player, EventType.ON_CREATURE_DEATH, (OnCreatureDeath event) -> onPlayerDeath(event), this)); + } + + private void removeListeners(L2PcInstance player) + { + for (AbstractEventListener listener : player.getListeners(EventType.ON_PLAYER_LOGOUT)) + { + if (listener.getOwner() == this) + { + listener.unregisterMe(); + } + } + for (AbstractEventListener listener : player.getListeners(EventType.ON_CREATURE_DEATH)) + { + if (listener.getOwner() == this) + { + listener.unregisterMe(); + } + } + } + + @RegisterEvent(EventType.ON_PLAYER_LOGOUT) + private void OnPlayerLogout(OnPlayerLogout event) + { + final L2PcInstance player = event.getActiveChar(); + if (player != null) + { + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + BLUE_TEAM.remove(player); + RED_TEAM.remove(player); + } + // If all players left instance end the event. + if (PLAYER_LIST.isEmpty()) + { + // Stop timers. + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Destroy world. + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + } + } + + @RegisterEvent(EventType.ON_CREATURE_DEATH) + public void onPlayerDeath(OnCreatureDeath event) + { + if (event.getTarget().isPlayer()) + { + final L2PcInstance killedPlayer = event.getTarget().getActingPlayer(); + final L2PcInstance killer = event.getAttacker().getActingPlayer(); + // Confirm Blue team kill. + if ((killer.getTeam() == Team.BLUE) && (killedPlayer.getTeam() == Team.RED)) + { + PLAYER_SCORES.put(killer, PLAYER_SCORES.get(killer) + 1); + BLUE_SCORE++; + broadcastScoreMessage(); + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.UPDATE, Util.sortByValue(PLAYER_SCORES))); + } + // Confirm Red team kill. + if ((killer.getTeam() == Team.RED) && (killedPlayer.getTeam() == Team.BLUE)) + { + PLAYER_SCORES.put(killer, PLAYER_SCORES.get(killer) + 1); + RED_SCORE++; + broadcastScoreMessage(); + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.UPDATE, Util.sortByValue(PLAYER_SCORES))); + } + // Auto release after 10 seconds. + startQuestTimer("ResurrectPlayer", 10000, null, killedPlayer); + } + } + + @Override + public boolean eventStart(L2PcInstance eventMaker) + { + if (EVENT_ACTIVE) + { + return false; + } + EVENT_ACTIVE = true; + + // Cancel timers. (In case event started immediately after another event finished.) + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Clear player lists. + PLAYER_LIST.clear(); + PLAYER_SCORES.clear(); + BLUE_TEAM.clear(); + RED_TEAM.clear(); + // Spawn event manager. + MANAGER_NPC_INSTANCE = addSpawn(MANAGER, MANAGER_SPAWN_LOC, false, REGISTRATION_TIME * 60000); + startQuestTimer("TeleportToArena", REGISTRATION_TIME * 60000, null, null); + // Send message to players. + Broadcast.toAllOnlinePlayers("TvT Event: Registration opened for " + REGISTRATION_TIME + " minutes."); + Broadcast.toAllOnlinePlayers("TvT Event: You can register at Giran TvT Event Manager."); + + return true; + } + + @Override + public boolean eventStop() + { + if (!EVENT_ACTIVE) + { + return false; + } + EVENT_ACTIVE = false; + + // Despawn event manager. + MANAGER_NPC_INSTANCE.deleteMe(); + // Cancel timers. + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Remove participants. + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setTeam(Team.NONE); + participant.setOnCustomEvent(false); + } + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + // Send message to players. + Broadcast.toAllOnlinePlayers("TvT Event: Event was canceled."); + return true; + } + + @Override + public boolean eventBypass(L2PcInstance activeChar, String bypass) + { + return false; + } + + public static void main(String[] args) + { + new TvT(); + } +} diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html new file mode 100644 index 0000000000..54bbd53443 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Need assistance?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html new file mode 100644 index 0000000000..6c9101990c --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Cancel your participation?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html new file mode 100644 index 0000000000..2b72e551d8 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
You are in combat, calm down...
+
+
+
+
+
+ + diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html new file mode 100644 index 0000000000..c5d7eb5d12 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Do you want to join the event?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html new file mode 100644 index 0000000000..5b21728486 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration canceled.
+
+
+
+
+
+ + diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html new file mode 100644 index 0000000000..2f3b31f9f6 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration failed.
+
+
+
+
+
+ + diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html new file mode 100644 index 0000000000..548a8a1750 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration successful!
+
+
+
+
+
+ + diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java index d17921338b..e06f9e07fd 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java @@ -63,19 +63,23 @@ public class AdminZone implements IAdminCommandHandler getGeoRegionXY(activeChar); activeChar.sendMessage("Closest Town: " + MapRegionManager.getInstance().getClosestTownName(activeChar)); - Location loc; - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CASTLE); - activeChar.sendMessage("TeleToLocation (Castle): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CLANHALL); - activeChar.sendMessage("TeleToLocation (ClanHall): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.SIEGEFLAG); - activeChar.sendMessage("TeleToLocation (SiegeFlag): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.TOWN); - activeChar.sendMessage("TeleToLocation (Town): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + // Prevent exit instance variable deletion. + if (!activeChar.isInInstance()) + { + Location loc; + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CASTLE); + activeChar.sendMessage("TeleToLocation (Castle): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CLANHALL); + activeChar.sendMessage("TeleToLocation (ClanHall): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.SIEGEFLAG); + activeChar.sendMessage("TeleToLocation (SiegeFlag): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.TOWN); + activeChar.sendMessage("TeleToLocation (Town): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + } } else if (actualCommand.equalsIgnoreCase("admin_zone_visual")) { diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/stats/npcs/custom/custom.xml b/L2J_Mobius_3.0_Helios/dist/game/data/stats/npcs/custom/custom.xml index 5b2d3489b1..c9b6b84f6c 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/stats/npcs/custom/custom.xml +++ b/L2J_Mobius_3.0_Helios/dist/game/data/stats/npcs/custom/custom.xml @@ -1,23 +1,5 @@ - - ELEMENTAL - FEMALE - - - - - - - - - - - - - - - ANIMAL MALE diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/stats/npcs/custom/tvt_event.xml b/L2J_Mobius_3.0_Helios/dist/game/data/stats/npcs/custom/tvt_event.xml new file mode 100644 index 0000000000..a867441b79 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/stats/npcs/custom/tvt_event.xml @@ -0,0 +1,22 @@ + + + + HUMAN + MALE + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 201dd8931f..3abd154e10 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -676,6 +676,7 @@ public final class L2PcInstance extends L2Playable @SuppressWarnings("rawtypes") private volatile Map, AbstractEvent> _events; + private boolean _isOnCustomEvent = false; public boolean isSpawnProtected() { @@ -8152,7 +8153,12 @@ public final class L2PcInstance extends L2Playable return false; } - // Check if the attacker is in TvT and TvT is started + if (isOnCustomEvent() && (getTeam() == attacker.getTeam())) + { + return false; + } + + // CoC needs this check? if (isOnEvent()) { return true; @@ -13128,12 +13134,26 @@ public final class L2PcInstance extends L2Playable _canRevive = val; } + public boolean isOnCustomEvent() + { + return _isOnCustomEvent; + } + + public void setOnCustomEvent(boolean value) + { + _isOnCustomEvent = value; + } + /** * @return {@code true} if player is on event, {@code false} otherwise. */ @Override public boolean isOnEvent() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) @@ -13149,6 +13169,10 @@ public final class L2PcInstance extends L2Playable public boolean isBlockedFromExit() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) @@ -13164,6 +13188,10 @@ public final class L2PcInstance extends L2Playable public boolean isBlockedFromDeathPenalty() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java index c3686c67be..d1bb6ffa75 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java @@ -63,6 +63,10 @@ public class ConditionPlayerCanEscape extends Condition { canTeleport = false; } + else if (player.isOnCustomEvent()) + { + canTeleport = false; + } return (_val == canTeleport); } } \ No newline at end of file diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java index 4ed6708e7f..679e38bdb6 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java @@ -64,6 +64,11 @@ public class ConditionPlayerCanTransform extends Condition player.sendPacket(SystemMessageId.YOU_CANNOT_TRANSFORM_WHILE_RIDING_A_PET); canTransform = false; } + else if (player.isOnCustomEvent()) + { + player.sendMessage("You cannot transform while registered on an event."); + canTransform = false; + } return (_val == canTransform); } } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/Instance.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/Instance.java index 77c2468437..70464afd7c 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/Instance.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/Instance.java @@ -888,19 +888,22 @@ public final class Instance implements IIdentifiable, INamable */ public void onDeath(L2PcInstance player) { - // Send message - final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IF_YOU_ARE_NOT_RESURRECTED_WITHIN_S1_MINUTE_S_YOU_WILL_BE_EXPELLED_FROM_THE_INSTANT_ZONE); - sm.addInt(_template.getEjectTime()); - player.sendPacket(sm); - - // Start eject task - _ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.schedule(() -> + if (!player.isOnCustomEvent()) { - if (player.isDead()) + // Send message + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IF_YOU_ARE_NOT_RESURRECTED_WITHIN_S1_MINUTE_S_YOU_WILL_BE_EXPELLED_FROM_THE_INSTANT_ZONE); + sm.addInt(_template.getEjectTime()); + player.sendPacket(sm); + + // Start eject task + _ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.schedule(() -> { - ejectPlayer(player.getActingPlayer()); - } - }, _template.getEjectTime() * 60 * 1000)); // minutes to milliseconds + if (player.isDead()) + { + ejectPlayer(player.getActingPlayer()); + } + }, _template.getEjectTime() * 60 * 1000)); // minutes to milliseconds + } } /** diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java index f4fa7592ad..409678ea5a 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java @@ -365,6 +365,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl public Location getExitLocation(L2PcInstance player) { Location location = null; + switch (_exitLocationType) { case RANDOM: diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java index 539b7c6d87..ea86c37430 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java @@ -180,8 +180,8 @@ public enum ExIncomingPackets implements IIncomingPackets EX_BOOKMARK_PACKET(0x4E, ExBookmarkPacket::new, ConnectionState.IN_GAME), REQUEST_WITHDRAW_PREMIUM_ITEM(0x4F, RequestWithDrawPremiumItem::new, ConnectionState.IN_GAME), REQUEST_EX_JUMP(0x50, null, ConnectionState.IN_GAME), - REQUEST_EX_START_SHOW_CRATAE_CUBE_RANK(0x51, null, ConnectionState.IN_GAME), - REQUEST_EX_STOP_SHOW_CRATAE_CUBE_RANK(0x52, null, ConnectionState.IN_GAME), + REQUEST_EX_START_SHOW_CRATAE_CUBE_RANK(0x51, RequestStartShowKrateisCubeRank::new, ConnectionState.IN_GAME), + REQUEST_EX_STOP_SHOW_CRATAE_CUBE_RANK(0x52, RequestStopShowKrateisCubeRank::new, ConnectionState.IN_GAME), NOTIFY_START_MINI_GAME(0x53, null, ConnectionState.IN_GAME), REQUEST_EX_JOIN_DOMINION_WAR(0x54, null, ConnectionState.IN_GAME), REQUEST_EX_DOMINION_INFO(0x55, null, ConnectionState.IN_GAME), diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java index 6c7ebff02e..31e80f64fb 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java @@ -29,7 +29,10 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.entity.Castle; import com.l2jmobius.gameserver.model.entity.ClanHall; import com.l2jmobius.gameserver.model.entity.Fort; +import com.l2jmobius.gameserver.model.events.EventType; +import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; import com.l2jmobius.gameserver.model.instancezone.Instance; +import com.l2jmobius.gameserver.model.quest.Event; import com.l2jmobius.gameserver.model.residences.AbstractResidence; import com.l2jmobius.gameserver.model.residences.ResidenceFunctionType; import com.l2jmobius.gameserver.network.L2GameClient; @@ -92,6 +95,19 @@ public final class RequestRestartPoint implements IClientIncomingPacket return; } + // Custom event resurrection management. + if (activeChar.isOnCustomEvent()) + { + for (AbstractEventListener listener : activeChar.getListeners(EventType.ON_CREATURE_DEATH)) + { + if (listener.getOwner() instanceof Event) + { + ((Event) listener.getOwner()).notifyEvent("ResurrectPlayer", null, activeChar); + return; + } + } + } + final Castle castle = CastleManager.getInstance().getCastle(activeChar.getX(), activeChar.getY(), activeChar.getZ()); if ((castle != null) && castle.getSiege().isInProgress()) { diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java new file mode 100644 index 0000000000..d2213e55b6 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java @@ -0,0 +1,39 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.clientpackets; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; + +/** + * @author Mobius + */ +public class RequestStartShowKrateisCubeRank implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return false; + } + + @Override + public void run(L2GameClient client) + { + // TODO: Implement. + System.out.println("RequestStartShowKrateisCubeRank"); + } +} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java new file mode 100644 index 0000000000..51ca3ea99b --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java @@ -0,0 +1,39 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.clientpackets; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; + +/** + * @author Mobius + */ +public class RequestStopShowKrateisCubeRank implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return false; + } + + @Override + public void run(L2GameClient client) + { + // TODO: Implement. + System.out.println("RequestStopShowKrateisCubeRank"); + } +} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java new file mode 100644 index 0000000000..57547b985e --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java @@ -0,0 +1,41 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.serverpackets; + +import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.network.OutgoingPackets; + +/** + * @author Mobius + */ +public class ExPVPMatchCCMyRecord implements IClientOutgoingPacket +{ + private final int _points; + + public ExPVPMatchCCMyRecord(int points) + { + _points = points; + } + + @Override + public boolean write(PacketWriter packet) + { + OutgoingPackets.EX_PVP_MATCH_CCMY_RECORD.writeId(packet); + packet.writeD(_points); + return true; + } +} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java new file mode 100644 index 0000000000..b199a7443c --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java @@ -0,0 +1,57 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.serverpackets; + +import java.util.Map; +import java.util.Map.Entry; + +import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.network.OutgoingPackets; + +/** + * @author Mobius + */ +public class ExPVPMatchCCRecord implements IClientOutgoingPacket +{ + public static final int INITIALIZE = 0; + public static final int UPDATE = 1; + public static final int FINISH = 2; + + private final int _state; + private final Map _players; + + public ExPVPMatchCCRecord(int state, Map players) + { + _state = state; + _players = players; + } + + @Override + public boolean write(PacketWriter packet) + { + OutgoingPackets.EX_PVP_MATCH_CCRECORD.writeId(packet); + packet.writeD(_state); // 0 - initialize, 1 - update, 2 - finish + packet.writeD(_players.size()); + for (Entry entry : _players.entrySet()) + { + packet.writeS(entry.getKey().getName()); + packet.writeD(entry.getValue()); + } + return true; + } +} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/util/Util.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/util/Util.java index e551224ab8..850ae469e6 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/util/Util.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/util/Util.java @@ -31,6 +31,8 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; import java.util.logging.Logger; import com.l2jmobius.Config; @@ -788,4 +790,15 @@ public final class Util return (input < min) ? min : (input > max) ? max : input; } + /** + * Short an map by its integer values. + * @param unsortedMap + * @return + */ + public static Map sortByValue(Map unsortedMap) + { + Map sortedMap = new TreeMap<>(new ValueComparator(unsortedMap)); + sortedMap.putAll(unsortedMap); + return sortedMap; + } } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/util/ValueComparator.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/util/ValueComparator.java new file mode 100644 index 0000000000..32c494218d --- /dev/null +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/util/ValueComparator.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.util; + +import java.util.Comparator; +import java.util.Map; + +/** + * @author Mobius + */ +public class ValueComparator implements Comparator +{ + Map _map; + + public ValueComparator(Map map) + { + _map = map; + } + + @SuppressWarnings( + { + "rawtypes", + "unchecked" + }) + @Override + public int compare(Object keyA, Object keyB) + { + Comparable valueA = (Comparable) _map.get(keyA); + Comparable valueB = (Comparable) _map.get(keyB); + return valueB.compareTo(valueA); + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/instances/custom/coliseum.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/instances/custom/coliseum.xml index 6c8eb9385c..27a7498e9b 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/instances/custom/coliseum.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/instances/custom/coliseum.xml @@ -1,9 +1,23 @@ + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java new file mode 100644 index 0000000000..f31b220207 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java @@ -0,0 +1,871 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package custom.events.TeamVsTeam; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.l2jmobius.gameserver.enums.CategoryType; +import com.l2jmobius.gameserver.enums.PartyDistributionType; +import com.l2jmobius.gameserver.enums.Team; +import com.l2jmobius.gameserver.instancemanager.InstanceManager; +import com.l2jmobius.gameserver.instancemanager.ZoneManager; +import com.l2jmobius.gameserver.model.L2CommandChannel; +import com.l2jmobius.gameserver.model.L2Party; +import com.l2jmobius.gameserver.model.Location; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.L2Npc; +import com.l2jmobius.gameserver.model.actor.L2Summon; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.events.EventType; +import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent; +import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDeath; +import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout; +import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; +import com.l2jmobius.gameserver.model.events.listeners.ConsumerEventListener; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.SkillHolder; +import com.l2jmobius.gameserver.model.instancezone.Instance; +import com.l2jmobius.gameserver.model.instancezone.InstanceTemplate; +import com.l2jmobius.gameserver.model.olympiad.OlympiadManager; +import com.l2jmobius.gameserver.model.quest.Event; +import com.l2jmobius.gameserver.model.quest.QuestTimer; +import com.l2jmobius.gameserver.model.skills.CommonSkill; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.skills.SkillCaster; +import com.l2jmobius.gameserver.model.zone.L2ZoneType; +import com.l2jmobius.gameserver.model.zone.ZoneId; +import com.l2jmobius.gameserver.network.serverpackets.ExPVPMatchCCRecord; +import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; +import com.l2jmobius.gameserver.util.Broadcast; +import com.l2jmobius.gameserver.util.Util; + +/** + * Team vs Team event. + * @author Mobius + */ +public class TvT extends Event +{ + // NPC + private static final int MANAGER = 70010; + // Skills + private static final SkillHolder KNIGHT = new SkillHolder(15648, 1); // Knight's Harmony (Adventurer) + private static final SkillHolder WARRIOR = new SkillHolder(15649, 1); // Warrior's Harmony (Adventurer) + private static final SkillHolder WIZARD = new SkillHolder(15650, 1); // Wizard's Harmony (Adventurer) + private static final SkillHolder[] GROUP_BUFFS = + { + new SkillHolder(15642, 1), // Horn Melody (Adventurer) + new SkillHolder(15643, 1), // Drum Melody (Adventurer) + new SkillHolder(15644, 1), // Pipe Organ Melody (Adventurer) + new SkillHolder(15645, 1), // Guitar Melody (Adventurer) + new SkillHolder(15646, 1), // Harp Melody (Adventurer) + new SkillHolder(15647, 1), // Lute Melody (Adventurer) + new SkillHolder(15651, 1), // Prevailing Sonata (Adventurer) + new SkillHolder(15652, 1), // Daring Sonata (Adventurer) + new SkillHolder(15653, 1), // Refreshing Sonata (Adventurer) + }; + // Others + private static final int INSTANCE_ID = 3049; + private static final int BLUE_DOOR_ID = 24190002; + private static final int RED_DOOR_ID = 24190003; + private static final Location MANAGER_SPAWN_LOC = new Location(83425, 148585, -3406, 32938); + private static final Location BLUE_BUFFER_SPAWN_LOC = new Location(147450, 46913, -3400, 49000); + private static final Location RED_BUFFER_SPAWN_LOC = new Location(151545, 46528, -3400, 16000); + private static final Location BLUE_SPAWN_LOC = new Location(147447, 46722, -3416); + private static final Location RED_SPAWN_LOC = new Location(151536, 46722, -3416); + private static final L2ZoneType BLUE_PEACE_ZONE = ZoneManager.getInstance().getZoneByName("colosseum_peace1"); + private static final L2ZoneType RED_PEACE_ZONE = ZoneManager.getInstance().getZoneByName("colosseum_peace2"); + // Settings + private static final int REGISTRATION_TIME = 10; // Minutes + private static final int WAIT_TIME = 1; // Minutes + private static final int FIGHT_TIME = 20; // Minutes + private static final int INACTIVITY_TIME = 2; // Minutes + private static final int MINIMUM_PARTICIPANT_LEVEL = 85; + private static final int MAXIMUM_PARTICIPANT_LEVEL = 200; + private static final int MINIMUM_PARTICIPANT_COUNT = 4; + private static final int MAXIMUM_PARTICIPANT_COUNT = 24; // Scoreboard has 25 slots + private static final int PARTY_MEMBER_COUNT = 7; + private static final ItemHolder REWARD = new ItemHolder(57, 1000000); // Adena + // Misc + private static final Map PLAYER_SCORES = new ConcurrentHashMap<>(); + private static final List PLAYER_LIST = new ArrayList<>(); + private static final List BLUE_TEAM = new ArrayList<>(); + private static final List RED_TEAM = new ArrayList<>(); + private static volatile int BLUE_SCORE; + private static volatile int RED_SCORE; + private static Instance PVP_WORLD = null; + private static L2Npc MANAGER_NPC_INSTANCE = null; + private static boolean EVENT_ACTIVE = false; + + private TvT() + { + addTalkId(MANAGER); + addFirstTalkId(MANAGER); + addExitZoneId(BLUE_PEACE_ZONE.getId(), RED_PEACE_ZONE.getId()); + addEnterZoneId(BLUE_PEACE_ZONE.getId(), RED_PEACE_ZONE.getId()); + } + + @Override + public String onAdvEvent(String event, L2Npc npc, L2PcInstance player) + { + if (!EVENT_ACTIVE) + { + return null; + } + + String htmltext = null; + switch (event) + { + case "Participate": + { + if (canRegister(player)) + { + PLAYER_LIST.add(player); + PLAYER_SCORES.put(player, 0); + player.setOnCustomEvent(true); + addLogoutListener(player); + htmltext = "registration-success.html"; + } + else + { + htmltext = "registration-failed.html"; + } + break; + } + case "CancelParticipation": + { + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + removeListeners(player); + player.setOnCustomEvent(false); + htmltext = "registration-canceled.html"; + break; + } + case "BuffHeal": + { + if (player.isOnCustomEvent() || player.isGM()) + { + if (player.isInCombat()) + { + htmltext = "manager-combat.html"; + } + else + { + for (SkillHolder holder : GROUP_BUFFS) + { + SkillCaster.triggerCast(npc, player, holder.getSkill()); + } + if (player.isMageClass()) + { + SkillCaster.triggerCast(npc, player, WIZARD.getSkill()); + } + else if (player.isInCategory(CategoryType.KNIGHT_GROUP)) + { + SkillCaster.triggerCast(npc, player, KNIGHT.getSkill()); + } + else + { + SkillCaster.triggerCast(npc, player, WARRIOR.getSkill()); + } + player.setCurrentHp(player.getMaxHp()); + player.setCurrentMp(player.getMaxMp()); + player.setCurrentCp(player.getMaxCp()); + } + } + break; + } + case "TeleportToArena": + { + // Remove offline players. + for (L2PcInstance participant : PLAYER_LIST) + { + if ((participant == null) || (participant.isOnlineInt() != 1)) + { + PLAYER_LIST.remove(participant); + PLAYER_SCORES.remove(participant); + } + } + // Check if there are enough players to start the event. + if (PLAYER_LIST.size() < MINIMUM_PARTICIPANT_COUNT) + { + Broadcast.toAllOnlinePlayers("TvT Event: Event was canceled, not enough participants."); + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setOnCustomEvent(false); + } + EVENT_ACTIVE = false; + return null; + } + // Create the instance. + final InstanceManager manager = InstanceManager.getInstance(); + final InstanceTemplate template = manager.getInstanceTemplate(INSTANCE_ID); + PVP_WORLD = manager.createInstance(template, null); + // Randomize player list and separate teams. + Collections.shuffle(PLAYER_LIST); + boolean team = getRandomBoolean(); // If teams are not even, randomize where extra player goes. + for (L2PcInstance participant : PLAYER_LIST) + { + if (team) + { + BLUE_TEAM.add(participant); + PVP_WORLD.addAllowed(participant); + participant.leaveParty(); + participant.setTeam(Team.BLUE); + participant.teleToLocation(BLUE_SPAWN_LOC, PVP_WORLD); + team = false; + } + else + { + RED_TEAM.add(participant); + PVP_WORLD.addAllowed(participant); + participant.leaveParty(); + participant.setTeam(Team.RED); + participant.teleToLocation(RED_SPAWN_LOC, PVP_WORLD); + team = true; + } + addDeathListener(participant); + } + // Make Blue CC. + if (BLUE_TEAM.size() > 1) + { + L2CommandChannel blueCC = null; + L2Party lastBlueParty = null; + int blueParticipantCounter = 0; + for (L2PcInstance participant : BLUE_TEAM) + { + blueParticipantCounter++; + if (blueParticipantCounter == 1) + { + lastBlueParty = new L2Party(participant, PartyDistributionType.FINDERS_KEEPERS); + participant.joinParty(lastBlueParty); + if (BLUE_TEAM.size() > PARTY_MEMBER_COUNT) + { + if (blueCC == null) + { + blueCC = new L2CommandChannel(participant); + } + else + { + blueCC.addParty(lastBlueParty); + } + } + } + else if (lastBlueParty != null) + { + participant.joinParty(lastBlueParty); + } + if (blueParticipantCounter == PARTY_MEMBER_COUNT) + { + blueParticipantCounter = 0; + } + } + } + // Make Red CC. + if (RED_TEAM.size() > 1) + { + L2CommandChannel redCC = null; + L2Party lastRedParty = null; + int redParticipantCounter = 0; + for (L2PcInstance participant : RED_TEAM) + { + redParticipantCounter++; + if (redParticipantCounter == 1) + { + lastRedParty = new L2Party(participant, PartyDistributionType.FINDERS_KEEPERS); + participant.joinParty(lastRedParty); + if (RED_TEAM.size() > PARTY_MEMBER_COUNT) + { + if (redCC == null) + { + redCC = new L2CommandChannel(participant); + } + else + { + redCC.addParty(lastRedParty); + } + } + } + else if (lastRedParty != null) + { + participant.joinParty(lastRedParty); + } + if (redParticipantCounter == PARTY_MEMBER_COUNT) + { + redParticipantCounter = 0; + } + } + } + // Spawn managers. + addSpawn(MANAGER, BLUE_BUFFER_SPAWN_LOC, false, (WAIT_TIME + FIGHT_TIME) * 60000, false, PVP_WORLD.getId()); + addSpawn(MANAGER, RED_BUFFER_SPAWN_LOC, false, (WAIT_TIME + FIGHT_TIME) * 60000, false, PVP_WORLD.getId()); + // Initialize scores. + BLUE_SCORE = 0; + RED_SCORE = 0; + // Initialize scoreboard. + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.INITIALIZE, Util.sortByValue(PLAYER_SCORES))); + // Schedule start. + startQuestTimer("5", (WAIT_TIME * 60000) - 5000, null, null); + startQuestTimer("4", (WAIT_TIME * 60000) - 4000, null, null); + startQuestTimer("3", (WAIT_TIME * 60000) - 3000, null, null); + startQuestTimer("2", (WAIT_TIME * 60000) - 2000, null, null); + startQuestTimer("1", (WAIT_TIME * 60000) - 1000, null, null); + startQuestTimer("StartFight", WAIT_TIME * 60000, null, null); + break; + } + case "StartFight": + { + // Open doors. + openDoor(BLUE_DOOR_ID, PVP_WORLD.getId()); + openDoor(RED_DOOR_ID, PVP_WORLD.getId()); + // Send message. + broadcastScreenMessageWithEffect("The fight has began!", 5); + // Schedule finish. + startQuestTimer("10", (FIGHT_TIME * 60000) - 10000, null, null); + startQuestTimer("9", (FIGHT_TIME * 60000) - 9000, null, null); + startQuestTimer("8", (FIGHT_TIME * 60000) - 8000, null, null); + startQuestTimer("7", (FIGHT_TIME * 60000) - 7000, null, null); + startQuestTimer("6", (FIGHT_TIME * 60000) - 6000, null, null); + startQuestTimer("5", (FIGHT_TIME * 60000) - 5000, null, null); + startQuestTimer("4", (FIGHT_TIME * 60000) - 4000, null, null); + startQuestTimer("3", (FIGHT_TIME * 60000) - 3000, null, null); + startQuestTimer("2", (FIGHT_TIME * 60000) - 2000, null, null); + startQuestTimer("1", (FIGHT_TIME * 60000) - 1000, null, null); + startQuestTimer("EndFight", FIGHT_TIME * 60000, null, null); + break; + } + case "EndFight": + { + // Close doors. + closeDoor(BLUE_DOOR_ID, PVP_WORLD.getId()); + closeDoor(RED_DOOR_ID, PVP_WORLD.getId()); + // Disable players. + for (L2PcInstance participant : PLAYER_LIST) + { + participant.setIsInvul(true); + participant.setIsImmobilized(true); + participant.disableAllSkills(); + for (L2Summon summon : participant.getServitors().values()) + { + summon.setIsInvul(true); + summon.setIsImmobilized(true); + summon.disableAllSkills(); + } + } + // Make sure noone is dead. + for (L2PcInstance participant : PLAYER_LIST) + { + if (participant.isDead()) + { + participant.doRevive(); + } + } + // Team Blue wins. + if (BLUE_SCORE > RED_SCORE) + { + final Skill skill = CommonSkill.FIREWORK.getSkill(); + broadcastScreenMessageWithEffect("Team Blue won the event!", 7); + for (L2PcInstance participant : BLUE_TEAM) + { + if ((participant != null) && (participant.getInstanceWorld() == PVP_WORLD)) + { + participant.broadcastPacket(new MagicSkillUse(participant, participant, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay())); + participant.broadcastSocialAction(3); + giveItems(participant, REWARD); + } + } + } + // Team Red wins. + else if (RED_SCORE > BLUE_SCORE) + { + final Skill skill = CommonSkill.FIREWORK.getSkill(); + broadcastScreenMessageWithEffect("Team Red won the event!", 7); + for (L2PcInstance participant : RED_TEAM) + { + if ((participant != null) && (participant.getInstanceWorld() == PVP_WORLD)) + { + participant.broadcastPacket(new MagicSkillUse(participant, participant, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay())); + participant.broadcastSocialAction(3); + giveItems(participant, REWARD); + } + } + } + // Tie. + else + { + broadcastScreenMessageWithEffect("The event ended with a tie!", 7); + for (L2PcInstance participant : PLAYER_LIST) + { + participant.broadcastSocialAction(13); + } + } + startQuestTimer("ScoreBoard", 3500, null, null); + startQuestTimer("TeleportOut", 7000, null, null); + break; + } + case "ScoreBoard": + { + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.FINISH, Util.sortByValue(PLAYER_SCORES))); + break; + } + case "TeleportOut": + { + // Remove event listeners. + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setTeam(Team.NONE); + participant.setOnCustomEvent(false); + participant.leaveParty(); + } + // Destroy world. + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + // Enable players. + for (L2PcInstance participant : PLAYER_LIST) + { + participant.setIsInvul(false); + participant.setIsImmobilized(false); + participant.enableAllSkills(); + for (L2Summon summon : participant.getServitors().values()) + { + summon.setIsInvul(true); + summon.setIsImmobilized(true); + summon.disableAllSkills(); + } + } + EVENT_ACTIVE = false; + break; + } + case "ResurrectPlayer": + { + if (player.isDead() && player.isOnCustomEvent()) + { + if (BLUE_TEAM.contains(player)) + { + player.setIsPendingRevive(true); + player.teleToLocation(BLUE_SPAWN_LOC, false, PVP_WORLD); + } + else if (RED_TEAM.contains(player)) + { + player.setIsPendingRevive(true); + player.teleToLocation(RED_SPAWN_LOC, false, PVP_WORLD); + } + } + break; + } + case "10": + { + broadcastScreenMessage("10", 4); + break; + } + case "9": + { + broadcastScreenMessage("9", 4); + break; + } + case "8": + { + broadcastScreenMessage("8", 4); + break; + } + case "7": + { + broadcastScreenMessage("7", 4); + break; + } + case "6": + { + broadcastScreenMessage("6", 4); + break; + } + case "5": + { + broadcastScreenMessage("5", 4); + break; + } + case "4": + { + broadcastScreenMessage("4", 4); + break; + } + case "3": + { + broadcastScreenMessage("3", 4); + break; + } + case "2": + { + broadcastScreenMessage("2", 4); + break; + } + case "1": + { + broadcastScreenMessage("1", 4); + break; + } + } + // Activity timer. + if (event.startsWith("KickPlayer") && (player != null) && (player.getInstanceWorld() == PVP_WORLD)) + { + player.setTeam(Team.NONE); + PVP_WORLD.ejectPlayer(player); + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + BLUE_TEAM.remove(player); + RED_TEAM.remove(player); + player.setOnCustomEvent(false); + removeListeners(player); + player.sendMessage("You have been kicked for been inactive."); + if (PVP_WORLD != null) + { + broadcastScreenMessageWithEffect("Player " + player.getName() + " was kicked for been inactive.", 7); + } + } + return htmltext; + } + + @Override + public String onFirstTalk(L2Npc npc, L2PcInstance player) + { + // Event not active. + if (!EVENT_ACTIVE) + { + return null; + } + + // Player has already registered. + if (PLAYER_LIST.contains(player)) + { + // Npc is in instance. + if (npc.getInstanceWorld() != null) + { + return "manager-buffheal.html"; + } + return "manager-cancel.html"; + } + // Player is not registered. + return "manager-register.html"; + } + + @Override + public String onEnterZone(L2Character character, L2ZoneType zone) + { + if (character.isPlayable() && character.getActingPlayer().isOnCustomEvent()) + { + // Kick enemy players. + if ((zone == BLUE_PEACE_ZONE) && (character.getTeam() == Team.RED)) + { + character.teleToLocation(RED_SPAWN_LOC, PVP_WORLD); + character.getActingPlayer().sendPacket(new ExShowScreenMessage("Entering the enemy headquarters is prohibited!", ExShowScreenMessage.TOP_CENTER, 10000, 0, true, false)); + } + if ((zone == RED_PEACE_ZONE) && (character.getTeam() == Team.BLUE)) + { + character.teleToLocation(BLUE_SPAWN_LOC, PVP_WORLD); + character.getActingPlayer().sendPacket(new ExShowScreenMessage("Entering the enemy headquarters is prohibited!", ExShowScreenMessage.TOP_CENTER, 10000, 0, true, false)); + } + // Start inactivity check. + if (character.isPlayer() && // + ((((zone == BLUE_PEACE_ZONE) && (character.getTeam() == Team.BLUE)) || // + ((zone == RED_PEACE_ZONE) && (character.getTeam() == Team.RED))))) + { + startQuestTimer("KickPlayer" + character.getObjectId(), PVP_WORLD.getDoor(BLUE_DOOR_ID).isOpen() ? INACTIVITY_TIME * 60000 : (INACTIVITY_TIME * 60000) + (WAIT_TIME * 60000), null, character.getActingPlayer()); + } + } + return null; + } + + @Override + public String onExitZone(L2Character character, L2ZoneType zone) + { + if (character.isPlayer() && character.getActingPlayer().isOnCustomEvent()) + { + cancelQuestTimer("KickPlayer" + character.getObjectId(), null, character.getActingPlayer()); + } + return super.onExitZone(character, zone); + } + + private boolean canRegister(L2PcInstance player) + { + if (PLAYER_LIST.contains(player)) + { + player.sendMessage("You are already registered on this event."); + return false; + } + if (player.getLevel() < MINIMUM_PARTICIPANT_LEVEL) + { + player.sendMessage("Your level is too low to participate."); + return false; + } + if (player.getLevel() > MAXIMUM_PARTICIPANT_LEVEL) + { + player.sendMessage("Your level is too high to participate."); + return false; + } + if (player.isOnEvent() || (player.getBlockCheckerArena() > -1)) + { + player.sendMessage("You are already registered on an event."); + return false; + } + if (PLAYER_LIST.size() >= MAXIMUM_PARTICIPANT_COUNT) + { + player.sendMessage("There are too many players registered on the event."); + return false; + } + if (player.isFlyingMounted()) + { + player.sendMessage("You cannot register on the event while flying."); + return false; + } + if (player.isTransformed()) + { + player.sendMessage("You cannot register on the event while on a transformed state."); + return false; + } + if (!player.isInventoryUnder80(false)) + { + player.sendMessage("There are too many items in your inventory."); + player.sendMessage("Try removing some items."); + return false; + } + if ((player.getWeightPenalty() != 0)) + { + player.sendMessage("Your invetory weight has exceeded the normal limit."); + player.sendMessage("Try removing some items."); + return false; + } + if (player.isCursedWeaponEquipped() || (player.getReputation() < 0)) + { + player.sendMessage("People with bad reputation can't register."); + return false; + } + if (player.isInDuel()) + { + player.sendMessage("You cannot register while on a duel."); + return false; + } + if (player.isInOlympiadMode() || OlympiadManager.getInstance().isRegistered(player)) + { + player.sendMessage("You cannot participate while registered on the Olympiad."); + return false; + } + if (player.isInInstance()) + { + player.sendMessage("You cannot register while in an instance."); + return false; + } + if (player.isInSiege() || player.isInsideZone(ZoneId.SIEGE)) + { + player.sendMessage("You cannot register while on a siege."); + return false; + } + if (player.isFishing()) + { + player.sendMessage("You cannot register while fishing."); + return false; + } + return true; + } + + private void broadcastScreenMessageWithEffect(String message, int duration) + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage(message, ExShowScreenMessage.TOP_CENTER, duration * 1000, 0, true, true)); + } + + private void broadcastScreenMessage(String message, int duration) + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage(message, ExShowScreenMessage.TOP_CENTER, duration * 1000, 0, true, false)); + } + + private void broadcastScoreMessage() + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage("Blue: " + BLUE_SCORE + " - Red: " + RED_SCORE, ExShowScreenMessage.BOTTOM_RIGHT, 15000, 0, true, false)); + } + + private void addLogoutListener(L2PcInstance player) + { + player.addListener(new ConsumerEventListener(player, EventType.ON_PLAYER_LOGOUT, (OnPlayerLogout event) -> OnPlayerLogout(event), this)); + } + + private void addDeathListener(L2PcInstance player) + { + player.addListener(new ConsumerEventListener(player, EventType.ON_CREATURE_DEATH, (OnCreatureDeath event) -> onPlayerDeath(event), this)); + } + + private void removeListeners(L2PcInstance player) + { + for (AbstractEventListener listener : player.getListeners(EventType.ON_PLAYER_LOGOUT)) + { + if (listener.getOwner() == this) + { + listener.unregisterMe(); + } + } + for (AbstractEventListener listener : player.getListeners(EventType.ON_CREATURE_DEATH)) + { + if (listener.getOwner() == this) + { + listener.unregisterMe(); + } + } + } + + @RegisterEvent(EventType.ON_PLAYER_LOGOUT) + private void OnPlayerLogout(OnPlayerLogout event) + { + final L2PcInstance player = event.getActiveChar(); + if (player != null) + { + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + BLUE_TEAM.remove(player); + RED_TEAM.remove(player); + } + // If all players left instance end the event. + if (PLAYER_LIST.isEmpty()) + { + // Stop timers. + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Destroy world. + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + } + } + + @RegisterEvent(EventType.ON_CREATURE_DEATH) + public void onPlayerDeath(OnCreatureDeath event) + { + if (event.getTarget().isPlayer()) + { + final L2PcInstance killedPlayer = event.getTarget().getActingPlayer(); + final L2PcInstance killer = event.getAttacker().getActingPlayer(); + // Confirm Blue team kill. + if ((killer.getTeam() == Team.BLUE) && (killedPlayer.getTeam() == Team.RED)) + { + PLAYER_SCORES.put(killer, PLAYER_SCORES.get(killer) + 1); + BLUE_SCORE++; + broadcastScoreMessage(); + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.UPDATE, Util.sortByValue(PLAYER_SCORES))); + } + // Confirm Red team kill. + if ((killer.getTeam() == Team.RED) && (killedPlayer.getTeam() == Team.BLUE)) + { + PLAYER_SCORES.put(killer, PLAYER_SCORES.get(killer) + 1); + RED_SCORE++; + broadcastScoreMessage(); + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.UPDATE, Util.sortByValue(PLAYER_SCORES))); + } + // Auto release after 10 seconds. + startQuestTimer("ResurrectPlayer", 10000, null, killedPlayer); + } + } + + @Override + public boolean eventStart(L2PcInstance eventMaker) + { + if (EVENT_ACTIVE) + { + return false; + } + EVENT_ACTIVE = true; + + // Cancel timers. (In case event started immediately after another event finished.) + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Clear player lists. + PLAYER_LIST.clear(); + PLAYER_SCORES.clear(); + BLUE_TEAM.clear(); + RED_TEAM.clear(); + // Spawn event manager. + MANAGER_NPC_INSTANCE = addSpawn(MANAGER, MANAGER_SPAWN_LOC, false, REGISTRATION_TIME * 60000); + startQuestTimer("TeleportToArena", REGISTRATION_TIME * 60000, null, null); + // Send message to players. + Broadcast.toAllOnlinePlayers("TvT Event: Registration opened for " + REGISTRATION_TIME + " minutes."); + Broadcast.toAllOnlinePlayers("TvT Event: You can register at Giran TvT Event Manager."); + + return true; + } + + @Override + public boolean eventStop() + { + if (!EVENT_ACTIVE) + { + return false; + } + EVENT_ACTIVE = false; + + // Despawn event manager. + MANAGER_NPC_INSTANCE.deleteMe(); + // Cancel timers. + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Remove participants. + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setTeam(Team.NONE); + participant.setOnCustomEvent(false); + } + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + // Send message to players. + Broadcast.toAllOnlinePlayers("TvT Event: Event was canceled."); + return true; + } + + @Override + public boolean eventBypass(L2PcInstance activeChar, String bypass) + { + return false; + } + + public static void main(String[] args) + { + new TvT(); + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html new file mode 100644 index 0000000000..54bbd53443 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Need assistance?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html new file mode 100644 index 0000000000..6c9101990c --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Cancel your participation?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html new file mode 100644 index 0000000000..2b72e551d8 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
You are in combat, calm down...
+
+
+
+
+
+ + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html new file mode 100644 index 0000000000..c5d7eb5d12 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Do you want to join the event?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html new file mode 100644 index 0000000000..5b21728486 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration canceled.
+
+
+
+
+
+ + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html new file mode 100644 index 0000000000..2f3b31f9f6 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration failed.
+
+
+
+
+
+ + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html new file mode 100644 index 0000000000..548a8a1750 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration successful!
+
+
+
+
+
+ + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java index d17921338b..e06f9e07fd 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java @@ -63,19 +63,23 @@ public class AdminZone implements IAdminCommandHandler getGeoRegionXY(activeChar); activeChar.sendMessage("Closest Town: " + MapRegionManager.getInstance().getClosestTownName(activeChar)); - Location loc; - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CASTLE); - activeChar.sendMessage("TeleToLocation (Castle): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CLANHALL); - activeChar.sendMessage("TeleToLocation (ClanHall): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.SIEGEFLAG); - activeChar.sendMessage("TeleToLocation (SiegeFlag): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.TOWN); - activeChar.sendMessage("TeleToLocation (Town): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + // Prevent exit instance variable deletion. + if (!activeChar.isInInstance()) + { + Location loc; + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CASTLE); + activeChar.sendMessage("TeleToLocation (Castle): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CLANHALL); + activeChar.sendMessage("TeleToLocation (ClanHall): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.SIEGEFLAG); + activeChar.sendMessage("TeleToLocation (SiegeFlag): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.TOWN); + activeChar.sendMessage("TeleToLocation (Town): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + } } else if (actualCommand.equalsIgnoreCase("admin_zone_visual")) { diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/npcs/custom/custom.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/npcs/custom/custom.xml index 5b2d3489b1..c9b6b84f6c 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/npcs/custom/custom.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/npcs/custom/custom.xml @@ -1,23 +1,5 @@ - - ELEMENTAL - FEMALE - - - - - - - - - - - - - - - ANIMAL MALE diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/npcs/custom/tvt_event.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/npcs/custom/tvt_event.xml new file mode 100644 index 0000000000..a867441b79 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/npcs/custom/tvt_event.xml @@ -0,0 +1,22 @@ + + + + HUMAN + MALE + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index dfdc1d6ea6..db7df42b5a 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -679,6 +679,7 @@ public final class L2PcInstance extends L2Playable @SuppressWarnings("rawtypes") private volatile Map, AbstractEvent> _events; + private boolean _isOnCustomEvent = false; public boolean isSpawnProtected() { @@ -8149,7 +8150,12 @@ public final class L2PcInstance extends L2Playable return false; } - // Check if the attacker is in TvT and TvT is started + if (isOnCustomEvent() && (getTeam() == attacker.getTeam())) + { + return false; + } + + // CoC needs this check? if (isOnEvent()) { return true; @@ -13110,12 +13116,26 @@ public final class L2PcInstance extends L2Playable _canRevive = val; } + public boolean isOnCustomEvent() + { + return _isOnCustomEvent; + } + + public void setOnCustomEvent(boolean value) + { + _isOnCustomEvent = value; + } + /** * @return {@code true} if player is on event, {@code false} otherwise. */ @Override public boolean isOnEvent() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) @@ -13131,6 +13151,10 @@ public final class L2PcInstance extends L2Playable public boolean isBlockedFromExit() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) @@ -13146,6 +13170,10 @@ public final class L2PcInstance extends L2Playable public boolean isBlockedFromDeathPenalty() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java index c3686c67be..d1bb6ffa75 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java @@ -63,6 +63,10 @@ public class ConditionPlayerCanEscape extends Condition { canTeleport = false; } + else if (player.isOnCustomEvent()) + { + canTeleport = false; + } return (_val == canTeleport); } } \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java index 4ed6708e7f..679e38bdb6 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java @@ -64,6 +64,11 @@ public class ConditionPlayerCanTransform extends Condition player.sendPacket(SystemMessageId.YOU_CANNOT_TRANSFORM_WHILE_RIDING_A_PET); canTransform = false; } + else if (player.isOnCustomEvent()) + { + player.sendMessage("You cannot transform while registered on an event."); + canTransform = false; + } return (_val == canTransform); } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/instancezone/Instance.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/instancezone/Instance.java index 77c2468437..70464afd7c 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/instancezone/Instance.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/instancezone/Instance.java @@ -888,19 +888,22 @@ public final class Instance implements IIdentifiable, INamable */ public void onDeath(L2PcInstance player) { - // Send message - final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IF_YOU_ARE_NOT_RESURRECTED_WITHIN_S1_MINUTE_S_YOU_WILL_BE_EXPELLED_FROM_THE_INSTANT_ZONE); - sm.addInt(_template.getEjectTime()); - player.sendPacket(sm); - - // Start eject task - _ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.schedule(() -> + if (!player.isOnCustomEvent()) { - if (player.isDead()) + // Send message + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IF_YOU_ARE_NOT_RESURRECTED_WITHIN_S1_MINUTE_S_YOU_WILL_BE_EXPELLED_FROM_THE_INSTANT_ZONE); + sm.addInt(_template.getEjectTime()); + player.sendPacket(sm); + + // Start eject task + _ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.schedule(() -> { - ejectPlayer(player.getActingPlayer()); - } - }, _template.getEjectTime() * 60 * 1000)); // minutes to milliseconds + if (player.isDead()) + { + ejectPlayer(player.getActingPlayer()); + } + }, _template.getEjectTime() * 60 * 1000)); // minutes to milliseconds + } } /** diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java index f4fa7592ad..409678ea5a 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java @@ -365,6 +365,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl public Location getExitLocation(L2PcInstance player) { Location location = null; + switch (_exitLocationType) { case RANDOM: diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java index 654f90b805..58913e355d 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java @@ -185,8 +185,8 @@ public enum ExIncomingPackets implements IIncomingPackets EX_BOOKMARK_PACKET(0x4E, ExBookmarkPacket::new, ConnectionState.IN_GAME), REQUEST_WITHDRAW_PREMIUM_ITEM(0x4F, RequestWithDrawPremiumItem::new, ConnectionState.IN_GAME), REQUEST_EX_JUMP(0x50, null, ConnectionState.IN_GAME), - REQUEST_EX_START_SHOW_CRATAE_CUBE_RANK(0x51, null, ConnectionState.IN_GAME), - REQUEST_EX_STOP_SHOW_CRATAE_CUBE_RANK(0x52, null, ConnectionState.IN_GAME), + REQUEST_EX_START_SHOW_CRATAE_CUBE_RANK(0x51, RequestStartShowKrateisCubeRank::new, ConnectionState.IN_GAME), + REQUEST_EX_STOP_SHOW_CRATAE_CUBE_RANK(0x52, RequestStopShowKrateisCubeRank::new, ConnectionState.IN_GAME), NOTIFY_START_MINI_GAME(0x53, null, ConnectionState.IN_GAME), REQUEST_EX_JOIN_DOMINION_WAR(0x54, null, ConnectionState.IN_GAME), REQUEST_EX_DOMINION_INFO(0x55, null, ConnectionState.IN_GAME), diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java index 6c7ebff02e..31e80f64fb 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java @@ -29,7 +29,10 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.entity.Castle; import com.l2jmobius.gameserver.model.entity.ClanHall; import com.l2jmobius.gameserver.model.entity.Fort; +import com.l2jmobius.gameserver.model.events.EventType; +import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; import com.l2jmobius.gameserver.model.instancezone.Instance; +import com.l2jmobius.gameserver.model.quest.Event; import com.l2jmobius.gameserver.model.residences.AbstractResidence; import com.l2jmobius.gameserver.model.residences.ResidenceFunctionType; import com.l2jmobius.gameserver.network.L2GameClient; @@ -92,6 +95,19 @@ public final class RequestRestartPoint implements IClientIncomingPacket return; } + // Custom event resurrection management. + if (activeChar.isOnCustomEvent()) + { + for (AbstractEventListener listener : activeChar.getListeners(EventType.ON_CREATURE_DEATH)) + { + if (listener.getOwner() instanceof Event) + { + ((Event) listener.getOwner()).notifyEvent("ResurrectPlayer", null, activeChar); + return; + } + } + } + final Castle castle = CastleManager.getInstance().getCastle(activeChar.getX(), activeChar.getY(), activeChar.getZ()); if ((castle != null) && castle.getSiege().isInProgress()) { diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java new file mode 100644 index 0000000000..d2213e55b6 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java @@ -0,0 +1,39 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.clientpackets; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; + +/** + * @author Mobius + */ +public class RequestStartShowKrateisCubeRank implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return false; + } + + @Override + public void run(L2GameClient client) + { + // TODO: Implement. + System.out.println("RequestStartShowKrateisCubeRank"); + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java new file mode 100644 index 0000000000..51ca3ea99b --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java @@ -0,0 +1,39 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.clientpackets; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; + +/** + * @author Mobius + */ +public class RequestStopShowKrateisCubeRank implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return false; + } + + @Override + public void run(L2GameClient client) + { + // TODO: Implement. + System.out.println("RequestStopShowKrateisCubeRank"); + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java new file mode 100644 index 0000000000..57547b985e --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java @@ -0,0 +1,41 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.serverpackets; + +import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.network.OutgoingPackets; + +/** + * @author Mobius + */ +public class ExPVPMatchCCMyRecord implements IClientOutgoingPacket +{ + private final int _points; + + public ExPVPMatchCCMyRecord(int points) + { + _points = points; + } + + @Override + public boolean write(PacketWriter packet) + { + OutgoingPackets.EX_PVP_MATCH_CCMY_RECORD.writeId(packet); + packet.writeD(_points); + return true; + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java new file mode 100644 index 0000000000..b199a7443c --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java @@ -0,0 +1,57 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.serverpackets; + +import java.util.Map; +import java.util.Map.Entry; + +import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.network.OutgoingPackets; + +/** + * @author Mobius + */ +public class ExPVPMatchCCRecord implements IClientOutgoingPacket +{ + public static final int INITIALIZE = 0; + public static final int UPDATE = 1; + public static final int FINISH = 2; + + private final int _state; + private final Map _players; + + public ExPVPMatchCCRecord(int state, Map players) + { + _state = state; + _players = players; + } + + @Override + public boolean write(PacketWriter packet) + { + OutgoingPackets.EX_PVP_MATCH_CCRECORD.writeId(packet); + packet.writeD(_state); // 0 - initialize, 1 - update, 2 - finish + packet.writeD(_players.size()); + for (Entry entry : _players.entrySet()) + { + packet.writeS(entry.getKey().getName()); + packet.writeD(entry.getValue()); + } + return true; + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/util/Util.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/util/Util.java index e551224ab8..850ae469e6 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/util/Util.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/util/Util.java @@ -31,6 +31,8 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; import java.util.logging.Logger; import com.l2jmobius.Config; @@ -788,4 +790,15 @@ public final class Util return (input < min) ? min : (input > max) ? max : input; } + /** + * Short an map by its integer values. + * @param unsortedMap + * @return + */ + public static Map sortByValue(Map unsortedMap) + { + Map sortedMap = new TreeMap<>(new ValueComparator(unsortedMap)); + sortedMap.putAll(unsortedMap); + return sortedMap; + } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/util/ValueComparator.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/util/ValueComparator.java new file mode 100644 index 0000000000..32c494218d --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/util/ValueComparator.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.util; + +import java.util.Comparator; +import java.util.Map; + +/** + * @author Mobius + */ +public class ValueComparator implements Comparator +{ + Map _map; + + public ValueComparator(Map map) + { + _map = map; + } + + @SuppressWarnings( + { + "rawtypes", + "unchecked" + }) + @Override + public int compare(Object keyA, Object keyB) + { + Comparable valueA = (Comparable) _map.get(keyA); + Comparable valueB = (Comparable) _map.get(keyB); + return valueB.compareTo(valueA); + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/instances/custom/coliseum.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/instances/custom/coliseum.xml index 6c8eb9385c..27a7498e9b 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/instances/custom/coliseum.xml +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/instances/custom/coliseum.xml @@ -1,9 +1,23 @@ + diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java new file mode 100644 index 0000000000..d7c0a8bdcb --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/TvT.java @@ -0,0 +1,873 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package custom.events.TeamVsTeam; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.l2jmobius.gameserver.enums.PartyDistributionType; +import com.l2jmobius.gameserver.enums.Team; +import com.l2jmobius.gameserver.instancemanager.InstanceManager; +import com.l2jmobius.gameserver.instancemanager.ZoneManager; +import com.l2jmobius.gameserver.model.L2CommandChannel; +import com.l2jmobius.gameserver.model.L2Party; +import com.l2jmobius.gameserver.model.Location; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.L2Npc; +import com.l2jmobius.gameserver.model.actor.L2Summon; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.events.EventType; +import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent; +import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDeath; +import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout; +import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; +import com.l2jmobius.gameserver.model.events.listeners.ConsumerEventListener; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.SkillHolder; +import com.l2jmobius.gameserver.model.instancezone.Instance; +import com.l2jmobius.gameserver.model.instancezone.InstanceTemplate; +import com.l2jmobius.gameserver.model.olympiad.OlympiadManager; +import com.l2jmobius.gameserver.model.quest.Event; +import com.l2jmobius.gameserver.model.quest.QuestTimer; +import com.l2jmobius.gameserver.model.skills.CommonSkill; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.skills.SkillCaster; +import com.l2jmobius.gameserver.model.zone.L2ZoneType; +import com.l2jmobius.gameserver.model.zone.ZoneId; +import com.l2jmobius.gameserver.network.serverpackets.ExPVPMatchCCRecord; +import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; +import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; +import com.l2jmobius.gameserver.util.Broadcast; +import com.l2jmobius.gameserver.util.Util; + +/** + * Team vs Team event. + * @author Mobius + */ +public class TvT extends Event +{ + // NPC + private static final int MANAGER = 70010; + // Skills + private static final SkillHolder[] FIGHTER_BUFFS = + { + new SkillHolder(4322, 1), // Wind Walk + new SkillHolder(4323, 1), // Shield + new SkillHolder(5637, 1), // Magic Barrier + new SkillHolder(4324, 1), // Bless the Body + new SkillHolder(4325, 1), // Vampiric Rage + new SkillHolder(4326, 1), // Regeneration + new SkillHolder(5632, 1), // Haste + }; + private static final SkillHolder[] MAGE_BUFFS = + { + new SkillHolder(4322, 1), // Wind Walk + new SkillHolder(4323, 1), // Shield + new SkillHolder(5637, 1), // Magic Barrier + new SkillHolder(4328, 1), // Bless the Soul + new SkillHolder(4329, 1), // Acumen + new SkillHolder(4330, 1), // Concentration + new SkillHolder(4331, 1), // Empower + }; + // Others + private static final int INSTANCE_ID = 3049; + private static final int BLUE_DOOR_ID = 24190002; + private static final int RED_DOOR_ID = 24190003; + private static final Location MANAGER_SPAWN_LOC = new Location(83425, 148585, -3406, 32938); + private static final Location BLUE_BUFFER_SPAWN_LOC = new Location(147450, 46913, -3400, 49000); + private static final Location RED_BUFFER_SPAWN_LOC = new Location(151545, 46528, -3400, 16000); + private static final Location BLUE_SPAWN_LOC = new Location(147447, 46722, -3416); + private static final Location RED_SPAWN_LOC = new Location(151536, 46722, -3416); + private static final L2ZoneType BLUE_PEACE_ZONE = ZoneManager.getInstance().getZoneByName("colosseum_peace1"); + private static final L2ZoneType RED_PEACE_ZONE = ZoneManager.getInstance().getZoneByName("colosseum_peace2"); + // Settings + private static final int REGISTRATION_TIME = 10; // Minutes + private static final int WAIT_TIME = 1; // Minutes + private static final int FIGHT_TIME = 20; // Minutes + private static final int INACTIVITY_TIME = 2; // Minutes + private static final int MINIMUM_PARTICIPANT_LEVEL = 76; + private static final int MAXIMUM_PARTICIPANT_LEVEL = 200; + private static final int MINIMUM_PARTICIPANT_COUNT = 4; + private static final int MAXIMUM_PARTICIPANT_COUNT = 24; // Scoreboard has 25 slots + private static final int PARTY_MEMBER_COUNT = 7; + private static final ItemHolder REWARD = new ItemHolder(57, 100000); // Adena + // Misc + private static final Map PLAYER_SCORES = new ConcurrentHashMap<>(); + private static final List PLAYER_LIST = new ArrayList<>(); + private static final List BLUE_TEAM = new ArrayList<>(); + private static final List RED_TEAM = new ArrayList<>(); + private static volatile int BLUE_SCORE; + private static volatile int RED_SCORE; + private static Instance PVP_WORLD = null; + private static L2Npc MANAGER_NPC_INSTANCE = null; + private static boolean EVENT_ACTIVE = false; + + private TvT() + { + addTalkId(MANAGER); + addFirstTalkId(MANAGER); + addExitZoneId(BLUE_PEACE_ZONE.getId(), RED_PEACE_ZONE.getId()); + addEnterZoneId(BLUE_PEACE_ZONE.getId(), RED_PEACE_ZONE.getId()); + } + + @Override + public String onAdvEvent(String event, L2Npc npc, L2PcInstance player) + { + if (!EVENT_ACTIVE) + { + return null; + } + + String htmltext = null; + switch (event) + { + case "Participate": + { + if (canRegister(player)) + { + PLAYER_LIST.add(player); + PLAYER_SCORES.put(player, 0); + player.setOnCustomEvent(true); + addLogoutListener(player); + htmltext = "registration-success.html"; + } + else + { + htmltext = "registration-failed.html"; + } + break; + } + case "CancelParticipation": + { + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + removeListeners(player); + player.setOnCustomEvent(false); + htmltext = "registration-canceled.html"; + break; + } + case "BuffHeal": + { + if (player.isOnCustomEvent() || player.isGM()) + { + if (player.isInCombat()) + { + htmltext = "manager-combat.html"; + } + else + { + if (player.isMageClass()) + { + for (SkillHolder skill : MAGE_BUFFS) + { + SkillCaster.triggerCast(npc, player, skill.getSkill()); + } + } + else + { + for (SkillHolder skill : FIGHTER_BUFFS) + { + SkillCaster.triggerCast(npc, player, skill.getSkill()); + } + } + player.setCurrentHp(player.getMaxHp()); + player.setCurrentMp(player.getMaxMp()); + player.setCurrentCp(player.getMaxCp()); + } + } + break; + } + case "TeleportToArena": + { + // Remove offline players. + for (L2PcInstance participant : PLAYER_LIST) + { + if ((participant == null) || (participant.isOnlineInt() != 1)) + { + PLAYER_LIST.remove(participant); + PLAYER_SCORES.remove(participant); + } + } + // Check if there are enough players to start the event. + if (PLAYER_LIST.size() < MINIMUM_PARTICIPANT_COUNT) + { + Broadcast.toAllOnlinePlayers("TvT Event: Event was canceled, not enough participants."); + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setOnCustomEvent(false); + } + EVENT_ACTIVE = false; + return null; + } + // Create the instance. + final InstanceManager manager = InstanceManager.getInstance(); + final InstanceTemplate template = manager.getInstanceTemplate(INSTANCE_ID); + PVP_WORLD = manager.createInstance(template, null); + // Randomize player list and separate teams. + Collections.shuffle(PLAYER_LIST); + boolean team = getRandomBoolean(); // If teams are not even, randomize where extra player goes. + for (L2PcInstance participant : PLAYER_LIST) + { + if (team) + { + BLUE_TEAM.add(participant); + PVP_WORLD.addAllowed(participant); + participant.leaveParty(); + participant.setTeam(Team.BLUE); + participant.teleToLocation(BLUE_SPAWN_LOC, PVP_WORLD); + team = false; + } + else + { + RED_TEAM.add(participant); + PVP_WORLD.addAllowed(participant); + participant.leaveParty(); + participant.setTeam(Team.RED); + participant.teleToLocation(RED_SPAWN_LOC, PVP_WORLD); + team = true; + } + addDeathListener(participant); + } + // Make Blue CC. + if (BLUE_TEAM.size() > 1) + { + L2CommandChannel blueCC = null; + L2Party lastBlueParty = null; + int blueParticipantCounter = 0; + for (L2PcInstance participant : BLUE_TEAM) + { + blueParticipantCounter++; + if (blueParticipantCounter == 1) + { + lastBlueParty = new L2Party(participant, PartyDistributionType.FINDERS_KEEPERS); + participant.joinParty(lastBlueParty); + if (BLUE_TEAM.size() > PARTY_MEMBER_COUNT) + { + if (blueCC == null) + { + blueCC = new L2CommandChannel(participant); + } + else + { + blueCC.addParty(lastBlueParty); + } + } + } + else if (lastBlueParty != null) + { + participant.joinParty(lastBlueParty); + } + if (blueParticipantCounter == PARTY_MEMBER_COUNT) + { + blueParticipantCounter = 0; + } + } + } + // Make Red CC. + if (RED_TEAM.size() > 1) + { + L2CommandChannel redCC = null; + L2Party lastRedParty = null; + int redParticipantCounter = 0; + for (L2PcInstance participant : RED_TEAM) + { + redParticipantCounter++; + if (redParticipantCounter == 1) + { + lastRedParty = new L2Party(participant, PartyDistributionType.FINDERS_KEEPERS); + participant.joinParty(lastRedParty); + if (RED_TEAM.size() > PARTY_MEMBER_COUNT) + { + if (redCC == null) + { + redCC = new L2CommandChannel(participant); + } + else + { + redCC.addParty(lastRedParty); + } + } + } + else if (lastRedParty != null) + { + participant.joinParty(lastRedParty); + } + if (redParticipantCounter == PARTY_MEMBER_COUNT) + { + redParticipantCounter = 0; + } + } + } + // Spawn managers. + addSpawn(MANAGER, BLUE_BUFFER_SPAWN_LOC, false, (WAIT_TIME + FIGHT_TIME) * 60000, false, PVP_WORLD.getId()); + addSpawn(MANAGER, RED_BUFFER_SPAWN_LOC, false, (WAIT_TIME + FIGHT_TIME) * 60000, false, PVP_WORLD.getId()); + // Initialize scores. + BLUE_SCORE = 0; + RED_SCORE = 0; + // Initialize scoreboard. + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.INITIALIZE, Util.sortByValue(PLAYER_SCORES))); + // Schedule start. + startQuestTimer("5", (WAIT_TIME * 60000) - 5000, null, null); + startQuestTimer("4", (WAIT_TIME * 60000) - 4000, null, null); + startQuestTimer("3", (WAIT_TIME * 60000) - 3000, null, null); + startQuestTimer("2", (WAIT_TIME * 60000) - 2000, null, null); + startQuestTimer("1", (WAIT_TIME * 60000) - 1000, null, null); + startQuestTimer("StartFight", WAIT_TIME * 60000, null, null); + break; + } + case "StartFight": + { + // Open doors. + openDoor(BLUE_DOOR_ID, PVP_WORLD.getId()); + openDoor(RED_DOOR_ID, PVP_WORLD.getId()); + // Send message. + broadcastScreenMessageWithEffect("The fight has began!", 5); + // Schedule finish. + startQuestTimer("10", (FIGHT_TIME * 60000) - 10000, null, null); + startQuestTimer("9", (FIGHT_TIME * 60000) - 9000, null, null); + startQuestTimer("8", (FIGHT_TIME * 60000) - 8000, null, null); + startQuestTimer("7", (FIGHT_TIME * 60000) - 7000, null, null); + startQuestTimer("6", (FIGHT_TIME * 60000) - 6000, null, null); + startQuestTimer("5", (FIGHT_TIME * 60000) - 5000, null, null); + startQuestTimer("4", (FIGHT_TIME * 60000) - 4000, null, null); + startQuestTimer("3", (FIGHT_TIME * 60000) - 3000, null, null); + startQuestTimer("2", (FIGHT_TIME * 60000) - 2000, null, null); + startQuestTimer("1", (FIGHT_TIME * 60000) - 1000, null, null); + startQuestTimer("EndFight", FIGHT_TIME * 60000, null, null); + break; + } + case "EndFight": + { + // Close doors. + closeDoor(BLUE_DOOR_ID, PVP_WORLD.getId()); + closeDoor(RED_DOOR_ID, PVP_WORLD.getId()); + // Disable players. + for (L2PcInstance participant : PLAYER_LIST) + { + participant.setIsInvul(true); + participant.setIsImmobilized(true); + participant.disableAllSkills(); + for (L2Summon summon : participant.getServitors().values()) + { + summon.setIsInvul(true); + summon.setIsImmobilized(true); + summon.disableAllSkills(); + } + } + // Make sure noone is dead. + for (L2PcInstance participant : PLAYER_LIST) + { + if (participant.isDead()) + { + participant.doRevive(); + } + } + // Team Blue wins. + if (BLUE_SCORE > RED_SCORE) + { + final Skill skill = CommonSkill.FIREWORK.getSkill(); + broadcastScreenMessageWithEffect("Team Blue won the event!", 7); + for (L2PcInstance participant : BLUE_TEAM) + { + if ((participant != null) && (participant.getInstanceWorld() == PVP_WORLD)) + { + participant.broadcastPacket(new MagicSkillUse(participant, participant, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay())); + participant.broadcastSocialAction(3); + giveItems(participant, REWARD); + } + } + } + // Team Red wins. + else if (RED_SCORE > BLUE_SCORE) + { + final Skill skill = CommonSkill.FIREWORK.getSkill(); + broadcastScreenMessageWithEffect("Team Red won the event!", 7); + for (L2PcInstance participant : RED_TEAM) + { + if ((participant != null) && (participant.getInstanceWorld() == PVP_WORLD)) + { + participant.broadcastPacket(new MagicSkillUse(participant, participant, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay())); + participant.broadcastSocialAction(3); + giveItems(participant, REWARD); + } + } + } + // Tie. + else + { + broadcastScreenMessageWithEffect("The event ended with a tie!", 7); + for (L2PcInstance participant : PLAYER_LIST) + { + participant.broadcastSocialAction(13); + } + } + startQuestTimer("ScoreBoard", 3500, null, null); + startQuestTimer("TeleportOut", 7000, null, null); + break; + } + case "ScoreBoard": + { + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.FINISH, Util.sortByValue(PLAYER_SCORES))); + break; + } + case "TeleportOut": + { + // Remove event listeners. + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setTeam(Team.NONE); + participant.setOnCustomEvent(false); + participant.leaveParty(); + } + // Destroy world. + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + // Enable players. + for (L2PcInstance participant : PLAYER_LIST) + { + participant.setIsInvul(false); + participant.setIsImmobilized(false); + participant.enableAllSkills(); + for (L2Summon summon : participant.getServitors().values()) + { + summon.setIsInvul(true); + summon.setIsImmobilized(true); + summon.disableAllSkills(); + } + } + EVENT_ACTIVE = false; + break; + } + case "ResurrectPlayer": + { + if (player.isDead() && player.isOnCustomEvent()) + { + if (BLUE_TEAM.contains(player)) + { + player.setIsPendingRevive(true); + player.teleToLocation(BLUE_SPAWN_LOC, false, PVP_WORLD); + } + else if (RED_TEAM.contains(player)) + { + player.setIsPendingRevive(true); + player.teleToLocation(RED_SPAWN_LOC, false, PVP_WORLD); + } + } + break; + } + case "10": + { + broadcastScreenMessage("10", 4); + break; + } + case "9": + { + broadcastScreenMessage("9", 4); + break; + } + case "8": + { + broadcastScreenMessage("8", 4); + break; + } + case "7": + { + broadcastScreenMessage("7", 4); + break; + } + case "6": + { + broadcastScreenMessage("6", 4); + break; + } + case "5": + { + broadcastScreenMessage("5", 4); + break; + } + case "4": + { + broadcastScreenMessage("4", 4); + break; + } + case "3": + { + broadcastScreenMessage("3", 4); + break; + } + case "2": + { + broadcastScreenMessage("2", 4); + break; + } + case "1": + { + broadcastScreenMessage("1", 4); + break; + } + } + // Activity timer. + if (event.startsWith("KickPlayer") && (player != null) && (player.getInstanceWorld() == PVP_WORLD)) + { + player.setTeam(Team.NONE); + PVP_WORLD.ejectPlayer(player); + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + BLUE_TEAM.remove(player); + RED_TEAM.remove(player); + player.setOnCustomEvent(false); + removeListeners(player); + player.sendMessage("You have been kicked for been inactive."); + if (PVP_WORLD != null) + { + broadcastScreenMessageWithEffect("Player " + player.getName() + " was kicked for been inactive.", 7); + } + } + return htmltext; + } + + @Override + public String onFirstTalk(L2Npc npc, L2PcInstance player) + { + // Event not active. + if (!EVENT_ACTIVE) + { + return null; + } + + // Player has already registered. + if (PLAYER_LIST.contains(player)) + { + // Npc is in instance. + if (npc.getInstanceWorld() != null) + { + return "manager-buffheal.html"; + } + return "manager-cancel.html"; + } + // Player is not registered. + return "manager-register.html"; + } + + @Override + public String onEnterZone(L2Character character, L2ZoneType zone) + { + if (character.isPlayable() && character.getActingPlayer().isOnCustomEvent()) + { + // Kick enemy players. + if ((zone == BLUE_PEACE_ZONE) && (character.getTeam() == Team.RED)) + { + character.teleToLocation(RED_SPAWN_LOC, PVP_WORLD); + character.getActingPlayer().sendPacket(new ExShowScreenMessage("Entering the enemy headquarters is prohibited!", ExShowScreenMessage.TOP_CENTER, 10000, 0, true, false)); + } + if ((zone == RED_PEACE_ZONE) && (character.getTeam() == Team.BLUE)) + { + character.teleToLocation(BLUE_SPAWN_LOC, PVP_WORLD); + character.getActingPlayer().sendPacket(new ExShowScreenMessage("Entering the enemy headquarters is prohibited!", ExShowScreenMessage.TOP_CENTER, 10000, 0, true, false)); + } + // Start inactivity check. + if (character.isPlayer() && // + ((((zone == BLUE_PEACE_ZONE) && (character.getTeam() == Team.BLUE)) || // + ((zone == RED_PEACE_ZONE) && (character.getTeam() == Team.RED))))) + { + startQuestTimer("KickPlayer" + character.getObjectId(), PVP_WORLD.getDoor(BLUE_DOOR_ID).isOpen() ? INACTIVITY_TIME * 60000 : (INACTIVITY_TIME * 60000) + (WAIT_TIME * 60000), null, character.getActingPlayer()); + } + } + return null; + } + + @Override + public String onExitZone(L2Character character, L2ZoneType zone) + { + if (character.isPlayer() && character.getActingPlayer().isOnCustomEvent()) + { + cancelQuestTimer("KickPlayer" + character.getObjectId(), null, character.getActingPlayer()); + } + return super.onExitZone(character, zone); + } + + private boolean canRegister(L2PcInstance player) + { + if (PLAYER_LIST.contains(player)) + { + player.sendMessage("You are already registered on this event."); + return false; + } + if (player.getLevel() < MINIMUM_PARTICIPANT_LEVEL) + { + player.sendMessage("Your level is too low to participate."); + return false; + } + if (player.getLevel() > MAXIMUM_PARTICIPANT_LEVEL) + { + player.sendMessage("Your level is too high to participate."); + return false; + } + if (player.isOnEvent() || (player.getBlockCheckerArena() > -1)) + { + player.sendMessage("You are already registered on an event."); + return false; + } + if (PLAYER_LIST.size() >= MAXIMUM_PARTICIPANT_COUNT) + { + player.sendMessage("There are too many players registered on the event."); + return false; + } + if (player.isFlyingMounted()) + { + player.sendMessage("You cannot register on the event while flying."); + return false; + } + if (player.isTransformed()) + { + player.sendMessage("You cannot register on the event while on a transformed state."); + return false; + } + if (!player.isInventoryUnder80(false)) + { + player.sendMessage("There are too many items in your inventory."); + player.sendMessage("Try removing some items."); + return false; + } + if ((player.getWeightPenalty() != 0)) + { + player.sendMessage("Your invetory weight has exceeded the normal limit."); + player.sendMessage("Try removing some items."); + return false; + } + if (player.isCursedWeaponEquipped() || (player.getReputation() < 0)) + { + player.sendMessage("People with bad reputation can't register."); + return false; + } + if (player.isInDuel()) + { + player.sendMessage("You cannot register while on a duel."); + return false; + } + if (player.isInOlympiadMode() || OlympiadManager.getInstance().isRegistered(player)) + { + player.sendMessage("You cannot participate while registered on the Olympiad."); + return false; + } + if (player.isInInstance()) + { + player.sendMessage("You cannot register while in an instance."); + return false; + } + if (player.isInSiege() || player.isInsideZone(ZoneId.SIEGE)) + { + player.sendMessage("You cannot register while on a siege."); + return false; + } + if (player.isFishing()) + { + player.sendMessage("You cannot register while fishing."); + return false; + } + return true; + } + + private void broadcastScreenMessageWithEffect(String message, int duration) + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage(message, ExShowScreenMessage.TOP_CENTER, duration * 1000, 0, true, true)); + } + + private void broadcastScreenMessage(String message, int duration) + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage(message, ExShowScreenMessage.TOP_CENTER, duration * 1000, 0, true, false)); + } + + private void broadcastScoreMessage() + { + PVP_WORLD.broadcastPacket(new ExShowScreenMessage("Blue: " + BLUE_SCORE + " - Red: " + RED_SCORE, ExShowScreenMessage.BOTTOM_RIGHT, 15000, 0, true, false)); + } + + private void addLogoutListener(L2PcInstance player) + { + player.addListener(new ConsumerEventListener(player, EventType.ON_PLAYER_LOGOUT, (OnPlayerLogout event) -> OnPlayerLogout(event), this)); + } + + private void addDeathListener(L2PcInstance player) + { + player.addListener(new ConsumerEventListener(player, EventType.ON_CREATURE_DEATH, (OnCreatureDeath event) -> onPlayerDeath(event), this)); + } + + private void removeListeners(L2PcInstance player) + { + for (AbstractEventListener listener : player.getListeners(EventType.ON_PLAYER_LOGOUT)) + { + if (listener.getOwner() == this) + { + listener.unregisterMe(); + } + } + for (AbstractEventListener listener : player.getListeners(EventType.ON_CREATURE_DEATH)) + { + if (listener.getOwner() == this) + { + listener.unregisterMe(); + } + } + } + + @RegisterEvent(EventType.ON_PLAYER_LOGOUT) + private void OnPlayerLogout(OnPlayerLogout event) + { + final L2PcInstance player = event.getActiveChar(); + if (player != null) + { + PLAYER_LIST.remove(player); + PLAYER_SCORES.remove(player); + BLUE_TEAM.remove(player); + RED_TEAM.remove(player); + } + // If all players left instance end the event. + if (PLAYER_LIST.isEmpty()) + { + // Stop timers. + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Destroy world. + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + } + } + + @RegisterEvent(EventType.ON_CREATURE_DEATH) + public void onPlayerDeath(OnCreatureDeath event) + { + if (event.getTarget().isPlayer()) + { + final L2PcInstance killedPlayer = event.getTarget().getActingPlayer(); + final L2PcInstance killer = event.getAttacker().getActingPlayer(); + // Confirm Blue team kill. + if ((killer.getTeam() == Team.BLUE) && (killedPlayer.getTeam() == Team.RED)) + { + PLAYER_SCORES.put(killer, PLAYER_SCORES.get(killer) + 1); + BLUE_SCORE++; + broadcastScoreMessage(); + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.UPDATE, Util.sortByValue(PLAYER_SCORES))); + } + // Confirm Red team kill. + if ((killer.getTeam() == Team.RED) && (killedPlayer.getTeam() == Team.BLUE)) + { + PLAYER_SCORES.put(killer, PLAYER_SCORES.get(killer) + 1); + RED_SCORE++; + broadcastScoreMessage(); + PVP_WORLD.broadcastPacket(new ExPVPMatchCCRecord(ExPVPMatchCCRecord.UPDATE, Util.sortByValue(PLAYER_SCORES))); + } + // Auto release after 10 seconds. + startQuestTimer("ResurrectPlayer", 10000, null, killedPlayer); + } + } + + @Override + public boolean eventStart(L2PcInstance eventMaker) + { + if (EVENT_ACTIVE) + { + return false; + } + EVENT_ACTIVE = true; + + // Cancel timers. (In case event started immediately after another event finished.) + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Clear player lists. + PLAYER_LIST.clear(); + PLAYER_SCORES.clear(); + BLUE_TEAM.clear(); + RED_TEAM.clear(); + // Spawn event manager. + MANAGER_NPC_INSTANCE = addSpawn(MANAGER, MANAGER_SPAWN_LOC, false, REGISTRATION_TIME * 60000); + startQuestTimer("TeleportToArena", REGISTRATION_TIME * 60000, null, null); + // Send message to players. + Broadcast.toAllOnlinePlayers("TvT Event: Registration opened for " + REGISTRATION_TIME + " minutes."); + Broadcast.toAllOnlinePlayers("TvT Event: You can register at Giran TvT Event Manager."); + + return true; + } + + @Override + public boolean eventStop() + { + if (!EVENT_ACTIVE) + { + return false; + } + EVENT_ACTIVE = false; + + // Despawn event manager. + MANAGER_NPC_INSTANCE.deleteMe(); + // Cancel timers. + for (List timers : getQuestTimers().values()) + { + for (QuestTimer timer : timers) + { + timer.cancel(); + } + } + // Remove participants. + for (L2PcInstance participant : PLAYER_LIST) + { + removeListeners(participant); + participant.setTeam(Team.NONE); + participant.setOnCustomEvent(false); + } + if (PVP_WORLD != null) + { + PVP_WORLD.destroy(); + PVP_WORLD = null; + } + // Send message to players. + Broadcast.toAllOnlinePlayers("TvT Event: Event was canceled."); + return true; + } + + @Override + public boolean eventBypass(L2PcInstance activeChar, String bypass) + { + return false; + } + + public static void main(String[] args) + { + new TvT(); + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html new file mode 100644 index 0000000000..54bbd53443 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-buffheal.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Need assistance?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html new file mode 100644 index 0000000000..6c9101990c --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-cancel.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Cancel your participation?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html new file mode 100644 index 0000000000..2b72e551d8 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-combat.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
You are in combat, calm down...
+
+
+
+
+
+ + diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html new file mode 100644 index 0000000000..c5d7eb5d12 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/manager-register.html @@ -0,0 +1,36 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Do you want to join the event?
+
+
+
+
+
+
+
+ + diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html new file mode 100644 index 0000000000..5b21728486 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-canceled.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration canceled.
+
+
+
+
+
+ + diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html new file mode 100644 index 0000000000..2f3b31f9f6 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-failed.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration failed.
+
+
+
+
+
+ + diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html new file mode 100644 index 0000000000..548a8a1750 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/custom/events/TeamVsTeam/registration-success.html @@ -0,0 +1,33 @@ + + TvT Event + +
+ + + + +
+ + + + + + + +
+ Team vs Team + +
+
+ + + + +
Registration successful!
+
+
+
+
+
+ + diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java index d17921338b..e06f9e07fd 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/admincommandhandlers/AdminZone.java @@ -63,19 +63,23 @@ public class AdminZone implements IAdminCommandHandler getGeoRegionXY(activeChar); activeChar.sendMessage("Closest Town: " + MapRegionManager.getInstance().getClosestTownName(activeChar)); - Location loc; - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CASTLE); - activeChar.sendMessage("TeleToLocation (Castle): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CLANHALL); - activeChar.sendMessage("TeleToLocation (ClanHall): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.SIEGEFLAG); - activeChar.sendMessage("TeleToLocation (SiegeFlag): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); - - loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.TOWN); - activeChar.sendMessage("TeleToLocation (Town): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + // Prevent exit instance variable deletion. + if (!activeChar.isInInstance()) + { + Location loc; + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CASTLE); + activeChar.sendMessage("TeleToLocation (Castle): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.CLANHALL); + activeChar.sendMessage("TeleToLocation (ClanHall): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.SIEGEFLAG); + activeChar.sendMessage("TeleToLocation (SiegeFlag): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + + loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, TeleportWhereType.TOWN); + activeChar.sendMessage("TeleToLocation (Town): x:" + loc.getX() + " y:" + loc.getY() + " z:" + loc.getZ()); + } } else if (actualCommand.equalsIgnoreCase("admin_zone_visual")) { diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/custom/custom.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/custom/custom.xml index 5b2d3489b1..c9b6b84f6c 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/custom/custom.xml +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/custom/custom.xml @@ -1,23 +1,5 @@ - - ELEMENTAL - FEMALE - - - - - - - - - - - - - - - ANIMAL MALE diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/custom/tvt_event.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/custom/tvt_event.xml new file mode 100644 index 0000000000..a867441b79 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/custom/tvt_event.xml @@ -0,0 +1,22 @@ + + + + HUMAN + MALE + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 0627df46b1..57baa3a743 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -672,6 +672,7 @@ public final class L2PcInstance extends L2Playable @SuppressWarnings("rawtypes") private volatile Map, AbstractEvent> _events; + private boolean _isOnCustomEvent = false; public boolean isSpawnProtected() { @@ -8100,7 +8101,12 @@ public final class L2PcInstance extends L2Playable return false; } - // Check if the attacker is in TvT and TvT is started + if (isOnCustomEvent() && (getTeam() == attacker.getTeam())) + { + return false; + } + + // CoC needs this check? if (isOnEvent()) { return true; @@ -13051,12 +13057,26 @@ public final class L2PcInstance extends L2Playable _canRevive = val; } + public boolean isOnCustomEvent() + { + return _isOnCustomEvent; + } + + public void setOnCustomEvent(boolean value) + { + _isOnCustomEvent = value; + } + /** * @return {@code true} if player is on event, {@code false} otherwise. */ @Override public boolean isOnEvent() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) @@ -13072,6 +13092,10 @@ public final class L2PcInstance extends L2Playable public boolean isBlockedFromExit() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) @@ -13087,6 +13111,10 @@ public final class L2PcInstance extends L2Playable public boolean isBlockedFromDeathPenalty() { + if (_isOnCustomEvent) + { + return true; + } if (_events != null) { for (AbstractEvent listener : _events.values()) diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java index c3686c67be..d1bb6ffa75 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanEscape.java @@ -63,6 +63,10 @@ public class ConditionPlayerCanEscape extends Condition { canTeleport = false; } + else if (player.isOnCustomEvent()) + { + canTeleport = false; + } return (_val == canTeleport); } } \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java index 4ed6708e7f..679e38bdb6 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerCanTransform.java @@ -64,6 +64,11 @@ public class ConditionPlayerCanTransform extends Condition player.sendPacket(SystemMessageId.YOU_CANNOT_TRANSFORM_WHILE_RIDING_A_PET); canTransform = false; } + else if (player.isOnCustomEvent()) + { + player.sendMessage("You cannot transform while registered on an event."); + canTransform = false; + } return (_val == canTransform); } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/Instance.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/Instance.java index 77c2468437..70464afd7c 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/Instance.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/Instance.java @@ -888,19 +888,22 @@ public final class Instance implements IIdentifiable, INamable */ public void onDeath(L2PcInstance player) { - // Send message - final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IF_YOU_ARE_NOT_RESURRECTED_WITHIN_S1_MINUTE_S_YOU_WILL_BE_EXPELLED_FROM_THE_INSTANT_ZONE); - sm.addInt(_template.getEjectTime()); - player.sendPacket(sm); - - // Start eject task - _ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.schedule(() -> + if (!player.isOnCustomEvent()) { - if (player.isDead()) + // Send message + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.IF_YOU_ARE_NOT_RESURRECTED_WITHIN_S1_MINUTE_S_YOU_WILL_BE_EXPELLED_FROM_THE_INSTANT_ZONE); + sm.addInt(_template.getEjectTime()); + player.sendPacket(sm); + + // Start eject task + _ejectDeadTasks.put(player.getObjectId(), ThreadPoolManager.schedule(() -> { - ejectPlayer(player.getActingPlayer()); - } - }, _template.getEjectTime() * 60 * 1000)); // minutes to milliseconds + if (player.isDead()) + { + ejectPlayer(player.getActingPlayer()); + } + }, _template.getEjectTime() * 60 * 1000)); // minutes to milliseconds + } } /** diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java index f4fa7592ad..409678ea5a 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/instancezone/InstanceTemplate.java @@ -365,6 +365,7 @@ public class InstanceTemplate extends ListenersContainer implements IIdentifiabl public Location getExitLocation(L2PcInstance player) { Location location = null; + switch (_exitLocationType) { case RANDOM: diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java index 48ba69e327..856a28b865 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/ExIncomingPackets.java @@ -180,8 +180,8 @@ public enum ExIncomingPackets implements IIncomingPackets EX_BOOKMARK_PACKET(0x4E, ExBookmarkPacket::new, ConnectionState.IN_GAME), REQUEST_WITHDRAW_PREMIUM_ITEM(0x4F, RequestWithDrawPremiumItem::new, ConnectionState.IN_GAME), REQUEST_EX_JUMP(0x50, null, ConnectionState.IN_GAME), - REQUEST_EX_START_SHOW_CRATAE_CUBE_RANK(0x51, null, ConnectionState.IN_GAME), - REQUEST_EX_STOP_SHOW_CRATAE_CUBE_RANK(0x52, null, ConnectionState.IN_GAME), + REQUEST_EX_START_SHOW_CRATAE_CUBE_RANK(0x51, RequestStartShowKrateisCubeRank::new, ConnectionState.IN_GAME), + REQUEST_EX_STOP_SHOW_CRATAE_CUBE_RANK(0x52, RequestStopShowKrateisCubeRank::new, ConnectionState.IN_GAME), NOTIFY_START_MINI_GAME(0x53, null, ConnectionState.IN_GAME), REQUEST_EX_JOIN_DOMINION_WAR(0x54, null, ConnectionState.IN_GAME), REQUEST_EX_DOMINION_INFO(0x55, null, ConnectionState.IN_GAME), diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java index 6c7ebff02e..31e80f64fb 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestRestartPoint.java @@ -29,7 +29,10 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.entity.Castle; import com.l2jmobius.gameserver.model.entity.ClanHall; import com.l2jmobius.gameserver.model.entity.Fort; +import com.l2jmobius.gameserver.model.events.EventType; +import com.l2jmobius.gameserver.model.events.listeners.AbstractEventListener; import com.l2jmobius.gameserver.model.instancezone.Instance; +import com.l2jmobius.gameserver.model.quest.Event; import com.l2jmobius.gameserver.model.residences.AbstractResidence; import com.l2jmobius.gameserver.model.residences.ResidenceFunctionType; import com.l2jmobius.gameserver.network.L2GameClient; @@ -92,6 +95,19 @@ public final class RequestRestartPoint implements IClientIncomingPacket return; } + // Custom event resurrection management. + if (activeChar.isOnCustomEvent()) + { + for (AbstractEventListener listener : activeChar.getListeners(EventType.ON_CREATURE_DEATH)) + { + if (listener.getOwner() instanceof Event) + { + ((Event) listener.getOwner()).notifyEvent("ResurrectPlayer", null, activeChar); + return; + } + } + } + final Castle castle = CastleManager.getInstance().getCastle(activeChar.getX(), activeChar.getY(), activeChar.getZ()); if ((castle != null) && castle.getSiege().isInProgress()) { diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java new file mode 100644 index 0000000000..d2213e55b6 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestStartShowKrateisCubeRank.java @@ -0,0 +1,39 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.clientpackets; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; + +/** + * @author Mobius + */ +public class RequestStartShowKrateisCubeRank implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return false; + } + + @Override + public void run(L2GameClient client) + { + // TODO: Implement. + System.out.println("RequestStartShowKrateisCubeRank"); + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java new file mode 100644 index 0000000000..51ca3ea99b --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/RequestStopShowKrateisCubeRank.java @@ -0,0 +1,39 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.clientpackets; + +import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.network.L2GameClient; + +/** + * @author Mobius + */ +public class RequestStopShowKrateisCubeRank implements IClientIncomingPacket +{ + @Override + public boolean read(L2GameClient client, PacketReader packet) + { + return false; + } + + @Override + public void run(L2GameClient client) + { + // TODO: Implement. + System.out.println("RequestStopShowKrateisCubeRank"); + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java new file mode 100644 index 0000000000..57547b985e --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCMyRecord.java @@ -0,0 +1,41 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.serverpackets; + +import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.network.OutgoingPackets; + +/** + * @author Mobius + */ +public class ExPVPMatchCCMyRecord implements IClientOutgoingPacket +{ + private final int _points; + + public ExPVPMatchCCMyRecord(int points) + { + _points = points; + } + + @Override + public boolean write(PacketWriter packet) + { + OutgoingPackets.EX_PVP_MATCH_CCMY_RECORD.writeId(packet); + packet.writeD(_points); + return true; + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java new file mode 100644 index 0000000000..b199a7443c --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/serverpackets/ExPVPMatchCCRecord.java @@ -0,0 +1,57 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.network.serverpackets; + +import java.util.Map; +import java.util.Map.Entry; + +import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.network.OutgoingPackets; + +/** + * @author Mobius + */ +public class ExPVPMatchCCRecord implements IClientOutgoingPacket +{ + public static final int INITIALIZE = 0; + public static final int UPDATE = 1; + public static final int FINISH = 2; + + private final int _state; + private final Map _players; + + public ExPVPMatchCCRecord(int state, Map players) + { + _state = state; + _players = players; + } + + @Override + public boolean write(PacketWriter packet) + { + OutgoingPackets.EX_PVP_MATCH_CCRECORD.writeId(packet); + packet.writeD(_state); // 0 - initialize, 1 - update, 2 - finish + packet.writeD(_players.size()); + for (Entry entry : _players.entrySet()) + { + packet.writeS(entry.getKey().getName()); + packet.writeD(entry.getValue()); + } + return true; + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/util/Util.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/util/Util.java index e551224ab8..850ae469e6 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/util/Util.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/util/Util.java @@ -31,6 +31,8 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; import java.util.logging.Logger; import com.l2jmobius.Config; @@ -788,4 +790,15 @@ public final class Util return (input < min) ? min : (input > max) ? max : input; } + /** + * Short an map by its integer values. + * @param unsortedMap + * @return + */ + public static Map sortByValue(Map unsortedMap) + { + Map sortedMap = new TreeMap<>(new ValueComparator(unsortedMap)); + sortedMap.putAll(unsortedMap); + return sortedMap; + } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/util/ValueComparator.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/util/ValueComparator.java new file mode 100644 index 0000000000..32c494218d --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/util/ValueComparator.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.util; + +import java.util.Comparator; +import java.util.Map; + +/** + * @author Mobius + */ +public class ValueComparator implements Comparator +{ + Map _map; + + public ValueComparator(Map map) + { + _map = map; + } + + @SuppressWarnings( + { + "rawtypes", + "unchecked" + }) + @Override + public int compare(Object keyA, Object keyB) + { + Comparable valueA = (Comparable) _map.get(keyA); + Comparable valueB = (Comparable) _map.get(keyB); + return valueB.compareTo(valueA); + } +}