diff --git a/L2J_DataPack/dist/game/config/adminCommands.xml b/L2J_DataPack/dist/game/config/adminCommands.xml
index dce17b54b3b4e0dead20ea478a869c5b57511572..d4fe5938b8b2d58f306b77a85acdbfa956a49b8a 100644
--- a/L2J_DataPack/dist/game/config/adminCommands.xml
+++ b/L2J_DataPack/dist/game/config/adminCommands.xml
@@ -29,22 +29,10 @@
 	<admin command="admin_gmon" accessLevel="7" />
 
 	<!-- ADMIN ANNOUNCEMENTS -->
-	<admin command="admin_list_announcements" accessLevel="7" />
-	<admin command="admin_list_critannouncements" accessLevel="7" />
-	<admin command="admin_reload_announcements" accessLevel="7" />
-	<admin command="admin_announce_announcements" accessLevel="7" />
-	<admin command="admin_add_announcement" accessLevel="7" />
-	<admin command="admin_del_announcement" accessLevel="7" />
-	<admin command="admin_add_critannouncement" accessLevel="7" />
-	<admin command="admin_del_critannouncement" accessLevel="7" />
 	<admin command="admin_announce" accessLevel="7" />
-	<admin command="admin_critannounce" accessLevel="7" />
-	<admin command="admin_announce_menu" accessLevel="7" />
-	<admin command="admin_critannounce_menu" accessLevel="7" />
-	<admin command="admin_list_autoann" accessLevel="7" />
-	<admin command="admin_reload_autoann" accessLevel="7" />
-	<admin command="admin_add_autoann" accessLevel="7" />
-	<admin command="admin_del_autoann" accessLevel="7" />
+	<admin command="admin_announce_crit" accessLevel="7" />
+	<admin command="admin_announce_screen" accessLevel="7" />
+	<admin command="admin_announces" accessLevel="7" />
 
 	<!-- ADMIN BAN -->
 	<admin command="admin_punishment" accessLevel="7" />
diff --git a/L2J_DataPack/dist/game/data/announcements.txt b/L2J_DataPack/dist/game/data/announcements.txt
deleted file mode 100644
index 51bcba0912ccbef16fc4ad84c276bbcd78a1f1fb..0000000000000000000000000000000000000000
--- a/L2J_DataPack/dist/game/data/announcements.txt
+++ /dev/null
@@ -1 +0,0 @@
-Thanks for using L2J.
\ No newline at end of file
diff --git a/L2J_DataPack/dist/game/data/critannouncements.txt b/L2J_DataPack/dist/game/data/critannouncements.txt
deleted file mode 100644
index 498e6285a79d5b684320086362fd101473947bc1..0000000000000000000000000000000000000000
--- a/L2J_DataPack/dist/game/data/critannouncements.txt
+++ /dev/null
@@ -1 +0,0 @@
-http://www.l2jserver.com
\ No newline at end of file
diff --git a/L2J_DataPack/dist/game/data/html/admin/announces-add.htm b/L2J_DataPack/dist/game/data/html/admin/announces-add.htm
new file mode 100644
index 0000000000000000000000000000000000000000..d43a758abd8dc6c624b63b26902e8742ffd33c7e
--- /dev/null
+++ b/L2J_DataPack/dist/game/data/html/admin/announces-add.htm
@@ -0,0 +1,49 @@
+<html noscrollbar>
+	<body>
+		<center>
+			<br>
+			<table border="0" cellpadding="0" cellspacing="0" width="97%" height="480" background="L2UI_CH3.refinewnd_back_Pattern">
+				<tr>
+					<td valign="top" align="center">
+						<table border="0" cellpadding="0" cellspacing="0">
+							<tr>
+								<td width="256" height="185" background="L2UI_CT1.OlympiadWnd_DF_GrandTexture"></td>
+							</tr>
+						</table>
+						Add announcement:<br1>
+						<table width=600 height=210 cellspacing=5 background="L2UI_CT1.Windows.Windows_DF_TooltipBG">
+							<tr>
+								<td width="200">Type</td>
+								<td width="420"><combobox width=200 height=17 var="typeBox" list="NORMAL;CRITICAL;AUTO_NORMAL;AUTO_CRITICAL"></td>
+							</tr>
+							<tr>
+								<td width="200">Initial Delay in sec</td>
+								<td width="420"><edit var="autoann_initdelay" width=200 height=12 type=number></td>
+							</tr>
+							<tr>
+								<td width="200">Delay in sec</td>
+								<td width="420"><edit var="autoann_delay" width=200 height=12 type=number></td>
+							</tr>
+							<tr>
+								<td width="200">Repeat (0 for infinite):</td>
+								<td width="420"><edit var="autoann_repeat" width=200 height=12 type=number></td>
+							</tr>
+							<tr>
+								<td width="200">Text:</td>
+								<td width="420"><multiedit var="autoann_memo" width=200 height=100></td>
+							</tr>
+						</table>
+						<center>
+							<table>
+								<tr>
+									<td><button value="Add" action="bypass -h admin_announces add $typeBox $autoann_initdelay $autoann_delay $autoann_repeat $autoann_memo" width="70" height="21" back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+									<td><button value="Back" action="bypass -h admin_announces list" width="70" height="21" back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+								</tr>
+							</table>
+						</center>
+					</td>
+				</tr>
+			</table>
+		</center>
+	</body>
+</html>
\ No newline at end of file
diff --git a/L2J_DataPack/dist/game/data/html/admin/announces-edit.htm b/L2J_DataPack/dist/game/data/html/admin/announces-edit.htm
new file mode 100644
index 0000000000000000000000000000000000000000..4c81413ca3b17d8b0e2f9f64b364e86dbc0fb4df
--- /dev/null
+++ b/L2J_DataPack/dist/game/data/html/admin/announces-edit.htm
@@ -0,0 +1,54 @@
+<html noscrollbar>
+	<body>
+		<center>
+			<br>
+			<table border="0" cellpadding="0" cellspacing="0" width="97%" height="480" background="L2UI_CH3.refinewnd_back_Pattern">
+				<tr>
+					<td valign="top" align="center">
+						<table border="0" cellpadding="0" cellspacing="0">
+							<tr>
+								<td width="256" height="185" background="L2UI_CT1.OlympiadWnd_DF_GrandTexture"></td>
+							</tr>
+						</table>
+						Edit announcements: %id%<br1>
+						<table width=600 height=210 cellspacing=5 background="L2UI_CT1.Windows.Windows_DF_TooltipBG">
+							<tr>
+								<td width="200">Type</td>
+								<td width="200"><combobox width=200 height=17 var="typeBox" list="NORMAL;CRITICAL;AUTO_NORMAL;AUTO_CRITICAL" sel="%type%"></td>
+								<td width="200">%type%</td>
+							</tr>
+							<tr>
+								<td width="200">Initial Delay in sec</td>
+								<td width="200"><edit var="autoann_initdelay" width=200 height=12 type=number></td>
+								<td width="200">%initial%</td>
+							</tr>
+							<tr>
+								<td width="200">Delay in sec</td>
+								<td width="200"><edit var="autoann_delay" width=200 height=12 type=number></td>
+								<td width="200">%delay%</td>
+							</tr>
+							<tr>
+								<td width="200">Repeat (0 for infinite):</td>
+								<td width="200"><edit var="autoann_repeat" width=200 height=12 type=number></td>
+								<td width="200">%repeat%</td>
+							</tr>
+							<tr>
+								<td width="200">Text:</td>
+								<td width="200"><multiedit var="autoann_memo" width=200 height=100></td>
+								<td width="200">%content%</td>
+							</tr>
+						</table>
+						<center>
+							<table>
+								<tr>
+									<td><button value="Edit" action="bypass -h admin_announces edit %id% $typeBox $autoann_initdelay $autoann_delay $autoann_repeat $autoann_memo" width="70" height="21" back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+									<td><button value="Back" action="bypass -h admin_announces list" width="70" height="21" back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+								</tr>
+							</table>
+						</center>
+					</td>
+				</tr>
+			</table>
+		</center>
+	</body>
+</html>
\ No newline at end of file
diff --git a/L2J_DataPack/dist/game/data/html/admin/announces-list.htm b/L2J_DataPack/dist/game/data/html/admin/announces-list.htm
new file mode 100644
index 0000000000000000000000000000000000000000..4ac80712baddd682e49948c6480c32b1fcdf50a1
--- /dev/null
+++ b/L2J_DataPack/dist/game/data/html/admin/announces-list.htm
@@ -0,0 +1,48 @@
+<html noscrollbar>
+	<body>
+		<center>
+			<br>
+			<table border="0" cellpadding="0" cellspacing="0" width="97%" height="480" background="L2UI_CH3.refinewnd_back_Pattern">
+				<tr>
+					<td valign="top" align="center">
+						<table border="0" cellpadding="0" cellspacing="0">
+							<tr>
+								<td width="256" height="185" background="L2UI_CT1.OlympiadWnd_DF_GrandTexture"></td>
+							</tr>
+						</table>
+						Announcements:<br1>
+						<table width="690" height="20" cellspacing="5" background="L2UI_CT1.Button_DF_Calculator">
+							<tr>
+								<td width="5"></td>
+								<td width="80">Id</td>
+								<td width="100">Type</td>
+								<td width="100">Author</td>
+								<td width="60">Restart</td>
+								<td width="60">Show</td>
+								<td width="60">Edit</td>
+								<td width="60">Remove</td>
+								<td width="5"></td>
+							</tr>
+						</table>
+						<table width="690" height="20" cellspacing="2" background="L2UI_CT1.Windows.Windows_DF_TooltipBG">
+							%announcements%
+						</table>
+						<center>
+							<table width=280 cellspacing=0>
+								<tr>
+									%pages%
+								</tr>
+							</table>
+							<table>
+								<tr>
+									<td><button value="Add" action="bypass -h admin_announces add" width="70" height="21" back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+									<td><button value="Restart" action="bypass -h admin_announces restart" width="70" height="21" back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+								</tr>
+							</table>
+						</center>
+					</td>
+				</tr>
+			</table>
+		</center>
+	</body>
+</html>
\ No newline at end of file
diff --git a/L2J_DataPack/dist/game/data/html/admin/announces-show.htm b/L2J_DataPack/dist/game/data/html/admin/announces-show.htm
new file mode 100644
index 0000000000000000000000000000000000000000..ef876d86c9964737e7ffadaf9b7a792554538979
--- /dev/null
+++ b/L2J_DataPack/dist/game/data/html/admin/announces-show.htm
@@ -0,0 +1,54 @@
+<html noscrollbar>
+	<body>
+		<center>
+			<br>
+			<table border="0" cellpadding="0" cellspacing="0" width="97%" height="480" background="L2UI_CH3.refinewnd_back_Pattern">
+				<tr>
+					<td valign="top" align="center">
+						<table border="0" cellpadding="0" cellspacing="0">
+							<tr>
+								<td width="256" height="185" background="L2UI_CT1.OlympiadWnd_DF_GrandTexture"></td>
+							</tr>
+						</table>
+						Announcement: %id%<br1>
+						<table width=600 height=185 cellspacing=5 background="L2UI_CT1.Windows.Windows_DF_TooltipBG">
+							<tr>
+								<td>Type</td>
+								<td>%type%</td>
+							</tr>
+							<tr>
+								<td>Initial Delay</td>
+								<td>%initial%</td>
+							</tr>
+							<tr>
+								<td>Delay</td>
+								<td>%delay%</td>
+							</tr>
+							<tr>
+								<td>Repeat:</td>
+								<td>%repeat%</td>
+							</tr>
+							<tr>
+								<td>Author:</td>
+								<td>%author%</td>
+							</tr>
+							<tr>
+								<td>Text:</td>
+								<td>%content%</td>
+							</tr>
+						</table>
+						<center>
+							<table>
+								<tr>
+									<td><button value="Remove" action="bypass -h admin_announces remove %id%" width="70" height="21" back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+									<td><button value="Restart" action="bypass -h admin_announces restart %id" width="70" height="21" back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+									<td><button value="Back" action="bypass -h admin_announces list" width="70" height="21" back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+								</tr>
+							</table>
+						</center>
+					</td>
+				</tr>
+			</table>
+		</center>
+	</body>
+</html>
\ No newline at end of file
diff --git a/L2J_DataPack/dist/game/data/html/admin/gm_menu.htm b/L2J_DataPack/dist/game/data/html/admin/gm_menu.htm
index 5c5276b5ca5acd89a8fb373dc4bc5ac8816bfa58..adf95f0fd732ade0f18f69db85b7958085fc258f 100644
--- a/L2J_DataPack/dist/game/data/html/admin/gm_menu.htm
+++ b/L2J_DataPack/dist/game/data/html/admin/gm_menu.htm
@@ -26,8 +26,7 @@
 <td><button value="TradeOff" action="bypass -h admin_tradeoff" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
 <td><button value="Invul" action="bypass -h admin_invul" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
 </tr><tr>
-<td><button value="Announc" action="bypass -h admin_list_announcements" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
-<td><button value="AutoAnn" action="bypass -h admin_list_autoann $qbox" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+<td><button value="Announces" action="bypass -h admin_announces" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
 <td><button value="Enhance" action="bypass -h admin_enchant" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
 <td><button value="GM Shop" action="bypass -h admin_gmshop" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
 </tr><tr>
@@ -47,9 +46,10 @@
 </tr></table><br>
 <center><multiedit var="new_announcement" width=250 height=50></center>
 <table width="160"><tr>
-<td><button value="Announce" action="bypass -h admin_announce_menu $new_announcement" width=95 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
-<td><button value="Crit. Announce" action="bypass -h admin_critannounce_menu $new_announcement" width=95 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
-<td><button value="GM Chat" action="bypass -h admin_gmchat_menu $new_announcement" width=95 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+<td><button value="Announce" action="bypass -h admin_announce $new_announcement" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+<td><button value="Critical" action="bypass -h admin_announce_crit $new_announcement" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+<td><button value="On-Screen" action="bypass -h admin_announce_screen $new_announcement" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
+<td><button value="GM Chat" action="bypass -h admin_gmchat_menu $new_announcement" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
 </tr></table><br>
 <table width=270><tr>
 <td><button value="Fenrir" action="bypass -h admin_ride_wolf" width=65 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>
diff --git a/L2J_DataPack/dist/game/data/html/admin/server_menu.htm b/L2J_DataPack/dist/game/data/html/admin/server_menu.htm
index b8521c6645d9399d0bf30f95982d10d7aa891875..f079f6dd7b071737d0c327d8c1bd258cb070a8cf 100644
--- a/L2J_DataPack/dist/game/data/html/admin/server_menu.htm
+++ b/L2J_DataPack/dist/game/data/html/admin/server_menu.htm
@@ -56,7 +56,7 @@ Maintenance:<br1>
 </table>
 </center>
 <br>
-<button value="Announcements" action="bypass -h admin_announce_announcements" width=130 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF">
+<button value="Announcements" action="bypass -h admin_announces" width=130 height=21 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF">
 <br><br>
 Geodata:<br1>
 <table width=270><tr>
diff --git a/L2J_DataPack/dist/game/data/scripts/conquerablehalls/RainbowSpringsChateau/RainbowSpringsChateau.java b/L2J_DataPack/dist/game/data/scripts/conquerablehalls/RainbowSpringsChateau/RainbowSpringsChateau.java
index 6cd3210e8f192921200b52e0c9c4f58943d74315..468a9de8c956954801daa2d67afb052a2dbfbd43 100644
--- a/L2J_DataPack/dist/game/data/scripts/conquerablehalls/RainbowSpringsChateau/RainbowSpringsChateau.java
+++ b/L2J_DataPack/dist/game/data/scripts/conquerablehalls/RainbowSpringsChateau/RainbowSpringsChateau.java
@@ -32,7 +32,6 @@ import java.util.concurrent.ScheduledFuture;
 
 import com.l2jserver.Config;
 import com.l2jserver.L2DatabaseFactory;
-import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.cache.HtmCache;
 import com.l2jserver.gameserver.datatables.ClanTable;
@@ -57,6 +56,7 @@ import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.network.clientpackets.Say2;
 import com.l2jserver.gameserver.network.serverpackets.NpcSay;
+import com.l2jserver.gameserver.util.Broadcast;
 import com.l2jserver.gameserver.util.Util;
 
 /**
@@ -124,7 +124,7 @@ public final class RainbowSpringsChateau extends ClanHallSiegeEngine
 				}
 				else
 				{
-					Announcements.getInstance().announceToAll("Rainbow Springs Chateau siege aborted due lack of population");
+					Broadcast.toAllOnlinePlayers("Rainbow Springs Chateau siege aborted due lack of population");
 				}
 			}
 		}
diff --git a/L2J_DataPack/dist/game/data/scripts/conquerablehalls/flagwar/FlagWar.java b/L2J_DataPack/dist/game/data/scripts/conquerablehalls/flagwar/FlagWar.java
index a4773b98b34e33e0073c6e16b48a8357d693aa23..b12bff34954c3b7da7624acd1fd9dff84ae376d0 100644
--- a/L2J_DataPack/dist/game/data/scripts/conquerablehalls/flagwar/FlagWar.java
+++ b/L2J_DataPack/dist/game/data/scripts/conquerablehalls/flagwar/FlagWar.java
@@ -28,7 +28,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import com.l2jserver.L2DatabaseFactory;
-import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.ai.L2SpecialSiegeGuardAI;
@@ -52,6 +51,7 @@ import com.l2jserver.gameserver.model.zone.type.L2ResidenceHallTeleportZone;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.util.Broadcast;
 
 /**
  * @author BiggBoss
@@ -458,7 +458,7 @@ public abstract class FlagWar extends ClanHallSiegeEngine
 		_hall.banishForeigners();
 		SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.REGISTRATION_TERM_FOR_S1_ENDED);
 		msg.addString(getName());
-		Announcements.getInstance().announceToAll(msg);
+		Broadcast.toAllOnlinePlayers(msg);
 		_hall.updateSiegeStatus(SiegeStatus.WAITING_BATTLE);
 		
 		_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new SiegeStarts(), 3600000);
@@ -474,7 +474,7 @@ public abstract class FlagWar extends ClanHallSiegeEngine
 			_hall.updateNextSiege();
 			SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SIEGE_OF_S1_HAS_BEEN_CANCELED_DUE_TO_LACK_OF_INTEREST);
 			sm.addString(_hall.getName());
-			Announcements.getInstance().announceToAll(sm);
+			Broadcast.toAllOnlinePlayers(sm);
 			return;
 		}
 		
diff --git a/L2J_DataPack/dist/game/data/scripts/custom/events/Elpies/Elpies.java b/L2J_DataPack/dist/game/data/scripts/custom/events/Elpies/Elpies.java
index c697c98457cdf990038ed3adc9fae290d81ebca8..92f9e64c2bd439df64b53ab0e11a4c81e32988c0 100644
--- a/L2J_DataPack/dist/game/data/scripts/custom/events/Elpies/Elpies.java
+++ b/L2J_DataPack/dist/game/data/scripts/custom/events/Elpies/Elpies.java
@@ -21,7 +21,6 @@ package custom.events.Elpies;
 import java.util.concurrent.ScheduledFuture;
 
 import com.l2jserver.Config;
-import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.datatables.SpawnTable;
 import com.l2jserver.gameserver.model.L2Spawn;
@@ -29,6 +28,7 @@ import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2EventMonsterInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.quest.Event;
+import com.l2jserver.gameserver.util.Broadcast;
 
 public final class Elpies extends Event
 {
@@ -110,19 +110,15 @@ public final class Elpies extends Event
 			CURRENT_ELPY_COUNT++;
 		}
 		
-		Announcements.getInstance().announceToAll("*Squeak Squeak*");
-		Announcements.getInstance().announceToAll("Elpy invasion in " + randomLoc.getName());
-		Announcements.getInstance().announceToAll("Help us exterminate them!");
-		Announcements.getInstance().announceToAll("You have " + EVENT_DURATION_MINUTES + " minutes!");
+		Broadcast.toAllOnlinePlayers("*Squeak Squeak*");
+		Broadcast.toAllOnlinePlayers("Elpy invasion in " + randomLoc.getName());
+		Broadcast.toAllOnlinePlayers("Help us exterminate them!");
+		Broadcast.toAllOnlinePlayers("You have " + EVENT_DURATION_MINUTES + " minutes!");
 		
-		_eventTask = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
+		_eventTask = ThreadPoolManager.getInstance().scheduleGeneral(() ->
 		{
-			@Override
-			public void run()
-			{
-				Announcements.getInstance().announceToAll("Time is up!");
-				eventStop();
-			}
+			Broadcast.toAllOnlinePlayers("Time is up!");
+			eventStop();
 		}, despawnDelay);
 		return true;
 	}
@@ -152,8 +148,8 @@ public final class Elpies extends Event
 			}
 		}
 		
-		Announcements.getInstance().announceToAll("*Squeak Squeak*");
-		Announcements.getInstance().announceToAll("Elpy Event finished!");
+		Broadcast.toAllOnlinePlayers("*Squeak Squeak*");
+		Broadcast.toAllOnlinePlayers("Elpy Event finished!");
 		return true;
 	}
 	
@@ -168,7 +164,7 @@ public final class Elpies extends Event
 			
 			if (CURRENT_ELPY_COUNT <= 0)
 			{
-				Announcements.getInstance().announceToAll("All elpies have been killed!");
+				Broadcast.toAllOnlinePlayers("All elpies have been killed!");
 				eventStop();
 			}
 		}
diff --git a/L2J_DataPack/dist/game/data/scripts/custom/events/Rabbits/Rabbits.java b/L2J_DataPack/dist/game/data/scripts/custom/events/Rabbits/Rabbits.java
index c75ca8f6a4bbc7ea78cf510db9bb847ff2d57df4..a667d75b78767a81115bf24b117a4eae85fad238 100644
--- a/L2J_DataPack/dist/game/data/scripts/custom/events/Rabbits/Rabbits.java
+++ b/L2J_DataPack/dist/game/data/scripts/custom/events/Rabbits/Rabbits.java
@@ -23,13 +23,13 @@ import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import com.l2jserver.Config;
-import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.holders.SkillHolder;
 import com.l2jserver.gameserver.model.quest.Event;
 import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.util.Broadcast;
 import com.l2jserver.gameserver.util.Util;
 
 /**
@@ -115,10 +115,10 @@ public final class Rabbits extends Event
 		}
 		
 		// Announce event start
-		Announcements.getInstance().announceToAll("Rabbits Event: Chests spawned!");
-		Announcements.getInstance().announceToAll("Rabbits Event: Go to Fantasy Isle and grab some rewards!");
-		Announcements.getInstance().announceToAll("Rabbits Event: You have " + EVENT_TIME + " minuntes!");
-		Announcements.getInstance().announceToAll("Rabbits Event: After that time all chests will disappear...");
+		Broadcast.toAllOnlinePlayers("Rabbits Event: Chests spawned!");
+		Broadcast.toAllOnlinePlayers("Rabbits Event: Go to Fantasy Isle and grab some rewards!");
+		Broadcast.toAllOnlinePlayers("Rabbits Event: You have " + EVENT_TIME + " minuntes!");
+		Broadcast.toAllOnlinePlayers("Rabbits Event: After that time all chests will disappear...");
 		// Schedule event end
 		startQuestTimer("END_RABBITS_EVENT", EVENT_TIME * 60000, null, eventMaker);
 		return true;
@@ -159,7 +159,7 @@ public final class Rabbits extends Event
 		_players.clear();
 		
 		// Announce event end
-		Announcements.getInstance().announceToAll("Rabbits Event: Event has finished.");
+		Broadcast.toAllOnlinePlayers("Rabbits Event: Event has finished.");
 		
 		return true;
 	}
@@ -188,7 +188,7 @@ public final class Rabbits extends Event
 			}
 			case "END_RABBITS_EVENT":
 			{
-				Announcements.getInstance().announceToAll("Rabbits Event: Time up!");
+				Broadcast.toAllOnlinePlayers("Rabbits Event: Time up!");
 				eventStop();
 				break;
 			}
@@ -215,7 +215,7 @@ public final class Rabbits extends Event
 				
 				if (_npcs.size() <= 1)
 				{
-					Announcements.getInstance().announceToAll("Rabbits Event: No more chests...");
+					Broadcast.toAllOnlinePlayers("Rabbits Event: No more chests...");
 					eventStop();
 				}
 			}
diff --git a/L2J_DataPack/dist/game/data/scripts/custom/events/Race/Race.java b/L2J_DataPack/dist/game/data/scripts/custom/events/Race/Race.java
index bb57ab1ddc47f60f4a9bb13810b842e5f089d20f..8260e360c65e1f8eb70a99b32568b965f7197fa3 100644
--- a/L2J_DataPack/dist/game/data/scripts/custom/events/Race/Race.java
+++ b/L2J_DataPack/dist/game/data/scripts/custom/events/Race/Race.java
@@ -24,7 +24,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ScheduledFuture;
 
 import com.l2jserver.Config;
-import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.datatables.SkillData;
 import com.l2jserver.gameserver.model.actor.L2Npc;
@@ -35,6 +34,7 @@ import com.l2jserver.gameserver.model.skills.AbnormalType;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
 import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.util.Broadcast;
 
 /**
  * @author Gnacik
@@ -136,8 +136,8 @@ public final class Race extends Event
 		_npc = recordSpawn(_start_npc, 18429, 145861, -3090, 0, false, 0);
 		
 		// Announce event start
-		Announcements.getInstance().announceToAll("* Race Event started! *");
-		Announcements.getInstance().announceToAll("Visit Event Manager in Dion village and signup, you have " + _time_register + " min before Race Start...");
+		Broadcast.toAllOnlinePlayers("* Race Event started! *");
+		Broadcast.toAllOnlinePlayers("Visit Event Manager in Dion village and signup, you have " + _time_register + " min before Race Start...");
 		
 		// Schedule Event end
 		_eventTask = ThreadPoolManager.getInstance().scheduleGeneral(() -> StartRace(), _time_register * 60 * 1000);
@@ -151,14 +151,14 @@ public final class Race extends Event
 		// Abort race if no players signup
 		if (_players.isEmpty())
 		{
-			Announcements.getInstance().announceToAll("Race aborted, nobody signup.");
+			Broadcast.toAllOnlinePlayers("Race aborted, nobody signup.");
 			eventStop();
 			return;
 		}
 		// Set state
 		_isRaceStarted = true;
 		// Announce
-		Announcements.getInstance().announceToAll("Race started!");
+		Broadcast.toAllOnlinePlayers("Race started!");
 		// Get random Finish
 		int location = getRandom(0, _locations.length - 1);
 		_randspawn = _coords[location];
@@ -226,7 +226,7 @@ public final class Race extends Event
 		_npclist.clear();
 		_players.clear();
 		// Announce event end
-		Announcements.getInstance().announceToAll("* Race Event finished *");
+		Broadcast.toAllOnlinePlayers("* Race Event finished *");
 		
 		return true;
 	}
@@ -394,7 +394,7 @@ public final class Race extends Event
 	
 	protected void timeUp()
 	{
-		Announcements.getInstance().announceToAll("Time up, nobody wins!");
+		Broadcast.toAllOnlinePlayers("Time up, nobody wins!");
 		eventStop();
 	}
 	
@@ -402,7 +402,7 @@ public final class Race extends Event
 	{
 		int[] _reward = _rewards[getRandom(_rewards.length - 1)];
 		player.addItem("eventModRace", _reward[0], _reward[1], _npc, true);
-		Announcements.getInstance().announceToAll(player.getName() + " is a winner!");
+		Broadcast.toAllOnlinePlayers(player.getName() + " is a winner!");
 		eventStop();
 	}
 	
diff --git a/L2J_DataPack/dist/game/data/scripts/custom/events/Wedding/Wedding.java b/L2J_DataPack/dist/game/data/scripts/custom/events/Wedding/Wedding.java
index ddf0c4e7a6729caec509cd5fd6763d9be1f44fc2..e989d5535c8f8b2267f018d281628d9d368a082e 100644
--- a/L2J_DataPack/dist/game/data/scripts/custom/events/Wedding/Wedding.java
+++ b/L2J_DataPack/dist/game/data/scripts/custom/events/Wedding/Wedding.java
@@ -21,7 +21,6 @@ package custom.events.Wedding;
 import ai.npc.AbstractNpcAI;
 
 import com.l2jserver.Config;
-import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.instancemanager.CoupleManager;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.actor.L2Npc;
@@ -32,6 +31,7 @@ import com.l2jserver.gameserver.model.skills.CommonSkill;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
 import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.util.Broadcast;
 
 /**
  * Wedding AI.
@@ -153,7 +153,7 @@ public final class Wedding extends AbstractNpcAI
 						partner.doCast(skill);
 					}
 					
-					Announcements.getInstance().announceToAll("Congratulations to " + player.getName() + " and " + partner.getName() + "! They have been married.");
+					Broadcast.toAllOnlinePlayers("Congratulations to " + player.getName() + " and " + partner.getName() + "! They have been married.");
 					
 					htmltext = sendHtml(partner, "Accepted.html", null, null);
 				}
diff --git a/L2J_DataPack/dist/game/data/scripts/handlers/admincommandhandlers/AdminAnnouncements.java b/L2J_DataPack/dist/game/data/scripts/handlers/admincommandhandlers/AdminAnnouncements.java
index 2145b2929f90ebcab26f39fa584a43598c271d96..454cb938d93412fdf372a340f6b5b47b39de5c7a 100644
--- a/L2J_DataPack/dist/game/data/scripts/handlers/admincommandhandlers/AdminAnnouncements.java
+++ b/L2J_DataPack/dist/game/data/scripts/handlers/admincommandhandlers/AdminAnnouncements.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2014 L2J DataPack
+ * Copyright (C) 2004-2013 L2J DataPack
  * 
  * This file is part of L2J DataPack.
  * 
@@ -18,308 +18,504 @@
  */
 package handlers.admincommandhandlers;
 
-import java.util.List;
 import java.util.StringTokenizer;
 
-import javolution.text.TextBuilder;
-
 import com.l2jserver.Config;
-import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.cache.HtmCache;
+import com.l2jserver.gameserver.datatables.AnnouncementsTable;
 import com.l2jserver.gameserver.handler.IAdminCommandHandler;
-import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.PageResult;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
-import com.l2jserver.gameserver.taskmanager.AutoAnnounceTaskManager;
-import com.l2jserver.gameserver.taskmanager.AutoAnnounceTaskManager.AutoAnnouncement;
+import com.l2jserver.gameserver.model.announce.Announcement;
+import com.l2jserver.gameserver.model.announce.AnnouncementType;
+import com.l2jserver.gameserver.model.announce.AutoAnnouncement;
+import com.l2jserver.gameserver.model.announce.IAnnouncement;
+import com.l2jserver.gameserver.util.Broadcast;
+import com.l2jserver.gameserver.util.HtmlUtil;
 import com.l2jserver.gameserver.util.Util;
-import com.l2jserver.util.StringUtil;
 
 /**
- * This class handles following admin commands: - announce text = announces text to all players - list_announcements = show menu - reload_announcements = reloads announcements from txt file - announce_announcements = announce all stored announcements to all players - add_announcement text = adds
- * text to startup announcements - del_announcement id = deletes announcement with respective id
- * @version $Revision: 1.4.4.5 $ $Date: 2005/04/11 10:06:06 $
+ * @author UnAfraid
  */
 public class AdminAnnouncements implements IAdminCommandHandler
 {
-	
 	private static final String[] ADMIN_COMMANDS =
 	{
-		"admin_list_announcements",
-		"admin_list_critannouncements",
-		"admin_reload_announcements",
-		"admin_announce_announcements",
-		"admin_add_announcement",
-		"admin_del_announcement",
-		"admin_add_critannouncement",
-		"admin_del_critannouncement",
 		"admin_announce",
-		"admin_critannounce",
-		"admin_announce_menu",
-		"admin_critannounce_menu",
-		"admin_list_autoann",
-		"admin_reload_autoann",
-		"admin_add_autoann",
-		"admin_del_autoann"
+		"admin_announce_crit",
+		"admin_announce_screen",
+		"admin_announces",
 	};
 	
 	@Override
 	public boolean useAdminCommand(String command, L2PcInstance activeChar)
 	{
-		if (command.equals("admin_list_announcements"))
-		{
-			Announcements.getInstance().listAnnouncements(activeChar);
-		}
-		else if (command.equals("admin_list_critannouncements"))
-		{
-			Announcements.getInstance().listCritAnnouncements(activeChar);
-		}
-		else if (command.equals("admin_reload_announcements"))
+		final StringTokenizer st = new StringTokenizer(command);
+		final String cmd = st.hasMoreTokens() ? st.nextToken() : "";
+		switch (cmd)
 		{
-			Announcements.getInstance().loadAnnouncements();
-			Announcements.getInstance().listAnnouncements(activeChar);
-		}
-		else if (command.startsWith("admin_announce_menu"))
-		{
-			if (Config.GM_ANNOUNCER_NAME && (command.length() > 20))
+			case "admin_announce":
+			case "admin_announce_crit":
+			case "admin_announce_screen":
 			{
-				command += " (" + activeChar.getName() + ")";
-			}
-			Announcements.getInstance().handleAnnounce(command, 20, false);
-			AdminHtml.showAdminHtml(activeChar, "gm_menu.htm");
-		}
-		else if (command.startsWith("admin_critannounce_menu"))
-		{
-			try
-			{
-				command = command.substring(24);
-				
-				if (Config.GM_CRITANNOUNCER_NAME && (command.length() > 0))
+				if (!st.hasMoreTokens())
 				{
-					command = activeChar.getName() + ": " + command;
+					activeChar.sendMessage("Syntax: //announce <text to announce here>");
+					return false;
 				}
-				Announcements.getInstance().handleAnnounce(command, 0, true);
-			}
-			catch (StringIndexOutOfBoundsException e)
-			{
-			}
-			
-			AdminHtml.showAdminHtml(activeChar, "gm_menu.htm");
-		}
-		else if (command.equals("admin_announce_announcements"))
-		{
-			for (L2PcInstance player : L2World.getInstance().getPlayers())
-			{
-				Announcements.getInstance().showAnnouncements(player);
-			}
-			Announcements.getInstance().listAnnouncements(activeChar);
-		}
-		else if (command.startsWith("admin_add_announcement"))
-		{
-			// FIXME the player can send only 16 chars (if you try to send more
-			// it sends null), remove this function or not?
-			if (!command.equals("admin_add_announcement"))
-			{
-				try
+				String announce = st.nextToken();
+				while (st.hasMoreTokens())
 				{
-					String val = command.substring(23);
-					Announcements.getInstance().addAnnouncement(val);
-					Announcements.getInstance().listAnnouncements(activeChar);
+					announce += " " + st.nextToken();
 				}
-				catch (StringIndexOutOfBoundsException e)
-				{
-				}// ignore errors
-			}
-		}
-		else if (command.startsWith("admin_add_critannouncement"))
-		{
-			// FIXME the player can send only 16 chars (if you try to send more
-			// it sends null), remove this function or not?
-			if (!command.equals("admin_add_critannouncement"))
-			{
-				try
+				if (cmd.equals("admin_announce_screen"))
 				{
-					String val = command.substring(27);
-					Announcements.getInstance().addCritAnnouncement(val);
-					Announcements.getInstance().listCritAnnouncements(activeChar);
+					Broadcast.toAllOnlinePlayersOnScreen(announce);
 				}
-				catch (StringIndexOutOfBoundsException e)
+				else
 				{
-				}// ignore errors
-			}
-		}
-		else if (command.startsWith("admin_del_announcement"))
-		{
-			try
-			{
-				int val = Integer.parseInt(command.substring(23));
-				Announcements.getInstance().delAnnouncement(val);
-				Announcements.getInstance().listAnnouncements(activeChar);
-			}
-			catch (StringIndexOutOfBoundsException e)
-			{
-			}
-		}
-		else if (command.startsWith("admin_del_critannouncement"))
-		{
-			try
-			{
-				int val = Integer.parseInt(command.substring(27));
-				Announcements.getInstance().delCritAnnouncement(val);
-				Announcements.getInstance().listCritAnnouncements(activeChar);
-			}
-			catch (StringIndexOutOfBoundsException e)
-			{
-			}
-		}
-		
-		// Command is admin announce
-		else if (command.startsWith("admin_announce"))
-		{
-			if (Config.GM_ANNOUNCER_NAME && (command.length() > 15))
-			{
-				command += " (" + activeChar.getName() + ")";
+					if (Config.GM_ANNOUNCER_NAME)
+					{
+						announce = announce + " [" + activeChar.getName() + "]";
+					}
+					Broadcast.toAllOnlinePlayers(announce, cmd.equals("admin_announce_crit"));
+				}
+				AdminHtml.showAdminHtml(activeChar, "gm_menu.htm");
+				break;
 			}
-			// Call method from another class
-			Announcements.getInstance().handleAnnounce(command, 15, false);
-		}
-		else if (command.startsWith("admin_critannounce"))
-		{
-			try
+			case "admin_announces":
 			{
-				command = command.substring(19);
-				
-				if (Config.GM_CRITANNOUNCER_NAME && (command.length() > 0))
+				final String subCmd = st.hasMoreTokens() ? st.nextToken() : "";
+				switch (subCmd)
 				{
-					command = activeChar.getName() + ": " + command;
+					case "add":
+					{
+						if (!st.hasMoreTokens())
+						{
+							String content = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/admin/announces-add.htm");
+							Util.sendCBHtml(activeChar, content);
+							break;
+						}
+						final String annType = st.nextToken();
+						final AnnouncementType type = AnnouncementType.findByName(annType);
+						// ************************************
+						if (!st.hasMoreTokens())
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						String annInitDelay = st.nextToken();
+						if (!isDigit(annInitDelay))
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						int initDelay = Integer.parseInt(annInitDelay) * 1000;
+						// ************************************
+						if (!st.hasMoreTokens())
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						String annDelay = st.nextToken();
+						if (!isDigit(annDelay))
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						int delay = Integer.parseInt(annDelay) * 1000;
+						if ((delay < (10 * 1000)) && ((type == AnnouncementType.AUTO_NORMAL) || (type == AnnouncementType.AUTO_CRITICAL)))
+						{
+							activeChar.sendMessage("Delay cannot be less then 10 seconds!");
+							break;
+						}
+						// ************************************
+						if (!st.hasMoreTokens())
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						String annRepeat = st.nextToken();
+						if (!isDigit(annRepeat))
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						int repeat = Integer.parseInt(annRepeat);
+						if (repeat == 0)
+						{
+							repeat = -1;
+						}
+						// ************************************
+						if (!st.hasMoreTokens())
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						String content = st.nextToken();
+						while (st.hasMoreTokens())
+						{
+							content += " " + st.nextToken();
+						}
+						// ************************************
+						final IAnnouncement announce;
+						if ((type == AnnouncementType.AUTO_CRITICAL) || (type == AnnouncementType.AUTO_NORMAL))
+						{
+							announce = new AutoAnnouncement(type, content, activeChar.getName(), initDelay, delay, repeat);
+						}
+						else
+						{
+							announce = new Announcement(type, content, activeChar.getName());
+						}
+						AnnouncementsTable.getInstance().addAnnouncement(announce);
+						activeChar.sendMessage("Announcement has been successfully added!");
+						return useAdminCommand("admin_announces list", activeChar);
+					}
+					case "edit":
+					{
+						if (!st.hasMoreTokens())
+						{
+							activeChar.sendMessage("Syntax: //announces edit <id>");
+							break;
+						}
+						String annId = st.nextToken();
+						if (!isDigit(annId))
+						{
+							activeChar.sendMessage("Syntax: //announces edit <id>");
+							break;
+						}
+						int id = Integer.parseInt(annId);
+						final IAnnouncement announce = AnnouncementsTable.getInstance().getAnnounce(id);
+						if (announce == null)
+						{
+							activeChar.sendMessage("Announcement doesnt exists!");
+							break;
+						}
+						if (!st.hasMoreTokens())
+						{
+							String content = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/admin/announces-edit.htm");
+							String announcementId = "" + announce.getId();
+							String announcementType = announce.getType().name();
+							String announcementInital = "0";
+							String announcementDelay = "0";
+							String announcementRepeat = "0";
+							String announcementAuthor = announce.getAuthor();
+							String announcementContent = announce.getContent();
+							if (announce instanceof AutoAnnouncement)
+							{
+								final AutoAnnouncement autoAnnounce = (AutoAnnouncement) announce;
+								announcementInital = "" + (autoAnnounce.getInitial() / 1000);
+								announcementDelay = "" + (autoAnnounce.getDelay() / 1000);
+								announcementRepeat = "" + autoAnnounce.getRepeat();
+							}
+							content = content.replaceAll("%id%", announcementId);
+							content = content.replaceAll("%type%", announcementType);
+							content = content.replaceAll("%initial%", announcementInital);
+							content = content.replaceAll("%delay%", announcementDelay);
+							content = content.replaceAll("%repeat%", announcementRepeat);
+							content = content.replaceAll("%author%", announcementAuthor);
+							content = content.replaceAll("%content%", announcementContent);
+							Util.sendCBHtml(activeChar, content);
+							break;
+						}
+						final String annType = st.nextToken();
+						final AnnouncementType type = AnnouncementType.findByName(annType);
+						switch (announce.getType())
+						{
+							case AUTO_CRITICAL:
+							case AUTO_NORMAL:
+							{
+								switch (type)
+								{
+									case AUTO_CRITICAL:
+									case AUTO_NORMAL:
+									{
+										break;
+									}
+									default:
+									{
+										activeChar.sendMessage("Announce type can be changed only to AUTO_NORMAL or AUTO_CRITICAL!");
+										return false;
+									}
+								}
+								break;
+							}
+							case NORMAL:
+							case CRITICAL:
+							{
+								switch (type)
+								{
+									case NORMAL:
+									case CRITICAL:
+									{
+										break;
+									}
+									default:
+									{
+										activeChar.sendMessage("Announce type can be changed only to NORMAL or CRITICAL!");
+										return false;
+									}
+								}
+								break;
+							}
+						}
+						// ************************************
+						if (!st.hasMoreTokens())
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						String annInitDelay = st.nextToken();
+						if (!isDigit(annInitDelay))
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						int initDelay = Integer.parseInt(annInitDelay);
+						// ************************************
+						if (!st.hasMoreTokens())
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						String annDelay = st.nextToken();
+						if (!isDigit(annDelay))
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						int delay = Integer.parseInt(annDelay);
+						if ((delay < 10) && ((type == AnnouncementType.AUTO_NORMAL) || (type == AnnouncementType.AUTO_CRITICAL)))
+						{
+							activeChar.sendMessage("Delay cannot be less then 10 seconds!");
+							break;
+						}
+						// ************************************
+						if (!st.hasMoreTokens())
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						String annRepeat = st.nextToken();
+						if (!isDigit(annRepeat))
+						{
+							activeChar.sendMessage("Syntax: //announces add <type> <delay> <repeat> <text>");
+							break;
+						}
+						int repeat = Integer.parseInt(annRepeat);
+						if (repeat == 0)
+						{
+							repeat = -1;
+						}
+						// ************************************
+						String content = "";
+						if (st.hasMoreTokens())
+						{
+							content = st.nextToken();
+							while (st.hasMoreTokens())
+							{
+								content += " " + st.nextToken();
+							}
+						}
+						if (content.isEmpty())
+						{
+							content = announce.getContent();
+						}
+						// ************************************
+						announce.setType(type);
+						announce.setContent(content);
+						announce.setAuthor(activeChar.getName());
+						if (announce instanceof AutoAnnouncement)
+						{
+							AutoAnnouncement autoAnnounce = (AutoAnnouncement) announce;
+							autoAnnounce.setInitial(initDelay * 1000);
+							autoAnnounce.setDelay(delay * 1000);
+							autoAnnounce.setRepeat(repeat);
+						}
+						announce.updateMe();
+						activeChar.sendMessage("Announcement has been successfully edited!");
+						return useAdminCommand("admin_announces list", activeChar);
+					}
+					case "remove":
+					{
+						if (!st.hasMoreTokens())
+						{
+							activeChar.sendMessage("Syntax: //announces remove <announcement id>");
+							break;
+						}
+						String token = st.nextToken();
+						if (!isDigit(token))
+						{
+							activeChar.sendMessage("Syntax: //announces remove <announcement id>");
+							break;
+						}
+						int id = Integer.parseInt(token);
+						if (AnnouncementsTable.getInstance().deleteAnnouncement(id))
+						{
+							activeChar.sendMessage("Announcement has been successfully removed!");
+						}
+						else
+						{
+							activeChar.sendMessage("Announcement doesnt exists!");
+						}
+						return useAdminCommand("admin_announces list", activeChar);
+					}
+					case "restart":
+					{
+						if (!st.hasMoreTokens())
+						{
+							for (IAnnouncement announce : AnnouncementsTable.getInstance().getAllAnnouncements())
+							{
+								if (announce instanceof AutoAnnouncement)
+								{
+									final AutoAnnouncement autoAnnounce = (AutoAnnouncement) announce;
+									autoAnnounce.restartMe();
+								}
+							}
+							activeChar.sendMessage("Auto announcements has been successfully restarted");
+							break;
+						}
+						String token = st.nextToken();
+						if (!isDigit(token))
+						{
+							activeChar.sendMessage("Syntax: //announces show <announcement id>");
+							break;
+						}
+						int id = Integer.parseInt(token);
+						final IAnnouncement announce = AnnouncementsTable.getInstance().getAnnounce(id);
+						if (announce != null)
+						{
+							if (announce instanceof AutoAnnouncement)
+							{
+								final AutoAnnouncement autoAnnounce = (AutoAnnouncement) announce;
+								autoAnnounce.restartMe();
+								activeChar.sendMessage("Auto announcement has been successfully restarted");
+							}
+							else
+							{
+								activeChar.sendMessage("This option has effect only on auto announcements!");
+							}
+						}
+						else
+						{
+							activeChar.sendMessage("Announcement doesnt exists!");
+						}
+						break;
+					}
+					case "show":
+					{
+						if (!st.hasMoreTokens())
+						{
+							activeChar.sendMessage("Syntax: //announces show <announcement id>");
+							break;
+						}
+						String token = st.nextToken();
+						if (!isDigit(token))
+						{
+							activeChar.sendMessage("Syntax: //announces show <announcement id>");
+							break;
+						}
+						int id = Integer.parseInt(token);
+						final IAnnouncement announce = AnnouncementsTable.getInstance().getAnnounce(id);
+						if (announce != null)
+						{
+							String content = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/admin/announces-show.htm");
+							String announcementId = "" + announce.getId();
+							String announcementType = announce.getType().name();
+							String announcementInital = "0";
+							String announcementDelay = "0";
+							String announcementRepeat = "0";
+							String announcementAuthor = announce.getAuthor();
+							String announcementContent = announce.getContent();
+							if (announce instanceof AutoAnnouncement)
+							{
+								final AutoAnnouncement autoAnnounce = (AutoAnnouncement) announce;
+								announcementInital = "" + (autoAnnounce.getInitial() / 1000);
+								announcementDelay = "" + (autoAnnounce.getDelay() / 1000);
+								announcementRepeat = "" + autoAnnounce.getRepeat();
+							}
+							content = content.replaceAll("%id%", announcementId);
+							content = content.replaceAll("%type%", announcementType);
+							content = content.replaceAll("%initial%", announcementInital);
+							content = content.replaceAll("%delay%", announcementDelay);
+							content = content.replaceAll("%repeat%", announcementRepeat);
+							content = content.replaceAll("%author%", announcementAuthor);
+							content = content.replaceAll("%content%", announcementContent);
+							Util.sendCBHtml(activeChar, content);
+							break;
+						}
+						activeChar.sendMessage("Announcement doesnt exists!");
+						return useAdminCommand("admin_announces list", activeChar);
+					}
+					case "list":
+					{
+						int page = 0;
+						if (st.hasMoreTokens())
+						{
+							final String token = st.nextToken();
+							if (Util.isDigit(token))
+							{
+								page = Integer.valueOf(token);
+							}
+						}
+						
+						String content = HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/admin/announces-list.htm");
+						final PageResult result = HtmlUtil.createPage(AnnouncementsTable.getInstance().getAllAnnouncements(), page, 8, currentPage ->
+						{
+							return "<td align=center><button action=\"bypass admin_announces list " + currentPage + "\" value=\"" + (currentPage + 1) + "\" width=35 height=20 back=\"L2UI_CT1.Button_DF_Down\" fore=\"L2UI_CT1.Button_DF\"></td>";
+						}, announcement ->
+						{
+							final StringBuilder sb = new StringBuilder();
+							sb.append("<tr>");
+							sb.append("<td width=5></td>");
+							sb.append("<td width=80>" + announcement.getId() + "</td>");
+							sb.append("<td width=100>" + announcement.getType() + "</td>");
+							sb.append("<td width=100>" + announcement.getAuthor() + "</td>");
+							if ((announcement.getType() == AnnouncementType.AUTO_NORMAL) || (announcement.getType() == AnnouncementType.AUTO_CRITICAL))
+							{
+								sb.append("<td width=60><button action=\"bypass -h admin_announces restart " + announcement.getId() + "\" value=\"Restart\" width=\"60\" height=\"21\" back=\"L2UI_CT1.Button_DF_Down\" fore=\"L2UI_CT1.Button_DF\"></td>");
+							}
+							else
+							{
+								sb.append("<td width=60><button action=\"\" value=\"\" width=\"60\" height=\"21\" back=\"L2UI_CT1.Button_DF_Down\" fore=\"L2UI_CT1.Button_DF\"></td>");
+							}
+							if (announcement.getType() == AnnouncementType.EVENT)
+							{
+								sb.append("<td width=60><button action=\"bypass -h admin_announces show " + announcement.getId() + "\" value=\"Show\" width=\"60\" height=\"21\" back=\"L2UI_CT1.Button_DF_Down\" fore=\"L2UI_CT1.Button_DF\"></td>");
+								sb.append("<td width=60></td>");
+							}
+							else
+							{
+								sb.append("<td width=60><button action=\"bypass -h admin_announces show " + announcement.getId() + "\" value=\"Show\" width=\"60\" height=\"21\" back=\"L2UI_CT1.Button_DF_Down\" fore=\"L2UI_CT1.Button_DF\"></td>");
+								sb.append("<td width=60><button action=\"bypass -h admin_announces edit " + announcement.getId() + "\" value=\"Edit\" width=\"60\" height=\"21\" back=\"L2UI_CT1.Button_DF_Down\" fore=\"L2UI_CT1.Button_DF\"></td>");
+							}
+							sb.append("<td width=60><button action=\"bypass -h admin_announces remove " + announcement.getId() + "\" value=\"Remove\" width=\"60\" height=\"21\" back=\"L2UI_CT1.Button_DF_Down\" fore=\"L2UI_CT1.Button_DF\"></td>");
+							sb.append("<td width=5></td>");
+							sb.append("</tr>");
+							return sb.toString();
+						});
+						content = content.replaceAll("%pages%", result.getPagerTemplate().toString());
+						content = content.replaceAll("%announcements%", result.getBodyTemplate().toString());
+						Util.sendCBHtml(activeChar, content);
+						break;
+					}
 				}
-				Announcements.getInstance().handleAnnounce(command, 0, true);
 			}
-			catch (StringIndexOutOfBoundsException e)
-			{
-			}
-		}
-		else if (command.startsWith("admin_list_autoann"))
-		{
-			listAutoAnnouncements(activeChar);
-		}
-		else if (command.startsWith("admin_reload_autoann"))
-		{
-			AutoAnnounceTaskManager.getInstance().restore();
-			activeChar.sendMessage("AutoAnnouncement Reloaded.");
-			listAutoAnnouncements(activeChar);
 		}
-		else if (command.startsWith("admin_add_autoann"))
-		{
-			StringTokenizer st = new StringTokenizer(command);
-			st.nextToken();
-			
-			if (!st.hasMoreTokens())
-			{
-				activeChar.sendMessage("Not enough parameters for adding autoannounce!");
-				return false;
-			}
-			String token = st.nextToken();
-			if (!Util.isDigit(token))
-			{
-				activeChar.sendMessage("Not a valid initial value!");
-				return false;
-			}
-			long initial = Long.parseLong(token);
-			if (!st.hasMoreTokens())
-			{
-				activeChar.sendMessage("Not enough parameters for adding autoannounce!");
-				return false;
-			}
-			token = st.nextToken();
-			if (!Util.isDigit(token))
-			{
-				activeChar.sendMessage("Not a valid delay value!");
-				return false;
-			}
-			long delay = Long.parseLong(token);
-			if (!st.hasMoreTokens())
-			{
-				activeChar.sendMessage("Not enough parameters for adding autoannounce!");
-				return false;
-			}
-			token = st.nextToken();
-			if (!token.equals("-1") && !Util.isDigit(token))
-			{
-				activeChar.sendMessage("Not a valid repeat value!");
-				return false;
-			}
-			int repeat = Integer.parseInt(token);
-			if (!st.hasMoreTokens())
-			{
-				activeChar.sendMessage("Not enough parameters for adding autoannounce!");
-				return false;
-			}
-			boolean isCritical = Boolean.valueOf(st.nextToken());
-			if (!st.hasMoreTokens())
-			{
-				activeChar.sendMessage("Not enough parameters for adding autoannounce!");
-				return false;
-			}
-			TextBuilder memo = new TextBuilder();
-			while (st.hasMoreTokens())
-			{
-				memo.append(st.nextToken());
-				memo.append(" ");
-			}
-			
-			AutoAnnounceTaskManager.getInstance().addAutoAnnounce(initial * 1000, delay * 1000, repeat, memo.toString().trim(), isCritical);
-			listAutoAnnouncements(activeChar);
-		}
-		
-		else if (command.startsWith("admin_del_autoann"))
-		{
-			StringTokenizer st = new StringTokenizer(command);
-			st.nextToken();
-			
-			if (!st.hasMoreTokens())
-			{
-				activeChar.sendMessage("Not enough parameters for deleting autoannounce!");
-				return false;
-			}
-			String token = st.nextToken();
-			if (!Util.isDigit(token))
-			{
-				activeChar.sendMessage("Not a valid auto announce Id value!");
-				return false;
-			}
-			AutoAnnounceTaskManager.getInstance().deleteAutoAnnounce(Integer.parseInt(token));
-			listAutoAnnouncements(activeChar);
-		}
-		return true;
+		return false;
 	}
 	
-	private void listAutoAnnouncements(L2PcInstance activeChar)
+	public boolean isDigit(String value)
 	{
-		String content = HtmCache.getInstance().getHtmForce(activeChar.getHtmlPrefix(), "data/html/admin/autoannounce.htm");
-		final NpcHtmlMessage adminReply = new NpcHtmlMessage();
-		adminReply.setHtml(content);
-		
-		final StringBuilder replyMSG = StringUtil.startAppend(500, "<br>");
-		List<AutoAnnouncement> autoannouncements = AutoAnnounceTaskManager.getInstance().getAutoAnnouncements();
-		for (int i = 0; i < autoannouncements.size(); i++)
+		try
 		{
-			AutoAnnouncement autoann = autoannouncements.get(i);
-			TextBuilder memo2 = new TextBuilder();
-			for (String memo0 : autoann.getMemo())
-			{
-				memo2.append(memo0);
-				memo2.append("/n");
-			}
-			replyMSG.append("<table width=260><tr><td width=220><font color=\"" + (autoann.isCritical() ? "00FCFC" : "7FFCFC") + "\">");
-			replyMSG.append(memo2.toString().trim());
-			replyMSG.append("</font></td><td width=40><button value=\"Delete\" action=\"bypass -h admin_del_autoann ");
-			replyMSG.append(i);
-			replyMSG.append("\" width=60 height=15 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\"></td></tr></table>");
+			Integer.parseInt(value);
+			return true;
+		}
+		catch (Exception e)
+		{
+			return false;
 		}
-		adminReply.replace("%announces%", replyMSG.toString());
-		
-		activeChar.sendPacket(adminReply);
 	}
 	
 	@Override
diff --git a/L2J_DataPack/dist/game/data/scripts/handlers/admincommandhandlers/AdminEventEngine.java b/L2J_DataPack/dist/game/data/scripts/handlers/admincommandhandlers/AdminEventEngine.java
index 553080809dc94d12b258f04ad4dc62a0dbe3a56c..0b323c43699a22b27ba49cdd56ba77c655d7416d 100644
--- a/L2J_DataPack/dist/game/data/scripts/handlers/admincommandhandlers/AdminEventEngine.java
+++ b/L2J_DataPack/dist/game/data/scripts/handlers/admincommandhandlers/AdminEventEngine.java
@@ -29,7 +29,6 @@ import java.io.PrintStream;
 import java.util.StringTokenizer;
 
 import com.l2jserver.Config;
-import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.datatables.AdminTable;
 import com.l2jserver.gameserver.datatables.TransformData;
 import com.l2jserver.gameserver.handler.IAdminCommandHandler;
@@ -42,6 +41,7 @@ import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
 import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
 import com.l2jserver.gameserver.network.serverpackets.PlaySound;
 import com.l2jserver.gameserver.network.serverpackets.UserInfo;
+import com.l2jserver.gameserver.util.Broadcast;
 import com.l2jserver.util.Rnd;
 import com.l2jserver.util.StringUtil;
 
@@ -221,7 +221,7 @@ public class AdminEventEngine implements IAdminCommandHandler
 				}
 				
 				activeChar.sendMessage(L2Event.startEventParticipation());
-				Announcements.getInstance().announceToAll(activeChar.getName() + " has started an event. You will find a participation NPC somewhere around you.");
+				Broadcast.toAllOnlinePlayers(activeChar.getName() + " has started an event. You will find a participation NPC somewhere around you.");
 				
 				PlaySound _snd = new PlaySound(1, "B03_F", 0, 0, 0, 0, 0);
 				activeChar.sendPacket(_snd);
diff --git a/L2J_DataPack/dist/game/data/scripts/handlers/telnethandlers/ChatsHandler.java b/L2J_DataPack/dist/game/data/scripts/handlers/telnethandlers/ChatsHandler.java
index e5c640e9d3dc00b1b99ecce446098a780507ecfc..706e92357f79653362cdcbd63049bd4a4afc9e5e 100644
--- a/L2J_DataPack/dist/game/data/scripts/handlers/telnethandlers/ChatsHandler.java
+++ b/L2J_DataPack/dist/game/data/scripts/handlers/telnethandlers/ChatsHandler.java
@@ -22,13 +22,13 @@ import java.io.PrintWriter;
 import java.net.Socket;
 import java.util.StringTokenizer;
 
-import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.datatables.AdminTable;
 import com.l2jserver.gameserver.handler.ITelnetHandler;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.network.clientpackets.Say2;
 import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
+import com.l2jserver.gameserver.util.Broadcast;
 
 /**
  * @author UnAfraid
@@ -50,7 +50,7 @@ public class ChatsHandler implements ITelnetHandler
 			try
 			{
 				command = command.substring(9);
-				Announcements.getInstance().announceToAll(command);
+				Broadcast.toAllOnlinePlayers(command);
 				_print.println("Announcement Sent!");
 			}
 			catch (StringIndexOutOfBoundsException e)
diff --git a/L2J_DataPack/dist/game/data/scripts/hellbound/HellboundEngine.java b/L2J_DataPack/dist/game/data/scripts/hellbound/HellboundEngine.java
index 78ec0356f39cda39dc0d4d326303d3c0accb8bb7..52348e5fb547b6924fdbacbf9efbeebd3bc09356 100644
--- a/L2J_DataPack/dist/game/data/scripts/hellbound/HellboundEngine.java
+++ b/L2J_DataPack/dist/game/data/scripts/hellbound/HellboundEngine.java
@@ -21,13 +21,13 @@ package hellbound;
 import ai.npc.AbstractNpcAI;
 
 import com.l2jserver.Config;
-import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.datatables.DoorTable;
 import com.l2jserver.gameserver.instancemanager.GlobalVariablesManager;
 import com.l2jserver.gameserver.model.L2Spawn;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.util.Broadcast;
 
 /**
  * Hellbound Engine.
@@ -292,7 +292,7 @@ public final class HellboundEngine extends AbstractNpcAI
 		
 		if (_cachedLevel > 0)
 		{
-			Announcements.getInstance().announceToAll(ANNOUNCEMENT.replace("%lvl%", String.valueOf(newLevel)));
+			Broadcast.toAllOnlinePlayers(ANNOUNCEMENT.replace("%lvl%", String.valueOf(newLevel)));
 			_log.info(HellboundEngine.class.getSimpleName() + ": New level: " + newLevel);
 		}
 		_cachedLevel = newLevel;
diff --git a/L2J_DataPack/dist/sql/game/announcements.sql b/L2J_DataPack/dist/sql/game/announcements.sql
new file mode 100644
index 0000000000000000000000000000000000000000..132e7007eff6b6454f41b12d7c1bbe015a8d58fa
--- /dev/null
+++ b/L2J_DataPack/dist/sql/game/announcements.sql
@@ -0,0 +1,12 @@
+CREATE TABLE IF NOT EXISTS `announcements` (
+  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `type` int(11) NOT NULL,
+  `initial` bigint(20) NOT NULL DEFAULT 0,
+  `delay` bigint(20) NOT NULL DEFAULT 0,
+  `repeat` int(11) NOT NULL DEFAULT 0,
+  `author` text NOT NULL,
+  `content` text NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+INSERT INTO announcements (`type`, `author`, `content`) VALUES (0, 'L2JServer', 'Thanks for using L2J.');
\ No newline at end of file
diff --git a/L2J_DataPack/dist/sql/game/auto_announcements.sql b/L2J_DataPack/dist/sql/game/auto_announcements.sql
deleted file mode 100644
index 83064ccd97740d209ffbc4ee74461883f7d7e7ab..0000000000000000000000000000000000000000
--- a/L2J_DataPack/dist/sql/game/auto_announcements.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-CREATE TABLE IF NOT EXISTS `auto_announcements` (
-  `id` INT(11) NOT NULL,
-  `initial` BIGINT(20) NOT NULL,
-  `delay` BIGINT(20) NOT NULL,
-  `cycle` INT(11) NOT NULL,
-  `memo` TEXT DEFAULT NULL,
-  `isCritical` enum('true','false') NOT NULL DEFAULT 'false',
-  PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
\ No newline at end of file
diff --git a/L2J_DataPack/dist/sql/game/updates/20141216update.sql b/L2J_DataPack/dist/sql/game/updates/20141216update.sql
new file mode 100644
index 0000000000000000000000000000000000000000..014a07f6c68e971126e163d5d66c2a5ecf11ce58
--- /dev/null
+++ b/L2J_DataPack/dist/sql/game/updates/20141216update.sql
@@ -0,0 +1 @@
+DROP TABLE auto_announcements;
\ No newline at end of file
diff --git a/L2J_DataPack/dist/tools/gs_cleanup.sql b/L2J_DataPack/dist/tools/gs_cleanup.sql
index 6f64ced2db84950ff5c6253e5397e5eae0663b6e..7e29166ebd55f7d4fb49d9f03f2afa3afbb50e9e 100644
--- a/L2J_DataPack/dist/tools/gs_cleanup.sql
+++ b/L2J_DataPack/dist/tools/gs_cleanup.sql
@@ -12,7 +12,7 @@ airships,
 auction,
 auction_bid,
 auction_watch,
-auto_announcements,
+announcements,
 buylists,
 castle,
 castle_doorupgrade,