Noticias:

No tienes permiso para ver los enlaces. Para poder verlos Registrate o Conectate.

Menú Principal

Experimental Event Engine

Iniciado por Swarlog, Jul 15, 2025, 12:08 AM

Tema anterior - Siguiente tema

Swarlog

Index: java/net/sf/l2j/gameserver/network/serverpackets/Die.java
===================================================================
--- java/net/sf/l2j/gameserver/network/serverpackets/Die.java	(revision 115)
+++ java/net/sf/l2j/gameserver/network/serverpackets/Die.java	(working copy)
@@ -14,6 +14,7 @@
  */
 package net.sf.l2j.gameserver.network.serverpackets;
 
+import net.sf.l2j.gameserver.customs.eventengine.EventCommons;
 import net.sf.l2j.gameserver.customs.events.TvTEvent;
 import net.sf.l2j.gameserver.datatables.AccessLevels;
 import net.sf.l2j.gameserver.instancemanager.CastleManager;
@@ -61,6 +62,9 @@
 		writeD(_charObjId);
 		if (_activeChar instanceof L2PcInstance)
 		{
+			if (!EventCommons.allowToVillage((L2PcInstance)_activeChar))
+				return;
+			
 			if (TvTEvent.getInstance()._state == TvTEvent.EventState.RUNNING)
 			{
 				if (TvTEvent.getInstance()._players.contains(_activeChar))
Index: java/net/sf/l2j/gameserver/customs/eventengine/EventManager.java
===================================================================
--- java/net/sf/l2j/gameserver/customs/eventengine/EventManager.java	(revision 0)
+++ java/net/sf/l2j/gameserver/customs/eventengine/EventManager.java	(revision 0)
@@ -0,0 +1,149 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.customs.eventengine;
+
+import com.sun.istack.internal.logging.Logger;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+import net.sf.l2j.gameserver.ThreadPoolManager;
+import net.sf.l2j.gameserver.customs.eventengine.events.TvT;
+
+/**
+ * @author Anarchy
+ *
+ */
+public final class EventManager
+{
+	private static final Logger log = Logger.getLogger(EventManager.class);
+	
+	private final List<Event> events;
+	
+	public static EventManager getInstance()
+	{
+		return SingletonHolder._instance;
+	}
+	
+	protected EventManager()
+	{
+		events = new ArrayList<>();
+		
+		registerEvent(new TvT());
+		
+		log.config("Event Engine: Loaded "+events.size()+" events.");
+	}
+	
+	public List<Event> getAllEvents()
+	{
+		return events;
+	}
+	
+	public Event getActiveEvent(Class<?> clazz)
+	{
+		for (Event e : events)
+		{
+			if (e.getClass() == clazz)
+			{
+				return e;
+			}
+		}
+		
+		return null;
+	}
+	
+	protected void registerEvent(final Event e)
+	{
+		if (!events.contains(e))
+			events.add(e);
+		
+		switch (e.getScheduleMethod())
+		{
+			case TIMES:
+			{
+				Calendar cld = Calendar.getInstance();
+				String[] times_splitted = e.getScheduleTimes().split(";");
+				int counter = times_splitted.length;
+				
+				for (String time : times_splitted)
+				{
+					String[] hrsmins = time.split(":");
+					int hour = Integer.parseInt(hrsmins[0]);
+					int minute = Integer.parseInt(hrsmins[1]);
+					
+					cld.set(Calendar.HOUR_OF_DAY, hour);
+					cld.set(Calendar.MINUTE, minute);
+					cld.set(Calendar.SECOND, 0);
+					
+					if (cld.getTimeInMillis()-System.currentTimeMillis() <= 0)
+					{
+						cld.set(Calendar.DAY_OF_MONTH, cld.get(Calendar.DAY_OF_MONTH)+1);
+						cld.set(Calendar.HOUR_OF_DAY, hour);
+						cld.set(Calendar.MINUTE, minute);
+						cld.set(Calendar.SECOND, 0);
+					}
+					
+					ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
+					{
+						@Override
+						public void run()
+						{
+							e.runEvent();
+						}
+					}, cld.getTimeInMillis()-System.currentTimeMillis());
+					
+					counter--;
+					
+					if (counter == 0)
+					{
+						ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
+						{
+							@Override
+							public void run()
+							{
+								registerEvent(e);
+							}
+						}, cld.getTimeInMillis()-System.currentTimeMillis());
+					}
+				}
+				
+				break;
+			}
+			case FIXED:
+			{
+				String[] time_splitted = e.getScheduleTimes().split(":");
+				int hours = Integer.parseInt(time_splitted[0]);
+				int minutes = Integer.parseInt(time_splitted[1]);
+				
+				ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Runnable()
+				{
+					@Override
+					public void run()
+					{
+						e.runEvent();
+					}
+				}, ((hours*1000*60*60)+(minutes*1000*60))/2, (hours*1000*60*60)+(minutes*1000*60));
+				
+				break;
+			}
+		}
+	}
+	
+	private static class SingletonHolder
+	{
+		protected static final EventManager _instance = new EventManager();
+	}
+}
Index: java/net/sf/l2j/gameserver/customs/eventengine/EventRegister.java
===================================================================
--- java/net/sf/l2j/gameserver/customs/eventengine/EventRegister.java	(revision 0)
+++ java/net/sf/l2j/gameserver/customs/eventengine/EventRegister.java	(revision 0)
@@ -0,0 +1,78 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.customs.eventengine;
+
+import net.sf.l2j.gameserver.customs.eventengine.events.TvT;
+import net.sf.l2j.gameserver.handler.IVoicedCommandHandler;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author Anarchy
+ *
+ */
+public class EventRegister implements IVoicedCommandHandler
+{
+	@Override
+	public boolean useVoicedCommand(String command, L2PcInstance activeChar)
+	{
+		if (command.startsWith("register_"))
+		{	
+			String event = command.substring(9);
+			
+			if (event == null || event.isEmpty())
+			{
+				activeChar.sendMessage("Invalid command.");
+				return false;
+			}
+			
+			if (EventCommons.isInEvent(activeChar))
+			{
+				activeChar.sendMessage("You have already registered for an event.");
+				return false;
+			}
+			
+			if (event.equals("tvt"))
+			{
+				Event tvt = null;
+				
+				for (Event e : EventManager.getInstance().getAllEvents())
+				{
+					if (e.getClass() == TvT.class)
+					{
+						tvt = e;
+						break;
+					}
+				}
+				
+				if (tvt != null)
+				{
+					if (tvt.getState() == EventState.REGISTERING)
+					{
+						tvt.registerPlayer(activeChar);
+						activeChar.sendMessage("You have registered for the TvT event.");
+					}
+				}
+			}
+		}
+		
+		return true;
+	}
+
+	@Override
+	public String[] getVoicedCommandList()
+	{
+		return new String[] { "register_" };
+	}
+}
Index: java/net/sf/l2j/gameserver/customs/eventengine/EventState.java
===================================================================
--- java/net/sf/l2j/gameserver/customs/eventengine/EventState.java	(revision 0)
+++ java/net/sf/l2j/gameserver/customs/eventengine/EventState.java	(revision 0)
@@ -0,0 +1,27 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.customs.eventengine;
+
+/**
+ * @author Anarchy
+ *
+ */
+public enum EventState
+{
+	INACTIVE,
+	REGISTERING,
+	WAITING,
+	RUNNING
+}
Index: java/net/sf/l2j/gameserver/network/clientpackets/Logout.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/Logout.java	(revision 115)
+++ java/net/sf/l2j/gameserver/network/clientpackets/Logout.java	(working copy)
@@ -16,6 +16,7 @@
 
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.SevenSignsFestival;
+import net.sf.l2j.gameserver.customs.eventengine.EventCommons;
 import net.sf.l2j.gameserver.customs.events.TvTEvent;
 import net.sf.l2j.gameserver.model.L2Party;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
@@ -39,6 +40,12 @@
 		if (player == null)
 			return;
 		
+		if (!EventCommons.allowExit(player))
+		{
+			player.sendPacket(ActionFailed.STATIC_PACKET);
+			return;
+		}
+		
 		if (TvTEvent.getInstance()._players.contains(player))
 		{
 			player.sendMessage("You may not exit while having registered for TvT event.");
Index: java/net/sf/l2j/gameserver/customs/eventengine/EventSchedule.java
===================================================================
--- java/net/sf/l2j/gameserver/customs/eventengine/EventSchedule.java	(revision 0)
+++ java/net/sf/l2j/gameserver/customs/eventengine/EventSchedule.java	(revision 0)
@@ -0,0 +1,31 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.customs.eventengine;
+
+/**
+ * @author Anarchy
+ *
+ */
+public enum EventSchedule
+{
+	// TIMES scheduling method works by scheduling the event
+	// on the specified times of day. Use this format: 19:00;22:30
+	TIMES,
+	
+	// FIXED scheduling method works by scheduling the event
+	// every hours/minutes specified. Use this format: 1:00 (it will run every 1 hour).
+	// NOTE: The first schedule will be the time specified divided by 2.
+	FIXED
+}
Index: java/net/sf/l2j/gameserver/customs/eventengine/EventTeam.java
===================================================================
--- java/net/sf/l2j/gameserver/customs/eventengine/EventTeam.java	(revision 0)
+++ java/net/sf/l2j/gameserver/customs/eventengine/EventTeam.java	(revision 0)
@@ -0,0 +1,126 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.customs.eventengine;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author Anarchy
+ *
+ */
+public class EventTeam
+{
+	private String name;
+	private int x, y, z;
+	private List<L2PcInstance> players;
+	private int score;
+	private int color;
+	
+	public EventTeam(String name, int x, int y, int z, int color)
+	{
+		this.name = name;
+		this.x = x;
+		this.y = y;
+		this.z = z;
+		score = 0;
+		this.color = color;
+		
+		players = new ArrayList<>();
+	}
+	
+	public void reward(int itemId, int count)
+	{
+		for (L2PcInstance p : players)
+		{
+			p.addItem("", itemId, count, null, true);
+		}
+	}
+	
+	public void teleport(int teleX, int teleY, int teleZ)
+	{
+		for (L2PcInstance p : players)
+		{
+			p.teleToLocation(teleX, teleY, teleZ, 10);
+		}
+	}
+	
+	public void teleport()
+	{
+		for (L2PcInstance p : players)
+		{
+			p.teleToLocation(x, y, z, 10);
+		}
+	}
+	
+	public void sendMessage(String msg)
+	{
+		for (L2PcInstance p : players)
+		{
+			p.sendMessage(msg);
+		}
+	}
+	
+	public void drop()
+	{
+		for (L2PcInstance p : players)
+		{
+			p.getAppearance().setNameColor(0xFFFFFF);
+		}
+	}
+	
+	public boolean containsPlayer(L2PcInstance p)
+	{
+		return players.contains(p);
+	}
+	
+	public void addPlayer(L2PcInstance p)
+	{
+		players.add(p);
+		p.getAppearance().setNameColor(color);
+	}
+	
+	public int getX()
+	{
+		return x;
+	}
+	
+	public int getY()
+	{
+		return y;
+	}
+	
+	public int getZ()
+	{
+		return z;
+	}
+	
+	public String getName()
+	{
+		return name;
+	}
+	
+	public int getScore()
+	{
+		return score;
+	}
+	
+	public void setScore(int val)
+	{
+		score = val;
+	}
+}
Index: java/net/sf/l2j/gameserver/customs/eventengine/events/TvT.java
===================================================================
--- java/net/sf/l2j/gameserver/customs/eventengine/events/TvT.java	(revision 0)
+++ java/net/sf/l2j/gameserver/customs/eventengine/events/TvT.java	(revision 0)
@@ -0,0 +1,126 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.customs.eventengine.events;
+
+import net.sf.l2j.gameserver.customs.eventengine.Event;
+import net.sf.l2j.gameserver.customs.eventengine.EventSchedule;
+import net.sf.l2j.gameserver.customs.eventengine.EventState;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author Anarchy
+ *
+ */
+public class TvT extends Event
+{
+	@Override
+	public void runEvent()
+	{
+		openRegistrations(true, "Registrations have opened.", 2*1000*60); // change
+		if (!proceed())
+		{
+			abortEvent(true, "Event canceled due to lack of participation.");
+			return;
+		}
+		splitToTeams("Red,0,0,0,00FF00;Blue,0,0,0,FFFF00");
+		closeRegistrations(true, "Registrations have closed. Event will start in 20 seconds.", 20*1000);
+		teleportTeams(true, "You have been teleported to your team's spot. Event will begin in 20 seconds.", 20*1000);
+		startEvent(true, "The fight has begun!", 2*1000*60); // change
+		endEvent(true, "The event has ended.", 0);
+		rewardTopTeam(3470, 1);
+		teleportTeamsToTown();
+		clear();
+	}
+	
+	@Override
+	public boolean proceed()
+	{
+		if (getState() == EventState.REGISTERING)
+		{
+			if (players.size() < teams.size()) // change
+				return false;
+		}
+		
+		return true;
+	}
+	
+	@Override
+	public EventSchedule getScheduleMethod()
+	{
+		return EventSchedule.TIMES;
+	}
+
+	@Override
+	public String getScheduleTimes()
+	{
+		return "12:00;14:00";
+	}
+	
+	@Override
+	public String getName()
+	{
+		return "TvT";
+	}
+
+	@Override
+	public boolean allowFight()
+	{
+		return true;
+	}
+
+	@Override
+	public boolean allowTargetting()
+	{
+		return true;
+	}
+
+	@Override
+	public boolean allowFriendlyFire()
+	{
+		return false;
+	}
+
+	@Override
+	public boolean allowEscape()
+	{
+		return false;
+	}
+	
+	@Override
+	public boolean allowToVillage()
+	{
+		return false;
+	}
+	
+	@Override
+	public void onPlayerRegister(L2PcInstance p)
+	{
+		
+	}
+
+	@Override
+	public void onDie(L2PcInstance p, L2PcInstance killer)
+	{
+		if (getPlayerTeam(p) != null)
+		{
+			if (getPlayerTeam(p) != getPlayerTeam(killer))
+			{
+				getPlayerTeam(killer).setScore(getPlayerTeam(killer).getScore()+1);
+			}
+			
+			res(p, 5*1000);
+		}
+	}
+}
Index: java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java
===================================================================
--- java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java	(revision 115)
+++ java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java	(working copy)
@@ -19,6 +19,7 @@
 import java.util.logging.Logger;
 
 import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.customs.eventengine.EventRegister;
 import net.sf.l2j.gameserver.handler.voicedcommandhandlers.BugReport;
 import net.sf.l2j.gameserver.handler.voicedcommandhandlers.ChaosEventCommands;
 import net.sf.l2j.gameserver.handler.voicedcommandhandlers.SellBuffs;
@@ -50,6 +51,7 @@
 		
 		registerVoicedCommandHandler(new SellBuffs());
 		registerVoicedCommandHandler(new BugReport());
+		registerVoicedCommandHandler(new EventRegister());
 	}
 	
 	public void registerVoicedCommandHandler(IVoicedCommandHandler handler)
Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java	(revision 115)
+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java	(working copy)
@@ -16,6 +16,7 @@
 
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.SevenSignsFestival;
+import net.sf.l2j.gameserver.customs.eventengine.EventCommons;
 import net.sf.l2j.gameserver.customs.events.TvTEvent;
 import net.sf.l2j.gameserver.model.L2Party;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
@@ -42,6 +43,12 @@
 		if (player == null)
 			return;
 		
+		if (!EventCommons.allowExit(player))
+		{
+			sendPacket(RestartResponse.valueOf(false));
+			return;
+		}
+		
 		if (TvTEvent.getInstance()._players.contains(player))
 		{
 			player.sendMessage("You may not restart why having registered for TvT event.");
Index: java/net/sf/l2j/gameserver/customs/eventengine/Event.java
===================================================================
--- java/net/sf/l2j/gameserver/customs/eventengine/Event.java	(revision 0)
+++ java/net/sf/l2j/gameserver/customs/eventengine/Event.java	(revision 0)
@@ -0,0 +1,302 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.customs.eventengine;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.l2j.gameserver.ThreadPoolManager;
+import net.sf.l2j.gameserver.datatables.SkillTable;
+import net.sf.l2j.gameserver.model.L2World;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
+
+/**
+ * @author Anarchy
+ *
+ */
+public abstract class Event
+{
+	protected List<EventTeam> teams = new ArrayList<>();
+	protected List<L2PcInstance> players = new ArrayList<>();
+	private EventState state = EventState.INACTIVE;
+	
+	protected void res(final L2PcInstance p, long millis)
+	{
+		final EventTeam team = getPlayerTeam(p);
+		
+		if (team != null)
+		{
+			ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
+			{
+				@Override
+				public void run()
+				{
+					p.doRevive();
+					p.setCurrentCp(p.getMaxCp());
+					p.setCurrentHp(p.getMaxHp());
+					p.setCurrentMp(p.getMaxMp());
+					
+					p.teleToLocation(team.getX(), team.getY(), team.getZ(), 0);
+				}
+			}, millis);
+		}
+	}
+	
+	protected void removeBuff(L2PcInstance p, int skillId)
+	{
+		if (p.getFirstEffect(skillId) != null)
+		{
+			p.getFirstEffect(skillId).exit();
+		}
+	}
+	
+	protected void addBuff(L2PcInstance p, int skillId, int skillLvl)
+	{
+		SkillTable.getInstance().getInfo(7029, 1).getEffects(p, p);
+	}
+	
+	protected void teleportTeamsToTown()
+	{
+		for (EventTeam team : teams)
+		{
+			team.teleport(83339, 148599, -3405);
+		}
+	}
+	
+	protected void abortEvent(boolean announce, String msg)
+	{
+		if (announce)
+		{
+			announce(msg);
+		}
+		
+		state = EventState.INACTIVE;
+		
+		teleportTeamsToTown();
+		clear();
+	}
+	
+	protected void rewardTopTeam(int itemId, int count)
+	{
+		int i = 0;
+		EventTeam winner = null;
+		
+		for (EventTeam team : teams)
+		{
+			if (team.getScore() > i)
+			{
+				i = team.getScore();
+				winner = team;
+			}
+		}
+		
+		if (winner != null)
+		{
+			winner.reward(itemId, count);
+		}
+	}
+	
+	protected void endEvent(boolean announce, String msg, long sleepMillis)
+	{
+		if (announce)
+		{
+			announce(msg);
+		}
+		
+		state = EventState.INACTIVE;
+		
+		if (sleepMillis > 0)
+		{
+			sleep(sleepMillis);
+		}
+	}
+	
+	protected void startEvent(boolean sendMessage, String msg, long sleepMillis)
+	{
+		if (sendMessage)
+		{
+			for (EventTeam team : teams)
+			{
+				team.sendMessage(msg);
+			}
+		}
+		
+		state = EventState.RUNNING;
+		
+		if (sleepMillis > 0)
+		{
+			sleep(sleepMillis);
+		}
+	}
+	
+	protected void teleportTeams(boolean sendMessage, String msg, long sleepMillis)
+	{
+		if (sendMessage)
+		{
+			for (EventTeam team : teams)
+			{
+				team.sendMessage(msg);
+			}
+		}
+		
+		for (EventTeam team : teams)
+		{
+			team.teleport();
+		}
+		
+		if (sleepMillis > 0)
+		{
+			sleep(sleepMillis);
+		}
+	}
+	
+	protected void closeRegistrations(boolean announce, String msg, long sleepMillis)
+	{
+		if (announce)
+		{
+			announce(msg);
+		}
+		
+		state = EventState.WAITING;
+		
+		if (sleepMillis > 0)
+		{
+			sleep(sleepMillis);
+		}
+	}
+	
+	protected void openRegistrations(boolean announce, String msg, long sleepMillis)
+	{
+		if (announce)
+		{
+			announce(msg);
+		}
+		
+		state = EventState.REGISTERING;
+		
+		if (sleepMillis > 0)
+		{
+			sleep(sleepMillis);
+		}
+	}
+	
+	protected void splitToTeams(String teams_data)
+	{
+		registerTeams(teams_data);
+		
+		int i = teams.size()-1;
+		
+		for (L2PcInstance p : players)
+		{
+			teams.get(i).addPlayer(p);
+			i--;
+			
+			if (i == -1)
+				i = teams.size()-1;
+		}
+	}
+	
+	protected void registerTeams(String teams_data)
+	{
+		String[] teams_splitted = teams_data.split(";");
+		
+		for (String team : teams_splitted)
+		{
+			String[] team_data = team.split(",");
+			
+			String name = team_data[0];
+			int x = Integer.parseInt(team_data[1]);
+			int y = Integer.parseInt(team_data[2]);
+			int z = Integer.parseInt(team_data[3]);
+			int color = Integer.decode("0x"+team_data[4]);
+			
+			EventTeam t = new EventTeam(name, x, y, z, color);
+			
+			teams.add(t);
+		}
+	}
+	
+	protected void clear()
+	{
+		for (EventTeam team : teams)
+			team.drop();
+		
+		teams.clear();
+		players.clear();
+	}
+	
+	protected void announce(String msg)
+	{
+		CreatureSay cs = new CreatureSay(0, 15, getName(), msg);
+		
+		for (L2PcInstance p : L2World.getInstance().getAllPlayers().values())
+		{
+			p.sendPacket(cs);
+		}
+	}
+	
+	protected void sleep(long millis)
+	{
+		try
+		{
+			Thread.sleep(millis);
+		}
+		catch (InterruptedException e)
+		{
+			e.printStackTrace();
+		}
+	}
+	
+	public EventTeam getPlayerTeam(L2PcInstance p)
+	{
+		for (EventTeam team : teams)
+		{
+			if (team.containsPlayer(p))
+				return team;
+		}
+		
+		return null;
+	}
+	
+	public void registerPlayer(L2PcInstance p)
+	{
+		players.add(p);
+		onPlayerRegister(p);
+	}
+	
+	public boolean containsPlayer(L2PcInstance p)
+	{
+		return players.contains(p);
+	}
+	
+	public EventState getState()
+	{
+		return state;
+	}
+	
+	public abstract void runEvent();
+	public abstract boolean proceed();
+	public abstract EventSchedule getScheduleMethod();
+	public abstract String getScheduleTimes();
+	public abstract String getName();
+	public abstract boolean allowFight();
+	public abstract boolean allowTargetting();
+	public abstract boolean allowFriendlyFire();
+	public abstract boolean allowEscape();
+	public abstract boolean allowToVillage();
+	public abstract void onPlayerRegister(L2PcInstance p);
+	public abstract void onDie(L2PcInstance p, L2PcInstance killer);
+}
Index: java/net/sf/l2j/gameserver/handler/skillhandlers/GetPlayer.java
===================================================================
--- java/net/sf/l2j/gameserver/handler/skillhandlers/GetPlayer.java	(revision 115)
+++ java/net/sf/l2j/gameserver/handler/skillhandlers/GetPlayer.java	(working copy)
@@ -14,6 +14,7 @@
  */
 package net.sf.l2j.gameserver.handler.skillhandlers;
 
+import net.sf.l2j.gameserver.customs.eventengine.EventCommons;
 import net.sf.l2j.gameserver.customs.events.TvTEvent;
 import net.sf.l2j.gameserver.handler.ISkillHandler;
 import net.sf.l2j.gameserver.model.L2Object;
@@ -44,6 +45,9 @@
 			if (victim == null || victim.isAlikeDead())
 				continue;
 			
+			if (!EventCommons.allowEscape(victim))
+				continue;
+			
 			if (TvTEvent.getInstance()._players.contains(victim))
 			{
 				continue;
Index: java/net/sf/l2j/gameserver/GameServer.java
===================================================================
--- java/net/sf/l2j/gameserver/GameServer.java	(revision 115)
+++ java/net/sf/l2j/gameserver/GameServer.java	(working copy)
@@ -35,6 +35,7 @@
 import net.sf.l2j.gameserver.customs.CleanVoteStatus;
 import net.sf.l2j.gameserver.customs.PvpProtection;
 import net.sf.l2j.gameserver.customs.custombosses.CustomBossManager;
+import net.sf.l2j.gameserver.customs.eventengine.EventManager;
 import net.sf.l2j.gameserver.customs.events.ChaosEvent;
 import net.sf.l2j.gameserver.customs.events.HourlyPvpEvent;
 import net.sf.l2j.gameserver.customs.events.SoloEventManager;
@@ -298,6 +299,7 @@
 		BalancerLoad.LoadEm();
 		HourlyPvpEvent.getInstance();
 		SoloEventManager.getInstance();
+		EventManager.getInstance();
 		
 		Util.printSection("System");
 		TaskManager.getInstance();
Index: java/net/sf/l2j/gameserver/model/actor/L2Character.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/L2Character.java	(revision 115)
+++ java/net/sf/l2j/gameserver/model/actor/L2Character.java	(working copy)
@@ -32,6 +32,7 @@
 import net.sf.l2j.gameserver.ai.CtrlIntention;
 import net.sf.l2j.gameserver.ai.L2AttackableAI;
 import net.sf.l2j.gameserver.ai.L2CharacterAI;
+import net.sf.l2j.gameserver.customs.eventengine.EventCommons;
 import net.sf.l2j.gameserver.datatables.DoorTable;
 import net.sf.l2j.gameserver.datatables.MapRegionTable;
 import net.sf.l2j.gameserver.datatables.MapRegionTable.TeleportWhereType;
@@ -587,6 +588,15 @@
 			return;
 		}
 		
+		if (this instanceof L2PcInstance && target instanceof L2PcInstance)
+		{
+			if (!EventCommons.canAttack((L2PcInstance)this, (L2PcInstance)target))
+			{
+				sendPacket(ActionFailed.STATIC_PACKET);
+				return;
+			}
+		}
+		
 		if (!isAlikeDead())
 		{
 			if (this instanceof L2Npc && target.isAlikeDead() || !getKnownList().knowsObject(target))
@@ -1538,6 +1548,15 @@
 			return false;
 		}
 		
+		if (this instanceof L2PcInstance && getTarget() instanceof L2PcInstance)
+		{
+			if (!EventCommons.canAttack((L2PcInstance)this, (L2PcInstance)getTarget()))
+			{
+				sendPacket(ActionFailed.STATIC_PACKET);
+				return false;
+			}
+		}
+		
 		return true;
 	}
 	
Index: java/net/sf/l2j/gameserver/handler/usercommandhandlers/Escape.java
===================================================================
--- java/net/sf/l2j/gameserver/handler/usercommandhandlers/Escape.java	(revision 115)
+++ java/net/sf/l2j/gameserver/handler/usercommandhandlers/Escape.java	(working copy)
@@ -14,6 +14,7 @@
  */
 package net.sf.l2j.gameserver.handler.usercommandhandlers;
 
+import net.sf.l2j.gameserver.customs.eventengine.EventCommons;
 import net.sf.l2j.gameserver.customs.events.TvTEvent;
 import net.sf.l2j.gameserver.datatables.SkillTable;
 import net.sf.l2j.gameserver.handler.IUserCommandHandler;
@@ -38,6 +39,9 @@
 			return false;
 		}
 		
+		if (!EventCommons.allowEscape(activeChar))
+			return false;
+		
 		activeChar.stopMove(null);
 		
 		// Official timer 5 minutes, for GM 1 second
Index: java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java	(revision 115)
+++ java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java	(working copy)
@@ -52,6 +52,7 @@
 import net.sf.l2j.gameserver.communitybbs.Manager.ForumsBBSManager;
 import net.sf.l2j.gameserver.customs.BuffShop;
 import net.sf.l2j.gameserver.customs.PvpProtection;
+import net.sf.l2j.gameserver.customs.eventengine.EventCommons;
 import net.sf.l2j.gameserver.customs.events.ChaosEvent;
 import net.sf.l2j.gameserver.customs.events.HourlyPvpEvent;
 import net.sf.l2j.gameserver.customs.events.TvTEvent;
@@ -3418,6 +3419,12 @@
 		// Check if the player already target this L2PcInstance
 		if (player.getTarget() != this)
 		{
+			if (!EventCommons.canTarget(player, this))
+			{
+				player.sendPacket(ActionFailed.STATIC_PACKET);
+				return;
+			}
+			
 			// Set the target of the player
 			player.setTarget(this);
 			
@@ -4185,6 +4192,8 @@
 			{
 				L2PcInstance kl = (L2PcInstance)killer;
 				
+				EventCommons.onDie(this, kl);
+				
 				if (TvTEvent.getInstance()._state == TvTEvent.EventState.RUNNING)
 				{
 					if ((TvTEvent.getInstance()._team1.contains(this) && TvTEvent.getInstance()._team2.contains(kl)) || (TvTEvent.getInstance()._team2.contains(this) && TvTEvent.getInstance()._team1.contains(kl)))
Index: java/net/sf/l2j/gameserver/customs/eventengine/EventCommons.java
===================================================================
--- java/net/sf/l2j/gameserver/customs/eventengine/EventCommons.java	(revision 0)
+++ java/net/sf/l2j/gameserver/customs/eventengine/EventCommons.java	(revision 0)
@@ -0,0 +1,199 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.customs.eventengine;
+
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author Anarchy
+ *
+ * A static class for checks.
+ */
+public class EventCommons
+{
+	public static void onDie(L2PcInstance victim, L2PcInstance killer)
+	{
+		Event e = null;
+		
+		for (Event event : EventManager.getInstance().getAllEvents())
+		{
+			if (event.getState() != EventState.INACTIVE)
+			{
+				if (event.containsPlayer(victim) && event.containsPlayer(killer))
+				{
+					e = event;
+					break;
+				}
+			}
+		}
+		
+		if (e != null)
+		{
+			e.onDie(victim, killer);
+		}
+	}
+	
+	public static boolean allowToVillage(L2PcInstance player)
+	{
+		Event e = null;
+		
+		for (Event event : EventManager.getInstance().getAllEvents())
+		{
+			if (event.getState() != EventState.INACTIVE)
+			{
+				if (event.containsPlayer(player))
+				{
+					e = event;
+					break;
+				}
+			}
+		}
+		
+		if (e != null)
+		{
+			if (!e.allowToVillage())
+				return false;
+		}
+		
+		return true;
+	}
+	
+	public static boolean isInEvent(L2PcInstance player)
+	{
+		Event e = null;
+		
+		for (Event event : EventManager.getInstance().getAllEvents())
+		{
+			if (event.getState() != EventState.INACTIVE)
+			{
+				if (event.containsPlayer(player))
+				{
+					e = event;
+					break;
+				}
+			}
+		}
+		
+		if (e != null)
+		{
+			return true;
+		}
+		
+		return false;
+	}
+	
+	public static boolean allowExit(L2PcInstance player)
+	{
+		Event e = null;
+		
+		for (Event event : EventManager.getInstance().getAllEvents())
+		{
+			if (event.getState() != EventState.INACTIVE)
+			{
+				if (event.containsPlayer(player))
+				{
+					e = event;
+					break;
+				}
+			}
+		}
+		
+		if (e != null)
+		{
+			player.sendMessage("You may not exit while in an event.");
+			return false;
+		}
+		
+		return true;
+	}
+	
+	public static boolean allowEscape(L2PcInstance player)
+	{
+		Event e = null;
+		
+		for (Event event : EventManager.getInstance().getAllEvents())
+		{
+			if (event.getState() != EventState.INACTIVE)
+			{
+				if (event.containsPlayer(player))
+				{
+					e = event;
+					break;
+				}
+			}
+		}
+		
+		if (e != null)
+		{
+			if (!e.allowEscape() && e.containsPlayer(player))
+				return false;
+		}
+		
+		return true;
+	}
+	
+	public static boolean canTarget(L2PcInstance player, L2PcInstance target)
+	{
+		Event e = null;
+		
+		for (Event event : EventManager.getInstance().getAllEvents())
+		{
+			if (event.getState() != EventState.INACTIVE)
+			{
+				if (event.containsPlayer(player) && event.containsPlayer(target))
+				{
+					e = event;
+					break;
+				}
+			}
+		}
+		
+		if (e != null)
+		{
+			if (!e.allowTargetting() && e.getPlayerTeam(player) != e.getPlayerTeam(target))
+				return false;
+		}
+		
+		return true;
+	}
+	
+	public static boolean canAttack(L2PcInstance player, L2PcInstance target)
+	{
+		Event e = null;
+		
+		for (Event event : EventManager.getInstance().getAllEvents())
+		{
+			if (event.getState() != EventState.INACTIVE)
+			{
+				if (event.containsPlayer(player) && event.containsPlayer(target))
+				{
+					e = event;
+					break;
+				}
+			}
+		}
+		
+		if (e != null)
+		{
+			if (!e.allowFight())
+				return false;
+			
+			if (!e.allowFriendlyFire() && e.getPlayerTeam(player) == e.getPlayerTeam(target) && e.getPlayerTeam(player) != null)
+				return false;
+		}
+		
+		return true;
+	}
+}