diff --git a/L2J_DataPack_BETA/dist/game/data/html/mods/TvTEventParticipation.htm b/L2J_DataPack_BETA/dist/game/data/html/mods/TvTEventParticipation.htm
deleted file mode 100644
index 28af4f9ba560b8b706cf09fb1e86ccdaa824d5f8..0000000000000000000000000000000000000000
--- a/L2J_DataPack_BETA/dist/game/data/html/mods/TvTEventParticipation.htm
+++ /dev/null
@@ -1,6 +0,0 @@
-<html><title>TvT Event</title><body>
-Registration for TvT Event:<br><br><center>
-%playercount% players in<br>
-<button value="Participate" action="bypass -h npc_%objectId%_tvt_event_participation" width=50 height=15 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df">
-<button value="Close" action="bypass -h npc_%objectId%_Close" width=50 height=15 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df">
-</center></body></html>
\ No newline at end of file
diff --git a/L2J_DataPack_BETA/dist/game/data/html/mods/TvTEventRemoveParticipation.htm b/L2J_DataPack_BETA/dist/game/data/html/mods/TvTEventRemoveParticipation.htm
deleted file mode 100644
index 87e710fae6adfbb9e0c4c9536689f325ebb9745e..0000000000000000000000000000000000000000
--- a/L2J_DataPack_BETA/dist/game/data/html/mods/TvTEventRemoveParticipation.htm
+++ /dev/null
@@ -1,6 +0,0 @@
-<html><title>TvT Event</title><body>
-Cancel Registration yourself for TvT Event:<br1>
-You are already registered for this event. Do you wish to cancel your participation in this Event?<br><br><center>
-<button value="Yes" action="bypass -h npc_%objectId%_tvt_event_remove_participation" width=40 height=15 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df">
-<button value="No" action="bypass -h npc_%objectId%_Close" width=40 height=15 back="L2UI_ct1.button_df" fore="L2UI_ct1.button_df">
-</center></body></html>
\ No newline at end of file
diff --git a/L2J_DataPack_BETA/dist/game/data/html/mods/TvTEventStatus.htm b/L2J_DataPack_BETA/dist/game/data/html/mods/TvTEventStatus.htm
deleted file mode 100644
index bed879d3387ff80b9206c50cb65379b838a2c755..0000000000000000000000000000000000000000
--- a/L2J_DataPack_BETA/dist/game/data/html/mods/TvTEventStatus.htm
+++ /dev/null
@@ -1,5 +0,0 @@
-<html><title>TvT Event</title><body>
-Status:<br><br><center>
-%team1name% with %team1playercount% players and %team1points% points.<br1>
-%team2name% with %team2playercount% players and %team2points% points.<br>
-</center></body></html>
\ No newline at end of file
diff --git a/L2J_DataPack_BETA/dist/game/data/scripts/custom/events/TvT/TvTManager/TvTManager.java b/L2J_DataPack_BETA/dist/game/data/scripts/custom/events/TvT/TvTManager/TvTManager.java
index 561ca52985520219f67f7d1564e94a1d0909ff9e..726bf5856df9f24f622fe5a7371543883d0636eb 100644
--- a/L2J_DataPack_BETA/dist/game/data/scripts/custom/events/TvT/TvTManager/TvTManager.java
+++ b/L2J_DataPack_BETA/dist/game/data/scripts/custom/events/TvT/TvTManager/TvTManager.java
@@ -21,19 +21,28 @@ package custom.events.TvT.TvTManager;
 import ai.npc.AbstractNpcAI;
 
 import com.l2jserver.Config;
+import com.l2jserver.gameserver.handler.IVoicedCommandHandler;
+import com.l2jserver.gameserver.handler.VoicedCommandHandler;
 import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.entity.TvTEvent;
 import com.l2jserver.gameserver.model.olympiad.OlympiadManager;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
 
 /**
  * TvT Manager AI.
  * @author Zoey76
  */
-public final class TvTManager extends AbstractNpcAI
+public final class TvTManager extends AbstractNpcAI implements IVoicedCommandHandler
 {
 	private static final int MANAGER_ID = 70010;
+	private static final String[] COMMANDS =
+	{
+		"tvt",
+		"tvtjoin",
+		"tvtleave"
+	};
 	
 	public TvTManager()
 	{
@@ -41,6 +50,11 @@ public final class TvTManager extends AbstractNpcAI
 		addFirstTalkId(MANAGER_ID);
 		addTalkId(MANAGER_ID);
 		addStartNpc(MANAGER_ID);
+		
+		if (Config.TVT_ALLOW_VOICED_COMMAND)
+		{
+			VoicedCommandHandler.getInstance().registerHandler(this);
+		}
 	}
 	
 	@Override
@@ -61,15 +75,15 @@ public final class TvTManager extends AbstractNpcAI
 				final int team2Count = TvTEvent.getTeamsPlayerCounts()[1];
 				if (player.isCursedWeaponEquipped())
 				{
-					htmltext = "CursedWeaponEquipped.html";
+					htmltext = getHtm(player.getHtmlPrefix(), "CursedWeaponEquipped.html");
 				}
 				else if (OlympiadManager.getInstance().isRegistered(player))
 				{
-					htmltext = "Olympiad.html";
+					htmltext = getHtm(player.getHtmlPrefix(), "Olympiad.html");
 				}
 				else if (player.getKarma() > 0)
 				{
-					htmltext = "Karma.html";
+					htmltext = getHtm(player.getHtmlPrefix(), "Karma.html");
 				}
 				else if ((playerLevel < Config.TVT_EVENT_MIN_LVL) || (playerLevel > Config.TVT_EVENT_MAX_LVL))
 				{
@@ -94,18 +108,24 @@ public final class TvTManager extends AbstractNpcAI
 				}
 				else if (TvTEvent.addParticipant(player))
 				{
-					htmltext = "Registered.html";
+					htmltext = getHtm(player.getHtmlPrefix(), "Registered.html");
 				}
 				break;
 			}
 			case "remove":
 			{
-				TvTEvent.removeParticipant(player.getObjectId());
-				if (Config.TVT_EVENT_MAX_PARTICIPANTS_PER_IP > 0)
+				if (TvTEvent.removeParticipant(player.getObjectId()))
+				{
+					if (Config.TVT_EVENT_MAX_PARTICIPANTS_PER_IP > 0)
+					{
+						AntiFeedManager.getInstance().removePlayer(AntiFeedManager.TVT_ID, player);
+					}
+					htmltext = getHtm(player.getHtmlPrefix(), "Unregistered.html");
+				}
+				else
 				{
-					AntiFeedManager.getInstance().removePlayer(AntiFeedManager.TVT_ID, player);
+					player.sendMessage("You cannot unregister to this event.");
 				}
-				htmltext = "Unregistered.html";
 				break;
 			}
 		}
@@ -135,19 +155,62 @@ public final class TvTManager extends AbstractNpcAI
 		}
 		else if (TvTEvent.isStarting() || TvTEvent.isStarted())
 		{
-			int[] teamsPlayerCounts = TvTEvent.getTeamsPlayerCounts();
-			int[] teamsPointsCounts = TvTEvent.getTeamsPoints();
-			htmltext = getHtm(player.getHtmlPrefix(), "Status.html");
-			htmltext = htmltext.replaceAll("%team1name%", Config.TVT_EVENT_TEAM_1_NAME);
-			htmltext = htmltext.replaceAll("%team1playercount%", String.valueOf(teamsPlayerCounts[0]));
-			htmltext = htmltext.replaceAll("%team1points%", String.valueOf(teamsPointsCounts[0]));
-			htmltext = htmltext.replaceAll("%team2name%", Config.TVT_EVENT_TEAM_2_NAME);
-			htmltext = htmltext.replaceAll("%team2playercount%", String.valueOf(teamsPlayerCounts[1]));
-			htmltext = htmltext.replaceAll("%team2points%", String.valueOf(teamsPointsCounts[1]));
+			htmltext = getTvTStatus(player);
+		}
+		return htmltext;
+	}
+	
+	@Override
+	public boolean useVoicedCommand(String command, L2PcInstance activeChar, String params)
+	{
+		switch (command)
+		{
+			case "tvt":
+			{
+				if (TvTEvent.isStarting() || TvTEvent.isStarted())
+				{
+					activeChar.sendPacket(new NpcHtmlMessage(getTvTStatus(activeChar)));
+				}
+				else
+				{
+					activeChar.sendMessage("The event has not started.");
+				}
+				break;
+			}
+			case "tvtjoin":
+			{
+				activeChar.sendPacket(new NpcHtmlMessage(onAdvEvent("join", null, activeChar)));
+				break;
+			}
+			case "tvtleave":
+			{
+				activeChar.sendPacket(new NpcHtmlMessage(onAdvEvent("remove", null, activeChar)));
+				break;
+			}
 		}
+		return false;
+	}
+	
+	private String getTvTStatus(L2PcInstance player)
+	{
+		int[] teamsPlayerCounts = TvTEvent.getTeamsPlayerCounts();
+		int[] teamsPointsCounts = TvTEvent.getTeamsPoints();
+		String htmltext = getHtm(player.getHtmlPrefix(), "Status.html");
+		htmltext = htmltext.replaceAll("%team1name%", Config.TVT_EVENT_TEAM_1_NAME);
+		htmltext = htmltext.replaceAll("%team1playercount%", String.valueOf(teamsPlayerCounts[0]));
+		htmltext = htmltext.replaceAll("%team1points%", String.valueOf(teamsPointsCounts[0]));
+		htmltext = htmltext.replaceAll("%team2name%", Config.TVT_EVENT_TEAM_2_NAME);
+		htmltext = htmltext.replaceAll("%team2playercount%", String.valueOf(teamsPlayerCounts[1]));
+		htmltext = htmltext.replaceAll("%team2points%", String.valueOf(teamsPointsCounts[1]));
 		return htmltext;
 	}
 	
+	@Override
+	public String[] getVoicedCommandList()
+	{
+		return COMMANDS;
+	}
+	
 	public static void main(String[] args)
 	{
 		new TvTManager();
diff --git a/L2J_DataPack_BETA/dist/game/data/scripts/handlers/MasterHandler.java b/L2J_DataPack_BETA/dist/game/data/scripts/handlers/MasterHandler.java
index 023d1c4ff6548a70c77f73cac12d2e9acba46d04..d02f21f47bc8f6606c7dc936a7e200e65a2295e1 100644
--- a/L2J_DataPack_BETA/dist/game/data/scripts/handlers/MasterHandler.java
+++ b/L2J_DataPack_BETA/dist/game/data/scripts/handlers/MasterHandler.java
@@ -264,7 +264,6 @@ import handlers.voicedcommandhandlers.ChatAdmin;
 import handlers.voicedcommandhandlers.Debug;
 import handlers.voicedcommandhandlers.Lang;
 import handlers.voicedcommandhandlers.StatsVCmd;
-import handlers.voicedcommandhandlers.TvTVoicedInfo;
 import handlers.voicedcommandhandlers.Wedding;
 
 /**
@@ -506,7 +505,6 @@ public class MasterHandler
 			// SetVCmd.class,
 			(Config.L2JMOD_ALLOW_WEDDING ? Wedding.class : null),
 			(Config.BANKING_SYSTEM_ENABLED ? Banking.class : null),
-			(Config.TVT_ALLOW_VOICED_COMMAND ? TvTVoicedInfo.class : null),
 			(Config.L2JMOD_CHAT_ADMIN ? ChatAdmin.class : null),
 			(Config.L2JMOD_MULTILANG_ENABLE && Config.L2JMOD_MULTILANG_VOICED_ALLOW ? Lang.class : null),
 			(Config.L2JMOD_DEBUG_VOICE_COMMAND ? Debug.class : null),
diff --git a/L2J_DataPack_BETA/dist/game/data/scripts/handlers/voicedcommandhandlers/TvTVoicedInfo.java b/L2J_DataPack_BETA/dist/game/data/scripts/handlers/voicedcommandhandlers/TvTVoicedInfo.java
deleted file mode 100644
index 0043ce20d00a095b33a2426f94243df31b552812..0000000000000000000000000000000000000000
--- a/L2J_DataPack_BETA/dist/game/data/scripts/handlers/voicedcommandhandlers/TvTVoicedInfo.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J DataPack
- * 
- * This file is part of L2J DataPack.
- * 
- * L2J DataPack is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * 
- * L2J DataPack is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-package handlers.voicedcommandhandlers;
-
-import com.l2jserver.Config;
-import com.l2jserver.gameserver.cache.HtmCache;
-import com.l2jserver.gameserver.handler.IVoicedCommandHandler;
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.entity.TvTEvent;
-import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
-import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
-
-/**
- * Tvt info.
- * @author denser
- */
-public class TvTVoicedInfo implements IVoicedCommandHandler
-{
-	private static final String[] _voicedCommands =
-	{
-		"tvt"
-	};
-	
-	/**
-	 * Set this to false and recompile script if you don't want to use string cache.<br>
-	 * This will decrease performance but will be more consistent against possible html editions during runtime Recompiling the script will get the new html would be enough too [DrHouse]
-	 */
-	private static final boolean USE_STATIC_HTML = true;
-	private static final String HTML = HtmCache.getInstance().getHtm(null, "data/html/mods/TvTEvent/Status.htm");
-	
-	@Override
-	public boolean useVoicedCommand(String command, L2PcInstance activeChar, String target)
-	{
-		if (command.equals("tvt"))
-		{
-			if (TvTEvent.isStarting() || TvTEvent.isStarted())
-			{
-				String htmContent = (USE_STATIC_HTML && !HTML.isEmpty()) ? HTML : HtmCache.getInstance().getHtm(activeChar.getHtmlPrefix(), "data/html/mods/TvTEvent/Status.htm");
-				try
-				{
-					final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
-					
-					npcHtmlMessage.setHtml(htmContent);
-					// npcHtmlMessage.replace("%objectId%",
-					// String.valueOf(getObjectId()));
-					npcHtmlMessage.replace("%team1name%", Config.TVT_EVENT_TEAM_1_NAME);
-					npcHtmlMessage.replace("%team1playercount%", String.valueOf(TvTEvent.getTeamsPlayerCounts()[0]));
-					npcHtmlMessage.replace("%team1points%", String.valueOf(TvTEvent.getTeamsPoints()[0]));
-					npcHtmlMessage.replace("%team2name%", Config.TVT_EVENT_TEAM_2_NAME);
-					npcHtmlMessage.replace("%team2playercount%", String.valueOf(TvTEvent.getTeamsPlayerCounts()[1]));
-					npcHtmlMessage.replace("%team2points%", String.valueOf(TvTEvent.getTeamsPoints()[1]));
-					activeChar.sendPacket(npcHtmlMessage);
-				}
-				catch (Exception e)
-				{
-					_log.warning("wrong TvT voiced: " + e);
-				}
-				
-			}
-			else
-			{
-				activeChar.sendPacket(ActionFailed.STATIC_PACKET);
-			}
-		}
-		return true;
-	}
-	
-	@Override
-	public String[] getVoicedCommandList()
-	{
-		return _voicedCommands;
-	}
-}
\ No newline at end of file