diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/CastleFlagOfProtection/CastleFlagOfProtection-01.html b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/CastleFlagOfProtection/CastleFlagOfProtection-01.html
new file mode 100644
index 0000000000..9769f89855
--- /dev/null
+++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/CastleFlagOfProtection/CastleFlagOfProtection-01.html
@@ -0,0 +1,3 @@
+
Flag of Protection:
+(Only characters who are performing For Victory sub quest, from the Exalted, One Who Shatters the Limit quest may take the reward.)
+
\ No newline at end of file
diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/CastleFlagOfProtection/CastleFlagOfProtection.html b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/CastleFlagOfProtection/CastleFlagOfProtection.html
new file mode 100644
index 0000000000..414eb410e5
--- /dev/null
+++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/CastleFlagOfProtection/CastleFlagOfProtection.html
@@ -0,0 +1,6 @@
+Flag of Protection:
+(It's a Flag of Protection with the symbol of the castle. It's the same as what Merlot mentioned)
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/CastleFlagOfProtection/CastleFlagOfProtection.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/CastleFlagOfProtection/CastleFlagOfProtection.java
new file mode 100644
index 0000000000..e0cc0abb57
--- /dev/null
+++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/others/CastleFlagOfProtection/CastleFlagOfProtection.java
@@ -0,0 +1,67 @@
+/*
+ * 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 ai.others.CastleFlagOfProtection;
+
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.quest.QuestState;
+
+import ai.AbstractNpcAI;
+
+/**
+ * Castle Flag of Protection AI.
+ * @author CostyKiller
+ */
+public class CastleFlagOfProtection extends AbstractNpcAI
+{
+ // Flag of Protection NPCs
+ private static final int FLAG_GLUDIO = 36741; // 1 Gludio Castle
+ private static final int FLAG_DION = 36742; // 2 Dion Castle
+ private static final int FLAG_GIRAN = 36743; // 3 Giran Castle
+ private static final int FLAG_OREN = 36744; // 4 Oren Castle
+ private static final int FLAG_ADEN = 36745; // 5 Aden Castle
+ private static final int FLAG_INNADRIL = 36746; // 6 Innadril Castle
+ private static final int FLAG_GODDARD = 36747; // 7 Goddard Castle
+ private static final int FLAG_RUNE = 36748; // 8 Rune Castle
+ private static final int FLAG_SCHUTTGART = 36749; // 9 Schuttgart Castle
+
+ private CastleFlagOfProtection()
+ {
+ addFirstTalkId(FLAG_GLUDIO, FLAG_DION, FLAG_GIRAN, FLAG_OREN, FLAG_ADEN, FLAG_INNADRIL, FLAG_GODDARD, FLAG_RUNE, FLAG_SCHUTTGART);
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ String htmltext;
+ final QuestState qs = player.getQuestState("Q10825_ForVictory");
+ if (((qs != null) && qs.isCond(1)))
+ {
+ htmltext = "CastleFlagOfProtection.html";
+ }
+ else
+ {
+ htmltext = "CastleFlagOfProtection-01.html";
+ }
+ return htmltext;
+ }
+
+ public static void main(String[] args)
+ {
+ new CastleFlagOfProtection();
+ }
+}
\ No newline at end of file
diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/SiegeFlagOfProtectionManager.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/SiegeFlagOfProtectionManager.java
new file mode 100644
index 0000000000..798d7c0e4d
--- /dev/null
+++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/SiegeFlagOfProtectionManager.java
@@ -0,0 +1,312 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.gameserver.instancemanager;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.entity.Castle;
+import org.l2jmobius.gameserver.model.events.AbstractScript;
+
+/**
+ * Siege Flag Of Protection Manager.
+ * @author CostyKiller
+ */
+public class SiegeFlagOfProtectionManager
+{
+ private static final Logger LOGGER = Logger.getLogger(SiegeFlagOfProtectionManager.class.getName());
+
+ private static final Map> FLAG_SPAWNS = new ConcurrentHashMap<>();
+
+ // Flag of Protection NPCs
+ private static final int FLAG_GLUDIO = 36741; // 1 Gludio Castle
+ private static final int FLAG_DION = 36742; // 2 Dion Castle
+ private static final int FLAG_GIRAN = 36743; // 3 Giran Castle
+ private static final int FLAG_OREN = 36744; // 4 Oren Castle
+ private static final int FLAG_ADEN = 36745; // 5 Aden Castle
+ private static final int FLAG_INNADRIL = 36746; // 6 Innadril Castle
+ private static final int FLAG_GODDARD = 36747; // 7 Goddard Castle
+ private static final int FLAG_RUNE = 36748; // 8 Rune Castle
+ private static final int FLAG_SCHUTTGART = 36749; // 9 Schuttgart Castle
+
+ // Flag Spawn Positions
+ private static final Location[] FLAG_LOC_GLUDIO =
+ {
+ new Location(-18488, 111080, -2575), // Front
+ new Location(-17736, 107272, -2567), // Back
+ new Location(-18568, 112328, -2509) // Tower
+ };
+ private static final Location[] FLAG_LOC_DION =
+ {
+ new Location(22440, 158632, -2776), // Front
+ new Location(21752, 162488, -2764), // Back
+ new Location(22536, 157432, -2703) // Tower
+ };
+ private static final Location[] FLAG_LOC_GIRAN =
+ {
+ new Location(114840, 144712, -2641), // Front
+ new Location(118664, 145432, -2646), // Back
+ new Location(113608, 144632, -2576) // Tower
+ };
+ private static final Location[] FLAG_LOC_OREN =
+ {
+ new Location(80904, 36824, -2368), // Front
+ new Location(84728, 37512, -2364), // Back
+ new Location(79672, 36728, -2303) // Tower
+ };
+ private static final Location[] FLAG_LOC_ADEN =
+ {
+ new Location(147464, 7240, -472), // Front
+ new Location(149608, 8296, -472), // Right
+ new Location(145304, 8296, -472), // Left
+ new Location(148696, 1832, -472), // Right back
+ new Location(146136, 1848, -472) // Left back
+ };
+ private static final Location[] FLAG_LOC_INNADRIL =
+ {
+ new Location(116392, 247464, -864), // Front
+ new Location(115704, 251272, -862), // Back
+ new Location(116488, 246200, -799) // Tower
+ };
+ private static final Location[] FLAG_LOC_GODDARD =
+ {
+ new Location(147320, -46072, -2087), // Front
+ new Location(148056, -46600, -2386), // Right
+ new Location(146888, -46568, -2386) // Left
+ };
+ private static final Location[] FLAG_LOC_RUNE =
+ {
+ new Location(15960, -48840, -1072), // Front
+ new Location(16616, -50328, -643), // Right
+ new Location(16616, -47976, -642), // Left
+ new Location(13768, -52120, -961), // Right back
+ new Location(13720, -46184, -954) // Left back
+ };
+ private static final Location[] FLAG_LOC_SCHUTTGART =
+ {
+ new Location(77704, -150104, -355), // Front
+ new Location(78168, -150680, -654), // Right
+ new Location(76968, -150632, -654) // Left
+ };
+
+ protected SiegeFlagOfProtectionManager()
+ {
+ }
+
+ /**
+ * Loads all flags of protection for all castles.
+ * @param castle
+ */
+ public void loadFlags(Castle castle)
+ {
+ Spawn spawn = null;
+ switch (castle.getResidenceId())
+ {
+ case 1:
+ {
+ try
+ {
+ spawn = new Spawn(FLAG_GLUDIO);
+ spawn.setXYZ(AbstractScript.getRandomEntry(FLAG_LOC_GLUDIO));
+ getSpawnedFlags(castle.getResidenceId()).add(spawn);
+ }
+ catch (ClassNotFoundException | NoSuchMethodException | ClassCastException e)
+ {
+ e.printStackTrace();
+ }
+ break;
+ }
+ case 2:
+ {
+ try
+ {
+ spawn = new Spawn(FLAG_DION);
+ spawn.setXYZ(AbstractScript.getRandomEntry(FLAG_LOC_DION));
+ getSpawnedFlags(castle.getResidenceId()).add(spawn);
+ }
+ catch (ClassNotFoundException | NoSuchMethodException | ClassCastException e)
+ {
+ e.printStackTrace();
+ }
+ break;
+ }
+ case 3:
+ {
+ try
+ {
+ spawn = new Spawn(FLAG_GIRAN);
+ spawn.setXYZ(AbstractScript.getRandomEntry(FLAG_LOC_GIRAN));
+ getSpawnedFlags(castle.getResidenceId()).add(spawn);
+ }
+ catch (ClassNotFoundException | NoSuchMethodException | ClassCastException e)
+ {
+ e.printStackTrace();
+ }
+ break;
+ }
+ case 4:
+ {
+ try
+ {
+ spawn = new Spawn(FLAG_OREN);
+ spawn.setXYZ(AbstractScript.getRandomEntry(FLAG_LOC_OREN));
+ getSpawnedFlags(castle.getResidenceId()).add(spawn);
+ }
+ catch (ClassNotFoundException | NoSuchMethodException | ClassCastException e)
+ {
+ e.printStackTrace();
+ }
+ break;
+ }
+ case 5:
+ {
+ try
+ {
+ spawn = new Spawn(FLAG_ADEN);
+ spawn.setXYZ(AbstractScript.getRandomEntry(FLAG_LOC_ADEN));
+ getSpawnedFlags(castle.getResidenceId()).add(spawn);
+ }
+ catch (ClassNotFoundException | NoSuchMethodException | ClassCastException e)
+ {
+ e.printStackTrace();
+ }
+ break;
+ }
+ case 6:
+ {
+ try
+ {
+ spawn = new Spawn(FLAG_INNADRIL);
+ spawn.setXYZ(AbstractScript.getRandomEntry(FLAG_LOC_INNADRIL));
+ getSpawnedFlags(castle.getResidenceId()).add(spawn);
+ }
+ catch (ClassNotFoundException | NoSuchMethodException | ClassCastException e)
+ {
+ e.printStackTrace();
+ }
+ break;
+ }
+ case 7:
+ {
+ try
+ {
+ spawn = new Spawn(FLAG_GODDARD);
+ spawn.setXYZ(AbstractScript.getRandomEntry(FLAG_LOC_GODDARD));
+ getSpawnedFlags(castle.getResidenceId()).add(spawn);
+ }
+ catch (ClassNotFoundException | NoSuchMethodException | ClassCastException e)
+ {
+ e.printStackTrace();
+ }
+ break;
+ }
+ case 8:
+ {
+ try
+ {
+ spawn = new Spawn(FLAG_RUNE);
+ spawn.setXYZ(AbstractScript.getRandomEntry(FLAG_LOC_RUNE));
+ getSpawnedFlags(castle.getResidenceId()).add(spawn);
+ }
+ catch (ClassNotFoundException | NoSuchMethodException | ClassCastException e)
+ {
+ e.printStackTrace();
+ }
+ break;
+ }
+ case 9:
+ {
+ try
+ {
+ spawn = new Spawn(FLAG_SCHUTTGART);
+ spawn.setXYZ(AbstractScript.getRandomEntry(FLAG_LOC_SCHUTTGART));
+ getSpawnedFlags(castle.getResidenceId()).add(spawn);
+ }
+ catch (ClassNotFoundException | NoSuchMethodException | ClassCastException e)
+ {
+ e.printStackTrace();
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * Spawn flag of protection for castle.
+ * @param castle the castle instance
+ */
+ public void spawnFlag(Castle castle)
+ {
+ try
+ {
+ loadFlags(castle);
+
+ for (Spawn spawn : getSpawnedFlags(castle.getResidenceId()))
+ {
+ if (spawn != null)
+ {
+ spawn.doSpawn();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ LOGGER.log(Level.SEVERE, "Error spawning flag of protection for castle " + castle.getName(), e);
+ }
+ }
+
+ /**
+ * Unspawn flag of protection for castle.
+ * @param castle the castle instance
+ */
+ public void unspawnFlag(Castle castle)
+ {
+ for (Spawn spawn : getSpawnedFlags(castle.getResidenceId()))
+ {
+ if ((spawn != null) && (spawn.getLastSpawn() != null))
+ {
+ spawn.stopRespawn();
+ spawn.getLastSpawn().doDie(spawn.getLastSpawn());
+ }
+ }
+ getSpawnedFlags(castle.getResidenceId()).clear();
+ }
+
+ public Set getSpawnedFlags(int castleId)
+ {
+ return FLAG_SPAWNS.computeIfAbsent(castleId, key -> ConcurrentHashMap.newKeySet());
+ }
+
+ /**
+ * Gets the single instance of {@code SiegeFlagOfProtectionManager}.
+ * @return single instance of {@code SiegeFlagOfProtectionManager}
+ */
+ public static SiegeFlagOfProtectionManager getInstance()
+ {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final SiegeFlagOfProtectionManager INSTANCE = new SiegeFlagOfProtectionManager();
+ }
+}
diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/entity/Siege.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/entity/Siege.java
index 4287c3d04c..21e58966fe 100644
--- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/entity/Siege.java
+++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/entity/Siege.java
@@ -40,6 +40,7 @@ import org.l2jmobius.gameserver.enums.SiegeClanType;
import org.l2jmobius.gameserver.enums.SiegeTeleportWhoType;
import org.l2jmobius.gameserver.enums.TeleportWhereType;
import org.l2jmobius.gameserver.instancemanager.CastleManager;
+import org.l2jmobius.gameserver.instancemanager.SiegeFlagOfProtectionManager;
import org.l2jmobius.gameserver.instancemanager.SiegeGuardManager;
import org.l2jmobius.gameserver.instancemanager.SiegeManager;
import org.l2jmobius.gameserver.model.PlayerCondOverride;
@@ -329,6 +330,7 @@ public class Siege implements Siegable
saveCastleSiege(); // Save castle specific data
clearSiegeClan(); // Clear siege clan from db
removeTowers(); // Remove all towers from this castle
+ SiegeFlagOfProtectionManager.getInstance().unspawnFlag(getCastle()); // Remove spawned flag of protection
SiegeGuardManager.getInstance().unspawnSiegeGuard(getCastle()); // Remove all spawned siege guard from this castle
if (_castle.getOwnerId() > 0)
{
@@ -503,6 +505,7 @@ public class Siege implements Siegable
spawnControlTower(); // Spawn control tower
spawnFlameTower(); // Spawn control tower
_castle.spawnDoor(); // Spawn door
+ SiegeFlagOfProtectionManager.getInstance().spawnFlag(getCastle()); // Spawn flag of protection
spawnSiegeGuard(); // Spawn siege guard
SiegeGuardManager.getInstance().deleteTickets(getCastle().getResidenceId()); // remove the tickets from the ground
_castle.getZone().setSiegeInstance(this);