Browse Source

BETA: Reworking listeners:
* Reimplemented all existing listeners and hooks implementations as one unified implementation.
* The new implementation is using the functional interfaces of java 8 which makes them really easy to use.
* Annotations binding is supported also.
* There will be more documentation about them soon.
* Reviewed by: Zoey76, Nos, DrHouse, Adry_85, FBIagent, St3eT, Tryskell, Nik

Rumen Nikiforov 11 năm trước cách đây
mục cha
commit
732b2e70c0
100 tập tin đã thay đổi với 5581 bổ sung2931 xóa
  1. 2 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/GameServer.java
  2. 85 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/ThreadPoolManager.java
  3. 8 28
      L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2AttackableAI.java
  4. 4 10
      L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2CharacterAI.java
  5. 15 94
      L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/ClanTable.java
  6. 4 66
      L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/ItemTable.java
  7. 4 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/enums/EventState.java
  8. 0 60
      L2J_Server_BETA/java/com/l2jserver/gameserver/enums/QuestEventType.java
  9. 3 9
      L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/WalkingManager.java
  10. 18 187
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Clan.java
  11. 2 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Object.java
  12. 3 9
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/WalkInfo.java
  13. 10 54
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Attackable.java
  14. 68 36
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java
  15. 16 34
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Npc.java
  16. 5 14
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Playable.java
  17. 4 23
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Summon.java
  18. 0 162
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/AbstractCharEvents.java
  19. 0 275
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/CharEvents.java
  20. 0 115
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/PlayableEvents.java
  21. 0 277
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/PlayerEvents.java
  22. 0 30
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IDamageDealtEventListener.java
  23. 0 29
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IDeathEventListener.java
  24. 0 29
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IExperienceReceivedEventListener.java
  25. 0 29
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IPlayerLoginEventListener.java
  26. 0 29
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IPlayerLogoutEventListener.java
  27. 0 29
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IPvPKillEventListener.java
  28. 0 29
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IPvPPointsEventChange.java
  29. 0 31
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/ISkillUseEventListener.java
  30. 6 9
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2GuardInstance.java
  31. 72 400
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
  32. 6 19
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2QuestGuardInstance.java
  33. 6 9
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2SepulcherNpcInstance.java
  34. 6 16
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2TrapInstance.java
  35. 5 11
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/knownlist/NpcKnownList.java
  36. 15 25
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
  37. 1 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PetStat.java
  38. 9 21
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PlayableStat.java
  39. 2 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2CharTemplate.java
  40. 0 60
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2NpcTemplate.java
  41. 2 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/AbstractResidence.java
  42. 9 71
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/FortSiege.java
  43. 13 80
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Siege.java
  44. 14 91
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/TvTEvent.java
  45. 12 10
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/TvTEventListener.java
  46. 2458 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/AbstractScript.java
  47. 250 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/EventDispatcher.java
  48. 242 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/EventType.java
  49. 10 5
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/ListenerRegisterType.java
  50. 107 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/ListenersContainer.java
  51. 6 4
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/annotations/Npc.java
  52. 4 4
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/annotations/Npcs.java
  53. 6 4
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/annotations/RegisterEvent.java
  54. 5 5
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/IBaseEvent.java
  55. 55 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureAttack.java
  56. 84 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureDamage.java
  57. 55 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureKill.java
  58. 31 52
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureSkillUse.java
  59. 21 4
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureTeleported.java
  60. 19 26
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureZoneEnter.java
  61. 19 26
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureZoneExit.java
  62. 21 24
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcCanBeSeen.java
  63. 25 32
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcCreatureSee.java
  64. 69 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcEventReceived.java
  65. 55 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcFirstTalk.java
  66. 22 8
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcMoveFinished.java
  67. 47 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcMoveNodeArrived.java
  68. 47 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcMoveRouteFinished.java
  69. 63 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcSkillFinished.java
  70. 34 20
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcSkillSee.java
  71. 21 13
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcSpawn.java
  72. 62 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/attackable/OnAttackableAggroRangeEnter.java
  73. 78 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/attackable/OnAttackableAttack.java
  74. 69 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/attackable/OnAttackableFactionCall.java
  75. 62 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/attackable/OnAttackableHate.java
  76. 63 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/attackable/OnAttackableKill.java
  77. 35 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/playable/OnPlayableExpChanged.java
  78. 70 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerAugment.java
  79. 13 10
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerBypass.java
  80. 68 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerChat.java
  81. 69 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerCreate.java
  82. 15 21
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerDelete.java
  83. 18 28
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerDlgAnswer.java
  84. 17 26
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerEquipItem.java
  85. 61 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerFameChanged.java
  86. 55 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerHennaAdd.java
  87. 16 42
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerHennaRemove.java
  88. 61 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerKarmaChanged.java
  89. 61 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerLevelChanged.java
  90. 21 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerLogin.java
  91. 21 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerLogout.java
  92. 61 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerPKChanged.java
  93. 21 40
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerProfessionChange.java
  94. 61 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerPvPChanged.java
  95. 28 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerPvPKill.java
  96. 61 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerRestore.java
  97. 69 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerSelect.java
  98. 71 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerSkillLearn.java
  99. 15 7
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerSummonSpawn.java
  100. 54 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerTransform.java

+ 2 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/GameServer.java

@@ -129,6 +129,7 @@ import com.l2jserver.gameserver.model.PartyMatchRoomList;
 import com.l2jserver.gameserver.model.PartyMatchWaitingList;
 import com.l2jserver.gameserver.model.entity.Hero;
 import com.l2jserver.gameserver.model.entity.TvTManager;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
 import com.l2jserver.gameserver.model.olympiad.Olympiad;
 import com.l2jserver.gameserver.network.L2GameClient;
 import com.l2jserver.gameserver.network.L2GamePacketHandler;
@@ -201,6 +202,7 @@ public class GameServer
 		}
 		
 		ThreadPoolManager.getInstance();
+		EventDispatcher.getInstance();
 		
 		new File("log/game").mkdirs();
 		

+ 85 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/ThreadPoolManager.java

@@ -106,9 +106,11 @@ public class ThreadPoolManager
 	protected ScheduledThreadPoolExecutor _effectsScheduledThreadPool;
 	protected ScheduledThreadPoolExecutor _generalScheduledThreadPool;
 	protected ScheduledThreadPoolExecutor _aiScheduledThreadPool;
+	protected ScheduledThreadPoolExecutor _eventScheduledThreadPool;
 	private final ThreadPoolExecutor _generalPacketsThreadPool;
 	private final ThreadPoolExecutor _ioPacketsThreadPool;
 	private final ThreadPoolExecutor _generalThreadPool;
+	private final ThreadPoolExecutor _eventThreadPool;
 	
 	private boolean _shutdown;
 	
@@ -121,10 +123,12 @@ public class ThreadPoolManager
 	{
 		_effectsScheduledThreadPool = new ScheduledThreadPoolExecutor(Config.THREAD_P_EFFECTS, new PriorityThreadFactory("EffectsSTPool", Thread.NORM_PRIORITY));
 		_generalScheduledThreadPool = new ScheduledThreadPoolExecutor(Config.THREAD_P_GENERAL, new PriorityThreadFactory("GeneralSTPool", Thread.NORM_PRIORITY));
+		_eventScheduledThreadPool = new ScheduledThreadPoolExecutor(2, new PriorityThreadFactory("EventSTPool", Thread.NORM_PRIORITY));
 		_ioPacketsThreadPool = new ThreadPoolExecutor(Config.IO_PACKET_THREAD_CORE_SIZE, Integer.MAX_VALUE, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("I/O Packet Pool", Thread.NORM_PRIORITY + 1));
 		_generalPacketsThreadPool = new ThreadPoolExecutor(Config.GENERAL_PACKET_THREAD_CORE_SIZE, Config.GENERAL_PACKET_THREAD_CORE_SIZE + 2, 15L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("Normal Packet Pool", Thread.NORM_PRIORITY + 1));
 		_generalThreadPool = new ThreadPoolExecutor(Config.GENERAL_THREAD_CORE_SIZE, Config.GENERAL_THREAD_CORE_SIZE + 2, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("General Pool", Thread.NORM_PRIORITY));
 		_aiScheduledThreadPool = new ScheduledThreadPoolExecutor(Config.AI_MAX_THREAD, new PriorityThreadFactory("AISTPool", Thread.NORM_PRIORITY));
+		_eventThreadPool = new ThreadPoolExecutor(1, 2, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("Event Pool", Thread.NORM_PRIORITY));
 		
 		scheduleGeneralAtFixedRate(new PurgeTask(), 10, 5, TimeUnit.MINUTES);
 	}
@@ -241,6 +245,56 @@ public class ThreadPoolManager
 		}
 	}
 	
+	/**
+	 * Schedules a event task to be executed after the given delay.
+	 * @param task the task to execute
+	 * @param delay the delay in the given time unit
+	 * @param unit the time unit of the delay parameter
+	 * @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation
+	 */
+	public ScheduledFuture<?> scheduleEvent(Runnable task, long delay, TimeUnit unit)
+	{
+		try
+		{
+			return _eventScheduledThreadPool.schedule(new RunnableWrapper(task), delay, unit);
+		}
+		catch (RejectedExecutionException e)
+		{
+			return null; /* shutdown, ignore */
+		}
+	}
+	
+	/**
+	 * Schedules a event task to be executed after the given delay.
+	 * @param task the task to execute
+	 * @param delay the delay in milliseconds
+	 * @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation
+	 */
+	public ScheduledFuture<?> scheduleEvent(Runnable task, long delay)
+	{
+		return scheduleEvent(task, delay, TimeUnit.MILLISECONDS);
+	}
+	
+	/**
+	 * Schedules a event task to be executed at fixed rate.
+	 * @param task the task to execute
+	 * @param initialDelay the initial delay in the given time unit
+	 * @param period the period between executions in the given time unit
+	 * @param unit the time unit of the initialDelay and period parameters
+	 * @return a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation
+	 */
+	public ScheduledFuture<?> scheduleEventAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit)
+	{
+		try
+		{
+			return _eventScheduledThreadPool.scheduleAtFixedRate(new RunnableWrapper(task), initialDelay, period, unit);
+		}
+		catch (RejectedExecutionException e)
+		{
+			return null; /* shutdown, ignore */
+		}
+	}
+	
 	/**
 	 * Schedules a general task to be executed at fixed rate.
 	 * @param task the task to execute
@@ -351,6 +405,15 @@ public class ThreadPoolManager
 		_aiScheduledThreadPool.execute(new RunnableWrapper(task));
 	}
 	
+	/**
+	 * Executes an Event task sometime in future in another thread.
+	 * @param task the task to execute
+	 */
+	public void executeEvent(Runnable task)
+	{
+		_eventThreadPool.execute(new RunnableWrapper(task));
+	}
+	
 	public String[] getStats()
 	{
 		return new String[]
@@ -379,6 +442,14 @@ public class ThreadPoolManager
 			" |- MaximumPoolSize: " + _aiScheduledThreadPool.getMaximumPoolSize(),
 			" |- CompletedTasks:  " + _aiScheduledThreadPool.getCompletedTaskCount(),
 			" |- ScheduledTasks:  " + _aiScheduledThreadPool.getQueue().size(),
+			" | -------",
+			" + Event:",
+			" |- ActiveThreads:   " + _eventScheduledThreadPool.getActiveCount(),
+			" |- getCorePoolSize: " + _eventScheduledThreadPool.getCorePoolSize(),
+			" |- PoolSize:        " + _eventScheduledThreadPool.getPoolSize(),
+			" |- MaximumPoolSize: " + _eventScheduledThreadPool.getMaximumPoolSize(),
+			" |- CompletedTasks:  " + _eventScheduledThreadPool.getCompletedTaskCount(),
+			" |- ScheduledTasks:  " + _eventScheduledThreadPool.getQueue().size(),
 			"TP:",
 			" + Packets:",
 			" |- ActiveThreads:   " + _generalPacketsThreadPool.getActiveCount(),
@@ -407,6 +478,15 @@ public class ThreadPoolManager
 			" |- CompletedTasks:  " + _generalThreadPool.getCompletedTaskCount(),
 			" |- QueuedTasks:     " + _generalThreadPool.getQueue().size(),
 			" | -------",
+			" + Event Tasks:",
+			" |- ActiveThreads:   " + _eventThreadPool.getActiveCount(),
+			" |- getCorePoolSize: " + _eventThreadPool.getCorePoolSize(),
+			" |- MaximumPoolSize: " + _eventThreadPool.getMaximumPoolSize(),
+			" |- LargestPoolSize: " + _eventThreadPool.getLargestPoolSize(),
+			" |- PoolSize:        " + _eventThreadPool.getPoolSize(),
+			" |- CompletedTasks:  " + _eventThreadPool.getCompletedTaskCount(),
+			" |- QueuedTasks:     " + _eventThreadPool.getQueue().size(),
+			" | -------",
 			" + Javolution stats:",
 			" |- FastList:        " + FastList.report(),
 			" |- FastMap:        " + FastMap.report(),
@@ -453,11 +533,13 @@ public class ThreadPoolManager
 			_generalPacketsThreadPool.awaitTermination(1, TimeUnit.SECONDS);
 			_ioPacketsThreadPool.awaitTermination(1, TimeUnit.SECONDS);
 			_generalThreadPool.awaitTermination(1, TimeUnit.SECONDS);
+			_eventThreadPool.awaitTermination(1, TimeUnit.SECONDS);
 			_effectsScheduledThreadPool.shutdown();
 			_generalScheduledThreadPool.shutdown();
 			_generalPacketsThreadPool.shutdown();
 			_ioPacketsThreadPool.shutdown();
 			_generalThreadPool.shutdown();
+			_eventThreadPool.shutdown();
 			_log.info("All ThreadPools are now stopped");
 			
 		}
@@ -477,9 +559,11 @@ public class ThreadPoolManager
 		_effectsScheduledThreadPool.purge();
 		_generalScheduledThreadPool.purge();
 		_aiScheduledThreadPool.purge();
+		_eventScheduledThreadPool.purge();
 		_ioPacketsThreadPool.purge();
 		_generalPacketsThreadPool.purge();
 		_generalThreadPool.purge();
+		_eventThreadPool.purge();
 	}
 	
 	public String getPacketStats()
@@ -589,6 +673,7 @@ public class ThreadPoolManager
 			_effectsScheduledThreadPool.purge();
 			_generalScheduledThreadPool.purge();
 			_aiScheduledThreadPool.purge();
+			_eventScheduledThreadPool.purge();
 		}
 	}
 	

+ 8 - 28
L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2AttackableAI.java

@@ -36,7 +36,6 @@ import com.l2jserver.gameserver.datatables.NpcData;
 import com.l2jserver.gameserver.datatables.TerritoryTable;
 import com.l2jserver.gameserver.enums.AISkillScope;
 import com.l2jserver.gameserver.enums.AIType;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.instancemanager.DimensionalRiftManager;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.Location;
@@ -57,7 +56,10 @@ import com.l2jserver.gameserver.model.actor.instance.L2RiftInvaderInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2StaticObjectInstance;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.model.effects.L2EffectType;
-import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableFactionCall;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableHate;
+import com.l2jserver.gameserver.model.events.returns.TerminateReturn;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
 import com.l2jserver.gameserver.model.zone.ZoneId;
@@ -481,28 +483,15 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 					}
 				}
 				
-				// TODO: The AI Script ought to handle aggro behaviors in onSee. Once implemented, aggro behaviors ought
-				// to be removed from here. (Fulminus)
 				// For each L2Character check if the target is autoattackable
 				if (autoAttackCondition(target)) // check aggression
 				{
 					if (target.isPlayable())
 					{
-						final List<Quest> quests = getActiveChar().getTemplate().getEventQuests(QuestEventType.ON_NPC_HATE);
-						if (quests != null)
+						final TerminateReturn term = EventDispatcher.getInstance().notifyEvent(new OnAttackableHate(getActiveChar(), target.getActingPlayer(), target.isSummon()), getActiveChar(), TerminateReturn.class);
+						if ((term != null) && term.terminate())
 						{
-							boolean breaking = false;
-							for (Quest q : quests)
-							{
-								if (!q.onNpcHate(getActiveChar(), (L2Playable) target))
-								{
-									breaking = true;
-								}
-							}
-							if (breaking)
-							{
-								continue;
-							}
+							continue;
 						}
 					}
 					
@@ -790,16 +779,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 							{
 								if (originalAttackTarget.isPlayable())
 								{
-									List<Quest> quests = called.getTemplate().getEventQuests(QuestEventType.ON_FACTION_CALL);
-									if ((quests != null) && !quests.isEmpty())
-									{
-										L2PcInstance player = originalAttackTarget.getActingPlayer();
-										boolean isSummon = originalAttackTarget.isSummon();
-										for (Quest quest : quests)
-										{
-											quest.notifyFactionCall(called, getActiveChar(), player, isSummon);
-										}
-									}
+									EventDispatcher.getInstance().notifyEventAsync(new OnAttackableFactionCall(called, getActiveChar(), originalAttackTarget.getActingPlayer(), originalAttackTarget.isSummon()), called);
 								}
 								else if ((called instanceof L2Attackable) && (getAttackTarget() != null) && (called.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK))
 								{

+ 4 - 10
L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2CharacterAI.java

@@ -37,7 +37,6 @@ import com.l2jserver.gameserver.GameTimeController;
 import com.l2jserver.gameserver.GeoData;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.enums.ItemLocation;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.instancemanager.WalkingManager;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.Location;
@@ -49,11 +48,12 @@ import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.model.effects.L2EffectType;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveFinished;
 import com.l2jserver.gameserver.model.interfaces.ILocational;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.type.WeaponType;
-import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
 import com.l2jserver.gameserver.network.SystemMessageId;
@@ -747,14 +747,8 @@ public class L2CharacterAI extends AbstractAI
 			L2Npc npc = (L2Npc) _actor;
 			WalkingManager.getInstance().onArrived(npc); // Walking Manager support
 			
-			// Notify quest
-			if (npc.getTemplate().getEventQuests(QuestEventType.ON_MOVE_FINISHED) != null)
-			{
-				for (Quest quest : npc.getTemplate().getEventQuests(QuestEventType.ON_MOVE_FINISHED))
-				{
-					quest.notifyMoveFinished(npc);
-				}
-			}
+			// Notify to scripts
+			EventDispatcher.getInstance().notifyEventAsync(new OnNpcMoveFinished(npc), npc);
 		}
 		
 		// If the Intention was AI_INTENTION_MOVE_TO, set the Intention to AI_INTENTION_ACTIVE

+ 15 - 94
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/ClanTable.java

@@ -29,8 +29,6 @@ import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import javolution.util.FastList;
-
 import com.l2jserver.Config;
 import com.l2jserver.L2DatabaseFactory;
 import com.l2jserver.gameserver.ThreadPoolManager;
@@ -50,6 +48,11 @@ import com.l2jserver.gameserver.model.entity.Fort;
 import com.l2jserver.gameserver.model.entity.FortSiege;
 import com.l2jserver.gameserver.model.entity.Siege;
 import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanCreate;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanDestroy;
+import com.l2jserver.gameserver.model.events.impl.clan.OnClanWarFinish;
+import com.l2jserver.gameserver.model.events.impl.clan.OnClanWarStart;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.communityserver.CommunityServerThread;
 import com.l2jserver.gameserver.network.communityserver.writepackets.WorldInfo;
@@ -59,9 +62,6 @@ import com.l2jserver.gameserver.network.serverpackets.PledgeShowMemberListAll;
 import com.l2jserver.gameserver.network.serverpackets.PledgeShowMemberListUpdate;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 import com.l2jserver.gameserver.network.serverpackets.UserInfo;
-import com.l2jserver.gameserver.scripting.scriptengine.events.ClanWarEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.impl.L2Script.EventStage;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.clan.ClanWarListener;
 import com.l2jserver.gameserver.util.Util;
 import com.l2jserver.util.EnumIntBitmask;
 
@@ -72,8 +72,6 @@ public class ClanTable
 {
 	private static final Logger _log = Logger.getLogger(ClanTable.class.getName());
 	
-	private static List<ClanWarListener> clanWarListeners = new FastList<ClanWarListener>().shared();
-	
 	private final Map<Integer, L2Clan> _clans = new HashMap<>();
 	
 	public L2Clan[] getClans()
@@ -213,6 +211,9 @@ public class ClanTable
 		player.sendPacket(SystemMessageId.CLAN_CREATED);
 		// notify CB server that a new Clan is created
 		CommunityServerThread.getInstance().sendPacket(new WorldInfo(null, clan, WorldInfo.TYPE_UPDATE_CLAN_DATA));
+		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerClanCreate(player, clan));
 		return clan;
 	}
 	
@@ -350,6 +351,9 @@ public class ClanTable
 		{
 			_log.log(Level.SEVERE, getClass().getSimpleName() + ": Error removing clan from DB.", e);
 		}
+		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerClanDestroy(leaderMember, clan));
 	}
 	
 	public void scheduleRemoveClan(final int clanId)
@@ -381,13 +385,10 @@ public class ClanTable
 	
 	public void storeclanswars(int clanId1, int clanId2)
 	{
-		L2Clan clan1 = ClanTable.getInstance().getClan(clanId1);
-		L2Clan clan2 = ClanTable.getInstance().getClan(clanId2);
+		final L2Clan clan1 = ClanTable.getInstance().getClan(clanId1);
+		final L2Clan clan2 = ClanTable.getInstance().getClan(clanId2);
 		
-		if (!fireClanWarStartListeners(clan1, clan2))
-		{
-			return;
-		}
+		EventDispatcher.getInstance().notifyEventAsync(new OnClanWarStart(clan1, clan2));
 		
 		clan1.setEnemyClan(clan2);
 		clan2.setAttackerClan(clan1);
@@ -426,10 +427,7 @@ public class ClanTable
 		L2Clan clan1 = ClanTable.getInstance().getClan(clanId1);
 		L2Clan clan2 = ClanTable.getInstance().getClan(clanId2);
 		
-		if (!fireClanWarEndListeners(clan1, clan2))
-		{
-			return;
-		}
+		EventDispatcher.getInstance().notifyEventAsync(new OnClanWarFinish(clan1, clan2));
 		
 		clan1.deleteEnemyClan(clan2);
 		clan2.deleteAttackerClan(clan1);
@@ -469,10 +467,6 @@ public class ClanTable
 		}
 		if (count == (clan1.getMembers().length - 1))
 		{
-			if (!fireClanWarEndListeners(clan1, clan2))
-			{
-				return;
-			}
 			clan1.deleteEnemyClan(clan2);
 			clan2.deleteEnemyClan(clan1);
 			deleteclanswars(clan1.getId(), clan2.getId());
@@ -553,79 +547,6 @@ public class ClanTable
 		}
 	}
 	
-	/**
-	 * Fires all the ClanWarListener.onWarStart() methods<br>
-	 * Returns true if the clan war is allowed
-	 * @param clan1
-	 * @param clan2
-	 * @return
-	 */
-	private boolean fireClanWarStartListeners(L2Clan clan1, L2Clan clan2)
-	{
-		if (!clanWarListeners.isEmpty() && (clan1 != null) && (clan2 != null))
-		{
-			ClanWarEvent event = new ClanWarEvent();
-			event.setClan1(clan1);
-			event.setClan2(clan2);
-			event.setStage(EventStage.START);
-			for (ClanWarListener listener : clanWarListeners)
-			{
-				if (!listener.onWarStart(event))
-				{
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fires all the ClanWarListener.onWarEnd() methods<br>
-	 * Returns true if the clan war end is allowed
-	 * @param clan1
-	 * @param clan2
-	 * @return
-	 */
-	private boolean fireClanWarEndListeners(L2Clan clan1, L2Clan clan2)
-	{
-		if (!clanWarListeners.isEmpty() && (clan1 != null) && (clan2 != null))
-		{
-			ClanWarEvent event = new ClanWarEvent();
-			event.setClan1(clan1);
-			event.setClan2(clan2);
-			event.setStage(EventStage.END);
-			for (ClanWarListener listener : clanWarListeners)
-			{
-				if (!listener.onWarEnd(event))
-				{
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Adds a clan war listener
-	 * @param listener
-	 */
-	public static void addClanWarListener(ClanWarListener listener)
-	{
-		if (!clanWarListeners.contains(listener))
-		{
-			clanWarListeners.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes a clan war listener
-	 * @param listener
-	 */
-	public static void removeClanWarListener(ClanWarListener listener)
-	{
-		clanWarListeners.remove(listener);
-	}
-	
 	public static ClanTable getInstance()
 	{
 		return SingletonHolder._instance;

+ 4 - 66
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/ItemTable.java

@@ -29,7 +29,6 @@ import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
 
-import javolution.util.FastList;
 import javolution.util.FastMap;
 
 import com.l2jserver.Config;
@@ -43,13 +42,13 @@ import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.instance.L2EventMonsterInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.item.OnItemCreate;
 import com.l2jserver.gameserver.model.items.L2Armor;
 import com.l2jserver.gameserver.model.items.L2EtcItem;
 import com.l2jserver.gameserver.model.items.L2Item;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
-import com.l2jserver.gameserver.scripting.scriptengine.events.ItemCreateEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.NewItemListener;
 import com.l2jserver.gameserver.util.GMAudit;
 
 /**
@@ -60,8 +59,6 @@ public class ItemTable
 	private static Logger _log = Logger.getLogger(ItemTable.class.getName());
 	private static Logger _logItems = Logger.getLogger("item");
 	
-	private static FastList<NewItemListener> newItemListeners = new FastList<NewItemListener>().shared();
-	
 	public static final Map<String, Integer> _slots = new FastMap<>();
 	
 	private L2Item[] _allTemplates;
@@ -213,11 +210,6 @@ public class ItemTable
 	 */
 	public L2ItemInstance createItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
 	{
-		if (!fireNewItemListeners(process, itemId, count, actor, reference))
-		{
-			return null;
-		}
-		
 		// Create and Init the L2ItemInstance corresponding to the Item Identifier
 		L2ItemInstance item = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
 		
@@ -294,6 +286,8 @@ public class ItemTable
 			}
 		}
 		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnItemCreate(process, item, actor, reference), item.getItem());
 		return item;
 	}
 	
@@ -444,60 +438,4 @@ public class ItemTable
 	{
 		protected static final ItemTable _instance = new ItemTable();
 	}
-	
-	// Listeners
-	
-	/**
-	 * Fires all the new item listeners, if any
-	 * @param process
-	 * @param itemId
-	 * @param count
-	 * @param actor
-	 * @param reference
-	 * @return
-	 */
-	private boolean fireNewItemListeners(String process, int itemId, long count, L2PcInstance actor, Object reference)
-	{
-		if (!newItemListeners.isEmpty() && (actor != null))
-		{
-			ItemCreateEvent event = new ItemCreateEvent();
-			event.setItemId(itemId);
-			event.setPlayer(actor);
-			event.setCount(count);
-			event.setProcess(process);
-			event.setReference(reference);
-			for (NewItemListener listener : newItemListeners)
-			{
-				if (listener.containsItemId(itemId))
-				{
-					if (!listener.onCreate(event))
-					{
-						return false;
-					}
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Adds a new item listener
-	 * @param listener
-	 */
-	public static void addNewItemListener(NewItemListener listener)
-	{
-		if (!newItemListeners.contains(listener))
-		{
-			newItemListeners.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes a new item listener
-	 * @param listener
-	 */
-	public static void removeNewItemListener(NewItemListener listener)
-	{
-		newItemListeners.remove(listener);
-	}
 }

+ 4 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IEventListener.java → L2J_Server_BETA/java/com/l2jserver/gameserver/enums/EventState.java

@@ -16,11 +16,13 @@
  * 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 com.l2jserver.gameserver.model.actor.events.listeners;
+package com.l2jserver.gameserver.enums;
 
 /**
  * @author UnAfraid
  */
-public interface IEventListener
+public enum EventState
 {
+	STARTED,
+	FINISHED,
 }

+ 0 - 60
L2J_Server_BETA/java/com/l2jserver/gameserver/enums/QuestEventType.java

@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.enums;
-
-public enum QuestEventType
-{
-	ON_FIRST_TALK(false), // control the first dialog shown by NPCs when they are clicked (some quests must override the default npc action)
-	QUEST_START(true), // onTalk action from start npcs
-	ON_TALK(true), // onTalk action from npcs participating in a quest
-	ON_ATTACK(true), // onAttack action triggered when a mob gets attacked by someone
-	ON_KILL(true), // onKill action triggered when a mob gets killed.
-	ON_SPAWN(true), // onSpawn action triggered when an NPC is spawned or respawned.
-	ON_SKILL_SEE(true), // NPC or Mob saw a person casting a skill (regardless what the target is).
-	ON_FACTION_CALL(true), // NPC or Mob saw a person casting a skill (regardless what the target is).
-	ON_AGGRO_RANGE_ENTER(true), // a person came within the Npc/Mob's range
-	ON_SPELL_FINISHED(true), // on spell finished action when npc finish casting skill
-	ON_SKILL_LEARN(false), // control the AcquireSkill dialog from quest script
-	ON_ENTER_ZONE(true), // on zone enter
-	ON_EXIT_ZONE(true), // on zone exit
-	ON_TRAP_ACTION(true), // on zone exit
-	ON_ITEM_USE(true),
-	ON_EVENT_RECEIVED(true), // onEventReceived action, triggered when NPC receiving an event, sent by other NPC
-	ON_MOVE_FINISHED(true), // onMoveFinished action, triggered when NPC stops after moving
-	ON_NODE_ARRIVED(true), // onNodeArrived action, triggered when NPC, controlled by Walking Manager, arrives to next node
-	ON_SEE_CREATURE(true), // onSeeCreature action, triggered when NPC's known list include the character
-	ON_ROUTE_FINISHED(true), // onRouteFinished action, triggered when NPC, controlled by Walking Manager, arrives to last node
-	ON_NPC_HATE(true),
-	ON_SUMMON(true),
-	ON_CAN_SEE_ME(false);
-	
-	// control whether this event type is allowed for the same npc template in multiple quests
-	// or if the npc must be registered in at most one quest for the specified event
-	private boolean _allowMultipleRegistration;
-	
-	private QuestEventType(boolean allowMultipleRegistration)
-	{
-		_allowMultipleRegistration = allowMultipleRegistration;
-	}
-	
-	public boolean isMultipleRegistrationAllowed()
-	{
-		return _allowMultipleRegistration;
-	}
-}

+ 3 - 9
L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/WalkingManager.java

@@ -29,7 +29,6 @@ import org.w3c.dom.Node;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.engines.DocumentParser;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.instancemanager.tasks.StartMovingTask;
 import com.l2jserver.gameserver.model.L2NpcWalkerNode;
 import com.l2jserver.gameserver.model.L2WalkRoute;
@@ -38,8 +37,9 @@ import com.l2jserver.gameserver.model.WalkInfo;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
 import com.l2jserver.gameserver.model.actor.tasks.npc.walker.ArrivedTask;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveNodeArrived;
 import com.l2jserver.gameserver.model.holders.NpcRoutesHolder;
-import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.network.NpcStringId;
 import com.l2jserver.gameserver.network.clientpackets.Say2;
 import com.l2jserver.gameserver.network.serverpackets.NpcSay;
@@ -411,13 +411,7 @@ public final class WalkingManager extends DocumentParser
 		if (_activeRoutes.containsKey(npc.getObjectId()))
 		{
 			// Notify quest
-			if (npc.getTemplate().getEventQuests(QuestEventType.ON_NODE_ARRIVED) != null)
-			{
-				for (Quest quest : npc.getTemplate().getEventQuests(QuestEventType.ON_NODE_ARRIVED))
-				{
-					quest.notifyNodeArrived(npc);
-				}
-			}
+			EventDispatcher.getInstance().notifyEventAsync(new OnNpcMoveNodeArrived(npc), npc);
 			
 			final WalkInfo walk = _activeRoutes.get(npc.getObjectId());
 			

+ 18 - 187
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Clan.java

@@ -46,6 +46,11 @@ import com.l2jserver.gameserver.instancemanager.SiegeManager;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager.Territory;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanJoin;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanLeaderChange;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanLeft;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanLvlUp;
 import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
 import com.l2jserver.gameserver.model.interfaces.INamable;
 import com.l2jserver.gameserver.model.itemcontainer.ClanWarehouse;
@@ -71,13 +76,6 @@ import com.l2jserver.gameserver.network.serverpackets.PledgeSkillListAdd;
 import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 import com.l2jserver.gameserver.network.serverpackets.UserInfo;
-import com.l2jserver.gameserver.scripting.scriptengine.events.ClanCreationEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.events.ClanJoinEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.events.ClanLeaderChangeEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.events.ClanLeaveEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.events.ClanLevelUpEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.clan.ClanCreationListener;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.clan.ClanMembershipListener;
 import com.l2jserver.gameserver.util.Util;
 import com.l2jserver.util.EnumIntBitmask;
 
@@ -114,9 +112,6 @@ public class L2Clan implements IIdentifiable, INamable
 	/** Clan subunit type of Order of Knights B-2 */
 	public static final int SUBUNIT_KNIGHT4 = 2002;
 	
-	private static List<ClanCreationListener> clanCreationListeners = new FastList<ClanCreationListener>().shared();
-	private static List<ClanMembershipListener> clanMembershipListeners = new FastList<ClanMembershipListener>().shared();
-	
 	private String _name;
 	private int _clanId;
 	private L2ClanMember _leader;
@@ -185,7 +180,6 @@ public class L2Clan implements IIdentifiable, INamable
 		_clanId = clanId;
 		_name = clanName;
 		initializePrivs();
-		fireClanCreationListeners();
 	}
 	
 	/**
@@ -236,10 +230,8 @@ public class L2Clan implements IIdentifiable, INamable
 		final L2ClanMember exMember = getLeader();
 		final L2PcInstance exLeader = exMember.getPlayerInstance();
 		
-		if (!fireClanLeaderChangeListeners(newLeader, exLeader))
-		{
-			return;
-		}
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerClanLeaderChange(exMember, member, this));
 		
 		if (exLeader != null)
 		{
@@ -366,11 +358,6 @@ public class L2Clan implements IIdentifiable, INamable
 	 */
 	public void addClanMember(L2PcInstance player)
 	{
-		if (!fireClanJoinListeners(player))
-		{
-			return;
-		}
-		
 		final L2ClanMember member = new L2ClanMember(this, player);
 		// store in memory
 		addClanMember(member);
@@ -382,6 +369,9 @@ public class L2Clan implements IIdentifiable, INamable
 		addSkillEffects(player);
 		// notify CB server about the change
 		CommunityServerThread.getInstance().sendPacket(new WorldInfo(null, this, WorldInfo.TYPE_UPDATE_CLAN_DATA));
+		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerClanJoin(member, this));
 	}
 	
 	/**
@@ -432,11 +422,6 @@ public class L2Clan implements IIdentifiable, INamable
 	 */
 	public void removeClanMember(int objectId, long clanJoinExpiryTime)
 	{
-		if (!fireClanLeaveListeners(objectId))
-		{
-			return;
-		}
-		
 		final L2ClanMember exMember = _members.remove(objectId);
 		if (exMember == null)
 		{
@@ -542,6 +527,9 @@ public class L2Clan implements IIdentifiable, INamable
 		{
 			CommunityServerThread.getInstance().sendPacket(new WorldInfo(null, this, WorldInfo.TYPE_UPDATE_CLAN_DATA));
 		}
+		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerClanLeft(exMember, this));
 	}
 	
 	public L2ClanMember[] getMembers()
@@ -2597,11 +2585,6 @@ public class L2Clan implements IIdentifiable, INamable
 		
 		boolean increaseClanLevel = false;
 		
-		if (!fireClanLevelUpListeners())
-		{
-			return false;
-		}
-		
 		switch (getLevel())
 		{
 			case 0:
@@ -2821,6 +2804,9 @@ public class L2Clan implements IIdentifiable, INamable
 		player.sendPacket(il);
 		
 		changeLevel(getLevel() + 1);
+		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerClanLvlUp(player, this));
 		return true;
 	}
 	
@@ -2843,12 +2829,12 @@ public class L2Clan implements IIdentifiable, INamable
 		if (getLeader().isOnline())
 		{
 			L2PcInstance leader = getLeader().getPlayerInstance();
-			if (4 < level)
+			if (level > 4)
 			{
 				SiegeManager.getInstance().addSiegeSkills(leader);
 				leader.sendPacket(SystemMessageId.CLAN_CAN_ACCUMULATE_CLAN_REPUTATION_POINTS);
 			}
-			else if (5 > level)
+			else if (level < 5)
 			{
 				SiegeManager.getInstance().removeSiegeSkills(leader);
 			}
@@ -3127,159 +3113,4 @@ public class L2Clan implements IIdentifiable, INamable
 	{
 		_siegeDeaths.set(0);
 	}
-	
-	// Listeners
-	/**
-	 * Fires the clan creation listeners, if any.
-	 */
-	private void fireClanCreationListeners()
-	{
-		if (!clanCreationListeners.isEmpty())
-		{
-			ClanCreationEvent event = new ClanCreationEvent();
-			event.setClan(this);
-			for (ClanCreationListener listener : clanCreationListeners)
-			{
-				listener.onClanCreate(event);
-			}
-		}
-	}
-	
-	/**
-	 * Fires all the ClanMemberShipListener.onLeaderChange() methods, if any. Prevents the clan leader change if it returns false;
-	 * @param newLeader
-	 * @param exLeader
-	 * @return
-	 */
-	private boolean fireClanLeaderChangeListeners(L2PcInstance newLeader, L2PcInstance exLeader)
-	{
-		if (!clanMembershipListeners.isEmpty() && (newLeader != null) && (exLeader != null))
-		{
-			ClanLeaderChangeEvent event = new ClanLeaderChangeEvent();
-			event.setClan(this);
-			event.setNewLeader(newLeader);
-			event.setOldLeader(exLeader);
-			for (ClanMembershipListener listener : clanMembershipListeners)
-			{
-				if (!listener.onLeaderChange(event))
-				{
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fires all the ClanMembershipListener.onJoin() methods, if any<br>
-	 * Returns true/false -> allow the player to join or not
-	 * @param player
-	 * @return
-	 */
-	private boolean fireClanJoinListeners(L2PcInstance player)
-	{
-		if (!clanMembershipListeners.isEmpty() && (player != null))
-		{
-			ClanJoinEvent event = new ClanJoinEvent();
-			event.setClan(this);
-			event.setPlayer(player);
-			for (ClanMembershipListener listener : clanMembershipListeners)
-			{
-				if (!listener.onJoin(event))
-				{
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fires all the ClanMembershipListener.onLeave() methods, if any<br>
-	 * Returns true/false -> the player can leave the clan or not
-	 * @param objectId - the clan member's objectId
-	 * @return
-	 */
-	private boolean fireClanLeaveListeners(int objectId)
-	{
-		if (!clanMembershipListeners.isEmpty())
-		{
-			ClanLeaveEvent event = new ClanLeaveEvent();
-			event.setPlayerId(objectId);
-			event.setClan(this);
-			for (ClanMembershipListener listener : clanMembershipListeners)
-			{
-				if (!listener.onLeave(event))
-				{
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fires all the ClanCreationListener.onClanLevelUp() methods, if any<br>
-	 * Blocks the level up if it returns false
-	 * @return
-	 */
-	private boolean fireClanLevelUpListeners()
-	{
-		if (!clanCreationListeners.isEmpty())
-		{
-			ClanLevelUpEvent event = new ClanLevelUpEvent();
-			event.setClan(this);
-			event.setOldLevel(_level);
-			for (ClanCreationListener listener : clanCreationListeners)
-			{
-				if (!listener.onClanLevelUp(event))
-				{
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Adds a clan creation listener
-	 * @param listener
-	 */
-	public static void addClanCreationListener(ClanCreationListener listener)
-	{
-		if (!clanCreationListeners.contains(listener))
-		{
-			clanCreationListeners.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes a clan creation listener
-	 * @param listener
-	 */
-	public static void removeClanCreationListener(ClanCreationListener listener)
-	{
-		clanCreationListeners.remove(listener);
-	}
-	
-	/**
-	 * Adds a clan join listener (a player just joined the clan)
-	 * @param listener
-	 */
-	public static void addClanMembershipListener(ClanMembershipListener listener)
-	{
-		if (!clanMembershipListeners.contains(listener))
-		{
-			clanMembershipListeners.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes a clan join listener (a player left the clan)
-	 * @param listener
-	 */
-	public static void removeClanMembershipListener(ClanMembershipListener listener)
-	{
-		clanMembershipListeners.remove(listener);
-	}
 }

+ 2 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Object.java

@@ -36,6 +36,7 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.knownlist.ObjectKnownList;
 import com.l2jserver.gameserver.model.actor.poly.ObjectPoly;
 import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.ListenersContainer;
 import com.l2jserver.gameserver.model.interfaces.IDecayable;
 import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
 import com.l2jserver.gameserver.model.interfaces.ILocational;
@@ -54,7 +55,7 @@ import com.l2jserver.gameserver.util.Util;
 /**
  * Base class for all interactive objects.
  */
-public abstract class L2Object implements IIdentifiable, INamable, ISpawnable, IUniqueId, IDecayable, IPositionable
+public abstract class L2Object extends ListenersContainer implements IIdentifiable, INamable, ISpawnable, IUniqueId, IDecayable, IPositionable
 {
 	/** Name */
 	private String _name;

+ 3 - 9
L2J_Server_BETA/java/com/l2jserver/gameserver/model/WalkInfo.java

@@ -20,10 +20,10 @@ package com.l2jserver.gameserver.model;
 
 import java.util.concurrent.ScheduledFuture;
 
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.instancemanager.WalkingManager;
 import com.l2jserver.gameserver.model.actor.L2Npc;
-import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveRouteFinished;
 import com.l2jserver.util.Rnd;
 
 /**
@@ -96,13 +96,7 @@ public class WalkInfo
 			if (_currentNode == getRoute().getNodesCount()) // Last node arrived
 			{
 				// Notify quest
-				if (npc.getTemplate().getEventQuests(QuestEventType.ON_ROUTE_FINISHED) != null)
-				{
-					for (Quest quest : npc.getTemplate().getEventQuests(QuestEventType.ON_ROUTE_FINISHED))
-					{
-						quest.notifyRouteFinished(npc);
-					}
-				}
+				EventDispatcher.getInstance().notifyEventAsync(new OnNpcMoveRouteFinished(npc), npc);
 				npc.sendDebugMessage("Route: " + getRoute().getName() + ", last node arrived");
 				
 				if (!getRoute().repeatWalk())

+ 10 - 54
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Attackable.java

@@ -38,7 +38,6 @@ import com.l2jserver.gameserver.datatables.EventDroplist.DateDrop;
 import com.l2jserver.gameserver.datatables.ItemTable;
 import com.l2jserver.gameserver.datatables.ManorData;
 import com.l2jserver.gameserver.enums.InstanceType;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.instancemanager.CursedWeaponsManager;
 import com.l2jserver.gameserver.instancemanager.WalkingManager;
 import com.l2jserver.gameserver.model.AbsorberInfo;
@@ -47,7 +46,6 @@ import com.l2jserver.gameserver.model.DamageDoneInfo;
 import com.l2jserver.gameserver.model.L2CommandChannel;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.L2Party;
-import com.l2jserver.gameserver.model.actor.events.AttackableEvents;
 import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@@ -55,13 +53,15 @@ import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
 import com.l2jserver.gameserver.model.actor.knownlist.AttackableKnownList;
 import com.l2jserver.gameserver.model.actor.status.AttackableStatus;
 import com.l2jserver.gameserver.model.actor.tasks.attackable.CommandChannelTimer;
-import com.l2jserver.gameserver.model.actor.tasks.attackable.OnKillNotifyTask;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.model.drops.DropListScope;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableAggroRangeEnter;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableAttack;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableKill;
 import com.l2jserver.gameserver.model.holders.ItemHolder;
 import com.l2jserver.gameserver.model.items.L2Item;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
-import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.model.stats.Stats;
 import com.l2jserver.gameserver.network.SystemMessageId;
@@ -151,18 +151,6 @@ public class L2Attackable extends L2Npc
 		setStatus(new AttackableStatus(this));
 	}
 	
-	@Override
-	public void initCharEvents()
-	{
-		setCharEvents(new AttackableEvents(this));
-	}
-	
-	@Override
-	public AttackableEvents getEvents()
-	{
-		return (AttackableEvents) super.getEvents();
-	}
-	
 	@Override
 	protected L2CharacterAI initAI()
 	{
@@ -351,30 +339,10 @@ public class L2Attackable extends L2Npc
 			return false;
 		}
 		
-		// Notify the Quest Engine of the L2Attackable death if necessary
-		try
+		if ((killer != null) && killer.isPlayable())
 		{
-			L2PcInstance player = null;
-			
-			if (killer != null)
-			{
-				player = killer.getActingPlayer();
-			}
-			
-			if (player != null)
-			{
-				if (getTemplate().getEventQuests(QuestEventType.ON_KILL) != null)
-				{
-					for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_KILL))
-					{
-						ThreadPoolManager.getInstance().scheduleEffect(new OnKillNotifyTask(this, quest, player, (killer != null) && killer.isSummon()), _onKillDelay);
-					}
-				}
-			}
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.SEVERE, "", e);
+			// Delayed notification
+			EventDispatcher.getInstance().notifyEventAsyncDelayed(new OnAttackableKill(killer.getActingPlayer(), this, killer.isSummon()), this, _onKillDelay);
 		}
 		return true;
 	}
@@ -677,16 +645,10 @@ public class L2Attackable extends L2Npc
 					WalkingManager.getInstance().stopMoving(this, false, true);
 				}
 				
-				L2PcInstance player = attacker.getActingPlayer();
+				final L2PcInstance player = attacker.getActingPlayer();
 				if (player != null)
 				{
-					if (getTemplate().getEventQuests(QuestEventType.ON_ATTACK) != null)
-					{
-						for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_ATTACK))
-						{
-							quest.notifyAttack(this, player, damage, attacker.isSummon(), skill);
-						}
-					}
+					EventDispatcher.getInstance().notifyEventAsync(new OnAttackableAttack(player, this, damage, skill, attacker.isSummon()), this);
 				}
 				// for now hard code damage hate caused by an L2Attackable
 				else
@@ -734,13 +696,7 @@ public class L2Attackable extends L2Npc
 		
 		if ((targetPlayer != null) && (aggro == 0))
 		{
-			if (getTemplate().getEventQuests(QuestEventType.ON_AGGRO_RANGE_ENTER) != null)
-			{
-				for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_AGGRO_RANGE_ENTER))
-				{
-					quest.notifyAggroRangeEnter(this, targetPlayer, attacker.isSummon());
-				}
-			}
+			EventDispatcher.getInstance().notifyEventAsync(new OnAttackableAggroRangeEnter(this, targetPlayer, attacker.isSummon()), this);
 		}
 		else if ((targetPlayer == null) && (aggro == 0))
 		{

+ 68 - 36
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java

@@ -25,9 +25,11 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -50,7 +52,6 @@ import com.l2jserver.gameserver.datatables.ItemTable;
 import com.l2jserver.gameserver.datatables.SkillData;
 import com.l2jserver.gameserver.enums.CategoryType;
 import com.l2jserver.gameserver.enums.InstanceType;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.enums.ShotType;
 import com.l2jserver.gameserver.enums.Team;
 import com.l2jserver.gameserver.instancemanager.DimensionalRiftManager;
@@ -69,7 +70,6 @@ import com.l2jserver.gameserver.model.Location;
 import com.l2jserver.gameserver.model.PcCondOverride;
 import com.l2jserver.gameserver.model.TeleportWhereType;
 import com.l2jserver.gameserver.model.TimeStamp;
-import com.l2jserver.gameserver.model.actor.events.CharEvents;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2RiftInvaderInstance;
@@ -88,6 +88,16 @@ import com.l2jserver.gameserver.model.actor.transform.TransformTemplate;
 import com.l2jserver.gameserver.model.effects.EffectFlag;
 import com.l2jserver.gameserver.model.effects.L2EffectType;
 import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureAttack;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureDamage;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureKill;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureSkillUse;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureTeleported;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSkillSee;
+import com.l2jserver.gameserver.model.events.listeners.AbstractEventListener;
+import com.l2jserver.gameserver.model.events.returns.TerminateReturn;
 import com.l2jserver.gameserver.model.holders.InvulSkillHolder;
 import com.l2jserver.gameserver.model.holders.SkillHolder;
 import com.l2jserver.gameserver.model.holders.SkillUseHolder;
@@ -102,7 +112,6 @@ import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.type.WeaponType;
 import com.l2jserver.gameserver.model.options.OptionsSkillHolder;
 import com.l2jserver.gameserver.model.options.OptionsSkillType;
-import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.skills.AbnormalType;
 import com.l2jserver.gameserver.model.skills.AbnormalVisualEffect;
 import com.l2jserver.gameserver.model.skills.BuffInfo;
@@ -190,7 +199,6 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 	
 	private CharStat _stat;
 	private CharStatus _status;
-	private CharEvents _events;
 	private L2CharTemplate _template; // The link on the L2CharTemplate object containing generic and static properties of this L2Character type (ex : Max HP, Speed...)
 	private String _title;
 	
@@ -457,7 +465,6 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 		setInstanceType(InstanceType.L2Character);
 		initCharStat();
 		initCharStatus();
-		initCharEvents();
 		
 		// Set its template to the new L2Character
 		_template = template;
@@ -545,7 +552,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 			}
 			spawnMe(getX(), getY(), getZ());
 			setIsTeleporting(false);
-			getEvents().onTeleported();
+			EventDispatcher.getInstance().notifyEventAsync(new OnCreatureTeleported(this), this);
 		}
 		finally
 		{
@@ -824,11 +831,14 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 	 */
 	protected synchronized void doAttack(L2Character target)
 	{
-		if ((target == null) || isAttackingDisabled() || !getEvents().onAttack(target))
+		if ((target == null) || isAttackingDisabled())
 		{
 			return;
 		}
 		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnCreatureAttack(this, target), this);
+		
 		if (!isAlikeDead())
 		{
 			if ((isNpc() && target.isAlikeDead()) || !getKnownList().knowsObject(target))
@@ -1723,7 +1733,26 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 	
 	private void beginCast(Skill skill, boolean simultaneously, L2Character target, L2Object[] targets)
 	{
-		if ((target == null) || !getEvents().onMagic(skill, simultaneously, target, targets))
+		if (target == null)
+		{
+			if (simultaneously)
+			{
+				setIsCastingSimultaneouslyNow(false);
+			}
+			else
+			{
+				setIsCastingNow(false);
+			}
+			if (isPlayer())
+			{
+				sendPacket(ActionFailed.STATIC_PACKET);
+				getAI().setIntention(AI_INTENTION_ACTIVE);
+			}
+			return;
+		}
+		
+		final TerminateReturn term = EventDispatcher.getInstance().notifyEvent(new OnCreatureSkillUse(this, skill, simultaneously, target, targets), this, TerminateReturn.class);
+		if ((term != null) && term.terminate())
 		{
 			if (simultaneously)
 			{
@@ -2457,6 +2486,12 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 	 */
 	public boolean doDie(L2Character killer)
 	{
+		final TerminateReturn returnBack = EventDispatcher.getInstance().notifyEvent(new OnCreatureKill(killer, this), this, TerminateReturn.class);
+		if ((returnBack != null) && returnBack.terminate())
+		{
+			return false;
+		}
+		
 		// killing is only possible one time
 		synchronized (this)
 		{
@@ -2464,14 +2499,11 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 			{
 				return false;
 			}
+			
 			// now reset currentHp to zero
 			setCurrentHp(0);
 			setIsDead(true);
 		}
-		if (!getEvents().onDeath(killer))
-		{
-			return false;
-		}
 		
 		// Set target to null and cancel Attack or Cast
 		setTarget(null);
@@ -3095,21 +3127,6 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 		_status = value;
 	}
 	
-	public void initCharEvents()
-	{
-		_events = new CharEvents(this);
-	}
-	
-	public void setCharEvents(CharEvents events)
-	{
-		_events = events;
-	}
-	
-	public CharEvents getEvents()
-	{
-		return _events;
-	}
-	
 	public L2CharTemplate getTemplate()
 	{
 		return _template;
@@ -6160,14 +6177,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 				{
 					if ((spMob != null) && spMob.isNpc())
 					{
-						L2Npc npcMob = (L2Npc) spMob;
-						
-						if ((npcMob.isInsideRadius(player, 1000, true, true)) && (npcMob.getTemplate().getEventQuests(QuestEventType.ON_SKILL_SEE) != null))
+						final L2Npc npcMob = (L2Npc) spMob;
+						if ((npcMob.isInsideRadius(player, 1000, true, true)))
 						{
-							for (Quest quest : npcMob.getTemplate().getEventQuests(QuestEventType.ON_SKILL_SEE))
-							{
-								quest.notifySkillSee(npcMob, player, skill, targets, isSummon());
-							}
+							EventDispatcher.getInstance().notifyEventAsync(new OnNpcSkillSee(npcMob, player, skill, targets, isSummon()), npcMob);
 						}
 					}
 				}
@@ -6928,8 +6941,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 	 */
 	public void notifyDamageReceived(double damage, L2Character attacker, Skill skill, boolean critical, boolean damageOverTime)
 	{
-		getEvents().onDamageReceived(damage, attacker, skill, critical, damageOverTime);
-		attacker.getEvents().onDamageDealt(damage, this, skill, critical, damageOverTime);
+		EventDispatcher.getInstance().notifyEventAsync(new OnCreatureDamage(attacker, this, damage, skill, critical, damageOverTime), this, attacker);
 	}
 	
 	/**
@@ -7058,4 +7070,24 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 		}
 		return _invulAgainst;
 	}
+	
+	@Override
+	public Queue<AbstractEventListener> getListeners(EventType type)
+	{
+		final Queue<AbstractEventListener> objectListenres = super.getListeners(type);
+		final Queue<AbstractEventListener> templateListeners = getTemplate().getListeners(type);
+		if (objectListenres.isEmpty())
+		{
+			return templateListeners;
+		}
+		else if (templateListeners.isEmpty())
+		{
+			return objectListenres;
+		}
+		
+		final Queue<AbstractEventListener> both = new LinkedBlockingDeque<>(objectListenres.size() + templateListeners.size());
+		both.addAll(objectListenres);
+		both.addAll(templateListeners);
+		return both;
+	}
 }

+ 16 - 34
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Npc.java

@@ -38,7 +38,6 @@ import com.l2jserver.gameserver.enums.AIType;
 import com.l2jserver.gameserver.enums.InstanceType;
 import com.l2jserver.gameserver.enums.NpcRace;
 import com.l2jserver.gameserver.enums.PrivateStoreType;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.enums.ShotType;
 import com.l2jserver.gameserver.enums.Team;
 import com.l2jserver.gameserver.handler.BypassHandler;
@@ -70,12 +69,18 @@ import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.Fort;
 import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcCanBeSeen;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcEventReceived;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSkillFinished;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSpawn;
+import com.l2jserver.gameserver.model.events.returns.TerminateReturn;
 import com.l2jserver.gameserver.model.holders.ItemHolder;
 import com.l2jserver.gameserver.model.items.L2Item;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.olympiad.Olympiad;
-import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
 import com.l2jserver.gameserver.model.variables.NpcVariables;
@@ -1386,13 +1391,7 @@ public class L2Npc extends L2Character
 		_soulshotamount = getTemplate().getSoulShot();
 		_spiritshotamount = getTemplate().getSpiritShot();
 		
-		if (getTemplate().getEventQuests(QuestEventType.ON_SPAWN) != null)
-		{
-			for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_SPAWN))
-			{
-				quest.notifySpawn(this);
-			}
-		}
+		EventDispatcher.getInstance().notifyEventAsync(new OnNpcSpawn(this, isTeleporting()), this);
 		
 		if (!isTeleporting())
 		{
@@ -1655,24 +1654,9 @@ public class L2Npc extends L2Character
 	@Override
 	protected final void notifyQuestEventSkillFinished(Skill skill, L2Object target)
 	{
-		try
-		{
-			if (getTemplate().getEventQuests(QuestEventType.ON_SPELL_FINISHED) != null)
-			{
-				L2PcInstance player = null;
-				if (target != null)
-				{
-					player = target.getActingPlayer();
-				}
-				for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_SPELL_FINISHED))
-				{
-					quest.notifySpellFinished(this, player, skill);
-				}
-			}
-		}
-		catch (Exception e)
+		if ((target != null) && target.isPlayable())
 		{
-			_log.log(Level.SEVERE, "", e);
+			EventDispatcher.getInstance().notifyEventAsync(new OnNpcSkillFinished(this, target.getActingPlayer(), skill), this);
 		}
 	}
 	
@@ -1873,12 +1857,9 @@ public class L2Npc extends L2Character
 	{
 		for (L2Object obj : L2World.getInstance().getVisibleObjects(this, radius))
 		{
-			if (obj.isNpc() && (((L2Npc) obj).getTemplate().getEventQuests(QuestEventType.ON_EVENT_RECEIVED) != null))
+			if (obj.isNpc() && obj.hasListener(EventType.ON_NPC_EVENT_RECEIVED))
 			{
-				for (Quest quest : ((L2Npc) obj).getTemplate().getEventQuests(QuestEventType.ON_EVENT_RECEIVED))
-				{
-					quest.notifyEventReceived(eventName, this, (L2Npc) obj, reference);
-				}
+				EventDispatcher.getInstance().notifyEventAsync(new OnNpcEventReceived(eventName, this, (L2Npc) obj, reference), obj);
 			}
 		}
 	}
@@ -1977,11 +1958,12 @@ public class L2Npc extends L2Character
 	@Override
 	public boolean isVisibleFor(L2PcInstance player)
 	{
-		if (getTemplate().getEventQuests(QuestEventType.ON_CAN_SEE_ME) != null)
+		if (hasListener(EventType.ON_NPC_CAN_BE_SEEN))
 		{
-			for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_CAN_SEE_ME))
+			final TerminateReturn term = EventDispatcher.getInstance().notifyEvent(new OnNpcCanBeSeen(this, player), this, TerminateReturn.class);
+			if (term != null)
 			{
-				return quest.notifyOnCanSeeMe(this, player);
+				return term.terminate();
 			}
 		}
 		return super.isVisibleFor(player);

+ 5 - 14
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Playable.java

@@ -21,7 +21,6 @@ package com.l2jserver.gameserver.model.actor;
 import com.l2jserver.gameserver.ai.CtrlEvent;
 import com.l2jserver.gameserver.enums.InstanceType;
 import com.l2jserver.gameserver.instancemanager.InstanceManager;
-import com.l2jserver.gameserver.model.actor.events.PlayableEvents;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.knownlist.PlayableKnownList;
 import com.l2jserver.gameserver.model.actor.stat.PlayableStat;
@@ -30,6 +29,9 @@ import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
 import com.l2jserver.gameserver.model.effects.EffectFlag;
 import com.l2jserver.gameserver.model.effects.L2EffectType;
 import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureKill;
+import com.l2jserver.gameserver.model.events.returns.TerminateReturn;
 import com.l2jserver.gameserver.model.quest.QuestState;
 import com.l2jserver.gameserver.model.skills.Skill;
 
@@ -101,7 +103,8 @@ public abstract class L2Playable extends L2Character
 	@Override
 	public boolean doDie(L2Character killer)
 	{
-		if (!getEvents().onDeath(killer))
+		final TerminateReturn returnBack = EventDispatcher.getInstance().notifyEvent(new OnCreatureKill(killer, this), this, TerminateReturn.class);
+		if ((returnBack != null) && returnBack.terminate())
 		{
 			return false;
 		}
@@ -338,18 +341,6 @@ public abstract class L2Playable extends L2Character
 		return transferDmgTo;
 	}
 	
-	@Override
-	public void initCharEvents()
-	{
-		setCharEvents(new PlayableEvents(this));
-	}
-	
-	@Override
-	public PlayableEvents getEvents()
-	{
-		return (PlayableEvents) super.getEvents();
-	}
-	
 	public abstract int getKarma();
 	
 	public abstract byte getPvpFlag();

+ 4 - 23
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Summon.java

@@ -26,7 +26,6 @@ import com.l2jserver.gameserver.datatables.ExperienceTable;
 import com.l2jserver.gameserver.datatables.ItemTable;
 import com.l2jserver.gameserver.enums.InstanceType;
 import com.l2jserver.gameserver.enums.NpcRace;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.enums.ShotType;
 import com.l2jserver.gameserver.enums.Team;
 import com.l2jserver.gameserver.handler.IItemHandler;
@@ -36,7 +35,6 @@ import com.l2jserver.gameserver.model.AggroInfo;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.L2Party;
 import com.l2jserver.gameserver.model.L2WorldRegion;
-import com.l2jserver.gameserver.model.actor.events.SummonEvents;
 import com.l2jserver.gameserver.model.actor.instance.L2NpcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.knownlist.SummonKnownList;
@@ -44,13 +42,14 @@ import com.l2jserver.gameserver.model.actor.stat.SummonStat;
 import com.l2jserver.gameserver.model.actor.status.SummonStatus;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.model.effects.L2EffectType;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerSummonSpawn;
 import com.l2jserver.gameserver.model.itemcontainer.PetInventory;
 import com.l2jserver.gameserver.model.items.L2EtcItem;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.type.ActionType;
 import com.l2jserver.gameserver.model.olympiad.OlympiadGameManager;
-import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
 import com.l2jserver.gameserver.model.zone.ZoneId;
@@ -148,14 +147,8 @@ public abstract class L2Summon extends L2Playable
 		// if someone comes into range now, the animation shouldn't show any more
 		_restoreSummon = false;
 		
-		// Notify DP scripts.
-		if (getTemplate().getEventQuests(QuestEventType.ON_SUMMON) != null)
-		{
-			for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_SUMMON))
-			{
-				quest.onSummon(this);
-			}
-		}
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerSummonSpawn(this), this);
 	}
 	
 	@Override
@@ -194,18 +187,6 @@ public abstract class L2Summon extends L2Playable
 		setStatus(new SummonStatus(this));
 	}
 	
-	@Override
-	public void initCharEvents()
-	{
-		setCharEvents(new SummonEvents(this));
-	}
-	
-	@Override
-	public SummonEvents getEvents()
-	{
-		return (SummonEvents) super.getEvents();
-	}
-	
 	@Override
 	protected L2CharacterAI initAI()
 	{

+ 0 - 162
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/AbstractCharEvents.java

@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import com.l2jserver.gameserver.model.actor.events.listeners.IEventListener;
-
-/**
- * @author UnAfraid
- */
-public abstract class AbstractCharEvents
-{
-	private static volatile List<IEventListener> _staticListeners = null;
-	private volatile List<IEventListener> _listeners = null;
-	
-	public static void registerStaticListener(IEventListener listener)
-	{
-		if (_staticListeners == null)
-		{
-			synchronized (AbstractCharEvents.class)
-			{
-				if (_staticListeners == null)
-				{
-					_staticListeners = new CopyOnWriteArrayList<>();
-				}
-			}
-		}
-		
-		_staticListeners.add(listener);
-	}
-	
-	public final void registerListener(IEventListener listener)
-	{
-		if (_listeners == null)
-		{
-			synchronized (this)
-			{
-				if (_listeners == null)
-				{
-					_listeners = new CopyOnWriteArrayList<>();
-				}
-			}
-		}
-		
-		_listeners.add(listener);
-	}
-	
-	public static void unregisterStaticListener(IEventListener listener)
-	{
-		if (_staticListeners == null)
-		{
-			return;
-		}
-		
-		if (_staticListeners.contains(listener))
-		{
-			_staticListeners.remove(listener);
-		}
-		
-		if (_staticListeners.isEmpty())
-		{
-			synchronized (AbstractCharEvents.class)
-			{
-				if (_staticListeners.isEmpty())
-				{
-					_staticListeners = null;
-				}
-			}
-		}
-	}
-	
-	public final void unregisterListener(IEventListener listener)
-	{
-		if (_listeners == null)
-		{
-			return;
-		}
-		
-		if (_listeners.contains(listener))
-		{
-			_listeners.remove(listener);
-		}
-		
-		if (_listeners.isEmpty())
-		{
-			synchronized (this)
-			{
-				if (_listeners.isEmpty())
-				{
-					_listeners = null;
-				}
-			}
-		}
-	}
-	
-	protected static boolean hasStaticEventListeners()
-	{
-		return _staticListeners != null;
-	}
-	
-	protected final boolean hasEventListeners()
-	{
-		return _listeners != null;
-	}
-	
-	protected final boolean hasListeners()
-	{
-		return (_listeners != null) || (_staticListeners != null);
-	}
-	
-	protected final <T> List<T> getEventListeners(Class<T> clazz)
-	{
-		if (!hasListeners())
-		{
-			return Collections.<T> emptyList();
-		}
-		
-		final List<T> listeners = new ArrayList<>();
-		if (hasEventListeners())
-		{
-			for (IEventListener listener : _listeners)
-			{
-				if (clazz.isInstance(listener))
-				{
-					listeners.add(clazz.cast(listener));
-				}
-			}
-		}
-		
-		if (hasStaticEventListeners())
-		{
-			for (IEventListener listener : _staticListeners)
-			{
-				if (clazz.isInstance(listener))
-				{
-					listeners.add(clazz.cast(listener));
-				}
-			}
-		}
-		return listeners;
-	}
-}

+ 0 - 275
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/CharEvents.java

@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.l2jserver.gameserver.model.L2Object;
-import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.actor.events.annotations.PlayerOnly;
-import com.l2jserver.gameserver.model.actor.events.annotations.SkillId;
-import com.l2jserver.gameserver.model.actor.events.annotations.SkillLevel;
-import com.l2jserver.gameserver.model.actor.events.listeners.IAttackEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.IDamageDealtEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.IDamageReceivedEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.IDeathEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.ISkillUseEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.ITeleportedEventListener;
-import com.l2jserver.gameserver.model.skills.Skill;
-import com.l2jserver.gameserver.util.Util;
-
-/**
- * @author UnAfraid
- */
-public class CharEvents extends AbstractCharEvents
-{
-	protected static final Logger _log = Logger.getLogger(CharEvents.class.getName());
-	
-	private final L2Character _activeChar;
-	
-	public CharEvents(L2Character activeChar)
-	{
-		_activeChar = activeChar;
-	}
-	
-	/**
-	 * Fired whenever current char attacks someone.<br>
-	 * Supported annotations:<br>
-	 * <ul>
-	 * <li>{@link PlayerOnly}</li>
-	 * </ul>
-	 * @param target
-	 * @return {@code true} if current attack is possible, {@code false} otherwise.
-	 */
-	public boolean onAttack(L2Character target)
-	{
-		if (hasListeners())
-		{
-			for (IAttackEventListener listener : getEventListeners(IAttackEventListener.class))
-			{
-				try
-				{
-					if (listener.getClass().isAnnotationPresent(PlayerOnly.class) && !target.isPlayer())
-					{
-						continue;
-					}
-					
-					if (!listener.onAttack(getActingPlayer(), target))
-					{
-						return false;
-					}
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fired whenever current char cast a magic.<br>
-	 * Supported annotations:<br>
-	 * <ul>
-	 * <li>{@link PlayerOnly}</li>
-	 * <li>{@link SkillId}</li>
-	 * <li>{@link SkillLevel}</li>
-	 * </ul>
-	 * @param skill
-	 * @param simultaneously
-	 * @param target
-	 * @param targets
-	 * @return {@code true} if cast can be made, {@code false} otherwise.
-	 */
-	public boolean onMagic(Skill skill, boolean simultaneously, L2Character target, L2Object[] targets)
-	{
-		if (hasListeners())
-		{
-			for (ISkillUseEventListener listener : getEventListeners(ISkillUseEventListener.class))
-			{
-				try
-				{
-					if (listener.getClass().isAnnotationPresent(PlayerOnly.class) && !target.isPlayer())
-					{
-						continue;
-					}
-					
-					final SkillId skillIdA = listener.getClass().getAnnotation(SkillId.class);
-					if ((skillIdA != null) && (!Util.contains(skillIdA.value(), skill.getId())))
-					{
-						continue;
-					}
-					
-					final SkillLevel skillLevelA = listener.getClass().getAnnotation(SkillLevel.class);
-					if ((skillLevelA != null) && (!Util.contains(skillLevelA.value(), skill.getLevel())))
-					{
-						continue;
-					}
-					
-					if (!listener.onSkillUse(getActingPlayer(), skill, simultaneously, target, targets))
-					{
-						return false;
-					}
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fired whenever current char dies.<br>
-	 * Supported annotations:<br>
-	 * <ul>
-	 * <li>{@link PlayerOnly}</li>
-	 * </ul>
-	 * @param killer
-	 * @return {@code true} if current char can die, {@code false} otherwise.
-	 */
-	public boolean onDeath(L2Character killer)
-	{
-		if (hasListeners())
-		{
-			for (IDeathEventListener listener : getEventListeners(IDeathEventListener.class))
-			{
-				try
-				{
-					if (listener.getClass().isAnnotationPresent(PlayerOnly.class) && !killer.isPlayer())
-					{
-						continue;
-					}
-					
-					if (!listener.onDeath(killer, getActingPlayer()))
-					{
-						return false;
-					}
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fired whenever current char deal damage.<br>
-	 * Supported annotations:<br>
-	 * <ul>
-	 * <li>{@link PlayerOnly}</li>
-	 * </ul>
-	 * @param damage
-	 * @param target
-	 * @param skill
-	 * @param crit
-	 * @param damageOverTime
-	 */
-	public void onDamageDealt(double damage, L2Character target, Skill skill, boolean crit, boolean damageOverTime)
-	{
-		if (hasListeners())
-		{
-			for (IDamageDealtEventListener listener : getEventListeners(IDamageDealtEventListener.class))
-			{
-				try
-				{
-					if (listener.getClass().isAnnotationPresent(PlayerOnly.class) && !target.isPlayer())
-					{
-						continue;
-					}
-					
-					listener.onDamageDealtEvent(getActingPlayer(), target, damage, skill, crit, damageOverTime);
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-	}
-	
-	/**
-	 * Fired whenever current char receive damage.<br>
-	 * Supported annotations:<br>
-	 * <ul>
-	 * <li>{@link PlayerOnly}</li>
-	 * </ul>
-	 * @param damage
-	 * @param attacker
-	 * @param skill
-	 * @param crit
-	 * @param damageOverTime
-	 */
-	public void onDamageReceived(double damage, L2Character attacker, Skill skill, boolean crit, boolean damageOverTime)
-	{
-		if (hasListeners())
-		{
-			for (IDamageReceivedEventListener listener : getEventListeners(IDamageReceivedEventListener.class))
-			{
-				try
-				{
-					if (listener.getClass().isAnnotationPresent(PlayerOnly.class) && !attacker.isPlayer())
-					{
-						continue;
-					}
-					
-					listener.onDamageReceivedEvent(attacker, getActingPlayer(), damage, skill, crit, damageOverTime);
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-	}
-	
-	/**
-	 * Fired whenever current char is teleported.
-	 */
-	public void onTeleported()
-	{
-		if (hasListeners())
-		{
-			for (ITeleportedEventListener listener : getEventListeners(ITeleportedEventListener.class))
-			{
-				try
-				{
-					listener.onTeleported(getActingPlayer());
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-	}
-	
-	/**
-	 * @return current char.
-	 */
-	public L2Character getActingPlayer()
-	{
-		return _activeChar;
-	}
-}

+ 0 - 115
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/PlayableEvents.java

@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events;
-
-import java.util.logging.Level;
-
-import com.l2jserver.gameserver.model.actor.L2Playable;
-import com.l2jserver.gameserver.model.actor.events.annotations.PlayerOnly;
-import com.l2jserver.gameserver.model.actor.events.listeners.IExperienceReceivedEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.ILevelChangeEventListener;
-
-/**
- * @author UnAfraid
- */
-public class PlayableEvents extends CharEvents
-{
-	public PlayableEvents(L2Playable activeChar)
-	{
-		super(activeChar);
-	}
-	
-	/**
-	 * Fired whenever current char receives any exp.<br>
-	 * Supported annotations:<br>
-	 * <ul>
-	 * <li>{@link PlayerOnly}</li>
-	 * </ul>
-	 * @param exp
-	 * @return {@code true} if experience can be received, {@code false} otherwise.
-	 */
-	public boolean onExperienceReceived(long exp)
-	{
-		if (hasListeners())
-		{
-			for (IExperienceReceivedEventListener listener : getEventListeners(IExperienceReceivedEventListener.class))
-			{
-				try
-				{
-					if (listener.getClass().isAnnotationPresent(PlayerOnly.class) && !getActingPlayer().isPlayer())
-					{
-						continue;
-					}
-					
-					if (!listener.onExperienceReceived(getActingPlayer(), exp))
-					{
-						return false;
-					}
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fired whenever current playable's level has change.<br>
-	 * Supported annotations:<br>
-	 * <ul>
-	 * <li>{@link PlayerOnly}</li>
-	 * </ul>
-	 * @param levels
-	 * @return {@code true} if level change is possible, {@code false} otherwise.
-	 */
-	public boolean onLevelChange(byte levels)
-	{
-		if (hasListeners())
-		{
-			for (ILevelChangeEventListener listener : getEventListeners(ILevelChangeEventListener.class))
-			{
-				try
-				{
-					if (listener.getClass().isAnnotationPresent(PlayerOnly.class) && !getActingPlayer().isPlayer())
-					{
-						continue;
-					}
-					
-					if (!listener.onLevelChange(getActingPlayer(), levels))
-					{
-						return false;
-					}
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-		return true;
-	}
-	
-	@Override
-	public L2Playable getActingPlayer()
-	{
-		return (L2Playable) super.getActingPlayer();
-	}
-}

+ 0 - 277
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/PlayerEvents.java

@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events;
-
-import java.util.logging.Level;
-
-import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
-import com.l2jserver.gameserver.model.actor.events.annotations.Message;
-import com.l2jserver.gameserver.model.actor.events.annotations.UseAntiFeed;
-import com.l2jserver.gameserver.model.actor.events.listeners.IDlgAnswerEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.IFamePointsChangeEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.IKarmaChangeEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.IPKPointsChangeEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.IPlayerLoginEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.IPlayerLogoutEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.IPvPKillEventListener;
-import com.l2jserver.gameserver.model.actor.events.listeners.IPvPPointsEventChange;
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.util.Util;
-
-/**
- * @author UnAfraid
- */
-public class PlayerEvents extends PlayableEvents
-{
-	public PlayerEvents(L2PcInstance activeChar)
-	{
-		super(activeChar);
-	}
-	
-	@Override
-	public L2PcInstance getActingPlayer()
-	{
-		return (L2PcInstance) super.getActingPlayer();
-	}
-	
-	/**
-	 * Fired whenever player's karma points has change.
-	 * @param oldKarma
-	 * @param newKarma
-	 * @return {@code true} if karma change is possible, {@code false} otherwise.
-	 */
-	public boolean onKarmaChange(int oldKarma, int newKarma)
-	{
-		if (hasListeners())
-		{
-			for (IKarmaChangeEventListener listener : getEventListeners(IKarmaChangeEventListener.class))
-			{
-				try
-				{
-					if (!listener.onKarmaChange(getActingPlayer(), oldKarma, newKarma))
-					{
-						return false;
-					}
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fired whenever player's pk points has change.
-	 * @param oldPKPoints
-	 * @param newPKPoints
-	 * @return {@code true} if pk points change is possible, {@code false} otherwise.
-	 */
-	public boolean onPKChange(int oldPKPoints, int newPKPoints)
-	{
-		if (hasListeners())
-		{
-			for (IPKPointsChangeEventListener listener : getEventListeners(IPKPointsChangeEventListener.class))
-			{
-				try
-				{
-					if (!listener.onPKPointsChange(getActingPlayer(), oldPKPoints, newPKPoints))
-					{
-						return false;
-					}
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fired whenever player's pvp points has change.
-	 * @param oldPvPPoints
-	 * @param newPvPPoints
-	 * @return {@code true} if pvp points change is possible, {@code false} otherwise.
-	 */
-	public boolean onPvPChange(int oldPvPPoints, int newPvPPoints)
-	{
-		if (hasListeners())
-		{
-			for (IPvPPointsEventChange listener : getEventListeners(IPvPPointsEventChange.class))
-			{
-				try
-				{
-					if (!listener.onPvPPointsChange(getActingPlayer(), oldPvPPoints, newPvPPoints))
-					{
-						return false;
-					}
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fired whenever player's fame points has change.
-	 * @param oldFamePoints
-	 * @param newFamePoints
-	 * @return {@code true} if fame points change is possible, {@code false} otherwise.
-	 */
-	public boolean onFameChange(int oldFamePoints, int newFamePoints)
-	{
-		if (hasListeners())
-		{
-			for (IFamePointsChangeEventListener listener : getEventListeners(IFamePointsChangeEventListener.class))
-			{
-				try
-				{
-					if (!listener.onFamePointsChange(getActingPlayer(), oldFamePoints, newFamePoints))
-					{
-						return false;
-					}
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fired whenever player answer on a dialog yes/no.<br>
-	 * Supported annotations:<br>
-	 * <ul>
-	 * <li>{@link Message}</li>
-	 * </ul>
-	 * @param messageId
-	 * @param answer
-	 * @param requesterId
-	 * @return {@code true} if current answer is possible, {@code false} otherwise.
-	 */
-	public boolean onDlgAnswer(int messageId, int answer, int requesterId)
-	{
-		if (hasListeners())
-		{
-			for (IDlgAnswerEventListener listener : getEventListeners(IDlgAnswerEventListener.class))
-			{
-				try
-				{
-					final Message messageA = listener.getClass().getAnnotation(Message.class);
-					if ((messageA != null) && !Util.contains(messageA.value(), messageId))
-					{
-						continue;
-					}
-					
-					if (!listener.onDlgAnswer(getActingPlayer(), messageId, answer, requesterId))
-					{
-						return false;
-					}
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fired whenever current player login.
-	 */
-	public void onPlayerLogin()
-	{
-		if (hasListeners())
-		{
-			for (IPlayerLoginEventListener listener : getEventListeners(IPlayerLoginEventListener.class))
-			{
-				try
-				{
-					listener.onPlayerLogin(getActingPlayer());
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-	}
-	
-	/**
-	 * Fired whenever current player is logged out.
-	 */
-	public void onPlayerLogout()
-	{
-		if (hasListeners())
-		{
-			for (IPlayerLogoutEventListener listener : getEventListeners(IPlayerLogoutEventListener.class))
-			{
-				try
-				{
-					listener.onPlayerLogout(getActingPlayer());
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-	}
-	
-	/**
-	 * Fired whenever player kills another player.<br>
-	 * Supported annotations:<br>
-	 * <ul>
-	 * <li>{@link UseAntiFeed}</li>
-	 * </ul>
-	 * @param target
-	 */
-	public void onPvPKill(L2PcInstance target)
-	{
-		if (hasListeners())
-		{
-			for (IPvPKillEventListener listener : getEventListeners(IPvPKillEventListener.class))
-			{
-				try
-				{
-					final UseAntiFeed useAntiFeed = listener.getClass().getAnnotation(UseAntiFeed.class);
-					if ((useAntiFeed != null) && !AntiFeedManager.getInstance().check(getActingPlayer(), target))
-					{
-						continue;
-					}
-					
-					listener.onPvPKill(getActingPlayer(), target);
-				}
-				catch (Exception e)
-				{
-					_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception caught: ", e);
-				}
-			}
-		}
-	}
-}

+ 0 - 30
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IDamageDealtEventListener.java

@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events.listeners;
-
-import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.skills.Skill;
-
-/**
- * @author UnAfraid
- */
-public interface IDamageDealtEventListener extends IEventListener
-{
-	public void onDamageDealtEvent(L2Character attacker, L2Character target, double damage, Skill skill, boolean crit, boolean damageOverTime);
-}

+ 0 - 29
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IDeathEventListener.java

@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events.listeners;
-
-import com.l2jserver.gameserver.model.actor.L2Character;
-
-/**
- * @author UnAfraid
- */
-public interface IDeathEventListener extends IEventListener
-{
-	public boolean onDeath(L2Character attacker, L2Character target);
-}

+ 0 - 29
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IExperienceReceivedEventListener.java

@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events.listeners;
-
-import com.l2jserver.gameserver.model.actor.L2Playable;
-
-/**
- * @author UnAfraid
- */
-public interface IExperienceReceivedEventListener extends IEventListener
-{
-	public boolean onExperienceReceived(L2Playable playable, long exp);
-}

+ 0 - 29
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IPlayerLoginEventListener.java

@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events.listeners;
-
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-
-/**
- * @author UnAfraid
- */
-public interface IPlayerLoginEventListener extends IEventListener
-{
-	public void onPlayerLogin(L2PcInstance player);
-}

+ 0 - 29
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IPlayerLogoutEventListener.java

@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events.listeners;
-
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-
-/**
- * @author UnAfraid
- */
-public interface IPlayerLogoutEventListener extends IEventListener
-{
-	public void onPlayerLogout(L2PcInstance player);
-}

+ 0 - 29
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IPvPKillEventListener.java

@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events.listeners;
-
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-
-/**
- * @author UnAfraid
- */
-public interface IPvPKillEventListener extends IEventListener
-{
-	public void onPvPKill(L2PcInstance attacker, L2PcInstance target);
-}

+ 0 - 29
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IPvPPointsEventChange.java

@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events.listeners;
-
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-
-/**
- * @author UnAfraid
- */
-public interface IPvPPointsEventChange extends IEventListener
-{
-	public boolean onPvPPointsChange(L2PcInstance player, int oldPvPPoints, int newPvPPoints);
-}

+ 0 - 31
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/ISkillUseEventListener.java

@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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 Server 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 com.l2jserver.gameserver.model.actor.events.listeners;
-
-import com.l2jserver.gameserver.model.L2Object;
-import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.skills.Skill;
-
-/**
- * @author UnAfraid
- */
-public interface ISkillUseEventListener extends IEventListener
-{
-	public boolean onSkillUse(L2Character caster, Skill skill, boolean simultaneously, L2Character target, L2Object[] targets);
-}

+ 6 - 9
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2GuardInstance.java

@@ -18,21 +18,21 @@
  */
 package com.l2jserver.gameserver.model.actor.instance;
 
-import java.util.List;
 import java.util.logging.Logger;
 
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.ai.L2AttackableAI;
 import com.l2jserver.gameserver.enums.InstanceType;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.L2WorldRegion;
 import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.knownlist.GuardKnownList;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
-import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcFirstTalk;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
 import com.l2jserver.gameserver.network.serverpackets.SocialAction;
 import com.l2jserver.util.Rnd;
@@ -188,17 +188,14 @@ public class L2GuardInstance extends L2Attackable
 					player.setLastFolkNPC(this);
 					
 					// Open a chat window on client with the text of the L2GuardInstance
-					List<Quest> qlsa = getTemplate().getEventQuests(QuestEventType.QUEST_START);
-					List<Quest> qlst = getTemplate().getEventQuests(QuestEventType.ON_FIRST_TALK);
-					
-					if ((qlsa != null) && !qlsa.isEmpty())
+					if (hasListener(EventType.ON_NPC_QUEST_START))
 					{
 						player.setLastQuestNpcObject(getObjectId());
 					}
 					
-					if ((qlst != null) && (qlst.size() == 1))
+					if (hasListener(EventType.ON_NPC_FIRST_TALK))
 					{
-						qlst.get(0).notifyFirstTalk(this, player);
+						EventDispatcher.getInstance().notifyEventAsync(new OnNpcFirstTalk(this, player), this);
 					}
 					else
 					{

+ 72 - 400
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -93,7 +93,6 @@ import com.l2jserver.gameserver.enums.PartyDistributionType;
 import com.l2jserver.gameserver.enums.PcRace;
 import com.l2jserver.gameserver.enums.PlayerAction;
 import com.l2jserver.gameserver.enums.PrivateStoreType;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.enums.Sex;
 import com.l2jserver.gameserver.enums.ShortcutType;
 import com.l2jserver.gameserver.enums.ShotType;
@@ -163,7 +162,6 @@ import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.L2Summon;
 import com.l2jserver.gameserver.model.actor.L2Vehicle;
 import com.l2jserver.gameserver.model.actor.appearance.PcAppearance;
-import com.l2jserver.gameserver.model.actor.events.PlayerEvents;
 import com.l2jserver.gameserver.model.actor.knownlist.PcKnownList;
 import com.l2jserver.gameserver.model.actor.stat.PcStat;
 import com.l2jserver.gameserver.model.actor.status.PcStatus;
@@ -185,6 +183,7 @@ import com.l2jserver.gameserver.model.actor.tasks.player.TeleportWatchdogTask;
 import com.l2jserver.gameserver.model.actor.tasks.player.VitalityTask;
 import com.l2jserver.gameserver.model.actor.tasks.player.WarnUserTakeBreakTask;
 import com.l2jserver.gameserver.model.actor.tasks.player.WaterTask;
+import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.model.actor.templates.L2PcTemplate;
 import com.l2jserver.gameserver.model.actor.transform.Transform;
 import com.l2jserver.gameserver.model.base.ClassId;
@@ -201,11 +200,26 @@ import com.l2jserver.gameserver.model.entity.Instance;
 import com.l2jserver.gameserver.model.entity.L2Event;
 import com.l2jserver.gameserver.model.entity.Siege;
 import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerEquipItem;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerFameChanged;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerHennaRemove;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerKarmaChanged;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLogin;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLogout;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerPKChanged;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerProfessionChange;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerPvPChanged;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerPvPKill;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerTransform;
+import com.l2jserver.gameserver.model.events.listeners.AbstractEventListener;
 import com.l2jserver.gameserver.model.fishing.L2Fish;
 import com.l2jserver.gameserver.model.fishing.L2Fishing;
 import com.l2jserver.gameserver.model.holders.ItemHolder;
 import com.l2jserver.gameserver.model.holders.PlayerEventHolder;
 import com.l2jserver.gameserver.model.holders.SkillUseHolder;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
 import com.l2jserver.gameserver.model.interfaces.ILocational;
 import com.l2jserver.gameserver.model.itemcontainer.Inventory;
 import com.l2jserver.gameserver.model.itemcontainer.ItemContainer;
@@ -316,15 +330,6 @@ import com.l2jserver.gameserver.network.serverpackets.TradeOtherDone;
 import com.l2jserver.gameserver.network.serverpackets.TradeStart;
 import com.l2jserver.gameserver.network.serverpackets.UserInfo;
 import com.l2jserver.gameserver.network.serverpackets.ValidateLocation;
-import com.l2jserver.gameserver.scripting.scriptengine.events.EquipmentEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.events.HennaEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.events.ProfessionChangeEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.events.TransformEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.EquipmentListener;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.EventListener;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.HennaListener;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.ProfessionChangeListener;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.TransformListener;
 import com.l2jserver.gameserver.taskmanager.AttackStanceTaskManager;
 import com.l2jserver.gameserver.util.Broadcast;
 import com.l2jserver.gameserver.util.FloodProtectors;
@@ -389,14 +394,7 @@ public final class L2PcInstance extends L2Playable
 	
 	public static final int REQUEST_TIMEOUT = 15;
 	
-	private static final List<HennaListener> HENNA_LISTENERS = new FastList<HennaListener>().shared();
-	private static final List<EquipmentListener> GLOBAL_EQUIPMENT_LISTENERS = new FastList<EquipmentListener>().shared();
-	private static final List<ProfessionChangeListener> GLOBAL_PROFESSION_CHANGE_LISTENERS = new FastList<ProfessionChangeListener>().shared();
-	
-	private final List<EquipmentListener> _equipmentListeners = new FastList<EquipmentListener>().shared();
-	private final List<TransformListener> _transformListeners = new FastList<TransformListener>().shared();
-	private final List<ProfessionChangeListener> _professionChangeListeners = new FastList<ProfessionChangeListener>().shared();
-	private final List<EventListener> _eventListeners = new FastList<EventListener>().shared();
+	private final List<IEventListener> _eventListeners = new FastList<IEventListener>().shared();
 	
 	public class AIAccessor extends L2Character.AIAccessor
 	{
@@ -1162,18 +1160,6 @@ public final class L2PcInstance extends L2Playable
 		setStatus(new PcStatus(this));
 	}
 	
-	@Override
-	public void initCharEvents()
-	{
-		setCharEvents(new PlayerEvents(this));
-	}
-	
-	@Override
-	public PlayerEvents getEvents()
-	{
-		return (PlayerEvents) super.getEvents();
-	}
-	
 	public final PcAppearance getAppearance()
 	{
 		return _appearance;
@@ -1510,104 +1496,41 @@ public final class L2PcInstance extends L2Playable
 	}
 	
 	/**
-	 * @param npc
-	 * @return a table containing all QuestState to modify after a L2Attackable killing.
+	 * @param npcId The Identifier of the NPC
+	 * @return a table containing all QuestState from the table _quests in which the L2PcInstance must talk to the NPC.
 	 */
-	public QuestState[] getQuestsForAttacks(L2Npc npc)
+	public QuestState[] getQuestsForTalk(int npcId)
 	{
 		// Create a QuestState table that will contain all QuestState to modify
 		QuestState[] states = null;
 		
-		// Go through the QuestState of the L2PcInstance quests
-		for (Quest quest : npc.getTemplate().getEventQuests(QuestEventType.ON_ATTACK))
+		final L2NpcTemplate template = NpcData.getInstance().getTemplate(npcId);
+		if (template == null)
 		{
-			// Check if the Identifier of the L2Attackable attack is needed for the current quest
-			if (getQuestState(quest.getName()) != null)
-			{
-				// Copy the current L2PcInstance QuestState in the QuestState table
-				if (states == null)
-				{
-					states = new QuestState[]
-					{
-						getQuestState(quest.getName())
-					};
-				}
-				else
-				{
-					states = addToQuestStateArray(states, getQuestState(quest.getName()));
-				}
-			}
+			_log.log(Level.WARNING, getClass().getSimpleName() + ": " + getName() + " requested quests for talk on non existing npc " + npcId);
+			return states;
 		}
 		
-		// Return a table containing all QuestState to modify
-		return states;
-	}
-	
-	/**
-	 * @param npc
-	 * @return a table containing all QuestState to modify after a L2Attackable killing.
-	 */
-	public QuestState[] getQuestsForKills(L2Npc npc)
-	{
-		// Create a QuestState table that will contain all QuestState to modify
-		QuestState[] states = null;
-		
 		// Go through the QuestState of the L2PcInstance quests
-		for (Quest quest : npc.getTemplate().getEventQuests(QuestEventType.ON_KILL))
+		for (AbstractEventListener listener : template.getListeners(EventType.ON_NPC_TALK))
 		{
-			// Check if the Identifier of the L2Attackable killed is needed for the current quest
-			if (getQuestState(quest.getName()) != null)
+			if (listener.getOwner() instanceof Quest)
 			{
+				final Quest quest = (Quest) listener.getOwner();
+				
 				// Copy the current L2PcInstance QuestState in the QuestState table
-				if (states == null)
+				if (getQuestState(quest.getName()) != null)
 				{
-					states = new QuestState[]
+					if (states == null)
 					{
-						getQuestState(quest.getName())
-					};
-				}
-				else
-				{
-					states = addToQuestStateArray(states, getQuestState(quest.getName()));
-				}
-			}
-		}
-		
-		// Return a table containing all QuestState to modify
-		return states;
-	}
-	
-	/**
-	 * @param npcId The Identifier of the NPC
-	 * @return a table containing all QuestState from the table _quests in which the L2PcInstance must talk to the NPC.
-	 */
-	public QuestState[] getQuestsForTalk(int npcId)
-	{
-		// Create a QuestState table that will contain all QuestState to modify
-		QuestState[] states = null;
-		
-		// Go through the QuestState of the L2PcInstance quests
-		List<Quest> quests = NpcData.getInstance().getTemplate(npcId).getEventQuests(QuestEventType.ON_TALK);
-		if (quests != null)
-		{
-			for (Quest quest : quests)
-			{
-				if (quest != null)
-				{
-					// Copy the current L2PcInstance QuestState in the QuestState table
-					if (getQuestState(quest.getName()) != null)
-					{
-						if (states == null)
-						{
-							states = new QuestState[]
-							{
-								getQuestState(quest.getName())
-							};
-						}
-						else
+						states = new QuestState[]
 						{
-							states = addToQuestStateArray(states, getQuestState(quest.getName()));
-						}
+							getQuestState(quest.getName())
+						};
+					}
+					else
+					{
+						states = addToQuestStateArray(states, getQuestState(quest.getName()));
 					}
 				}
 			}
@@ -2043,11 +1966,7 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public void setPkKills(int pkKills)
 	{
-		if (!getEvents().onPKChange(_pkKills, pkKills))
-		{
-			return;
-		}
-		
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerPKChanged(this, _pkKills, pkKills), this);
 		_pkKills = pkKills;
 	}
 	
@@ -2159,10 +2078,8 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public void setKarma(int karma)
 	{
-		if (!getEvents().onKarmaChange(_karma, karma))
-		{
-			return;
-		}
+		// Notify to scripts.
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerKarmaChanged(this, getKarma(), karma), this);
 		
 		if (karma < 0)
 		{
@@ -2361,10 +2278,6 @@ public final class L2PcInstance extends L2Playable
 		final int oldInvLimit = getInventoryLimit();
 		SystemMessage sm = null;
 		
-		if (!fireEquipmentListeners(isEquiped, item))
-		{
-			return;
-		}
 		if (isEquiped)
 		{
 			if (item.getEnchantLevel() > 0)
@@ -2440,6 +2353,9 @@ public final class L2PcInstance extends L2Playable
 		{
 			sendPacket(new ExStorageMaxCount(this));
 		}
+		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerEquipItem(this, item), this);
 	}
 	
 	/**
@@ -2456,10 +2372,7 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public void setPvpKills(int pvpKills)
 	{
-		if (!getEvents().onPvPChange(_pvpKills, pvpKills))
-		{
-			return;
-		}
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerPvPChanged(this, _pvpKills, pvpKills), this);
 		_pvpKills = pvpKills;
 	}
 	
@@ -2477,10 +2390,7 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public void setFame(int fame)
 	{
-		if (!getEvents().onFameChange(_fame, fame))
-		{
-			return;
-		}
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerFameChanged(this, _fame, fame), this);
 		_fame = (fame > Config.MAX_PERSONAL_FAME_POINTS) ? Config.MAX_PERSONAL_FAME_POINTS : fame;
 	}
 	
@@ -4930,11 +4840,6 @@ public final class L2PcInstance extends L2Playable
 			return;
 		}
 		
-		if (!fireTransformListeners(transformation, true))
-		{
-			return;
-		}
-		
 		setQueuedSkill(null, false, false);
 		if (isMounted())
 		{
@@ -4948,6 +4853,9 @@ public final class L2PcInstance extends L2Playable
 		sendSkillList();
 		sendPacket(new SkillCoolTime(this));
 		broadcastUserInfo();
+		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerTransform(this, transformation.getId()), this);
 	}
 	
 	@Override
@@ -4955,10 +4863,6 @@ public final class L2PcInstance extends L2Playable
 	{
 		if (_transformation != null)
 		{
-			if (!fireTransformListeners(_transformation, false))
-			{
-				return;
-			}
 			setQueuedSkill(null, false, false);
 			_transformation.onUntransform(this);
 			_transformation = null;
@@ -4966,6 +4870,9 @@ public final class L2PcInstance extends L2Playable
 			sendSkillList();
 			sendPacket(new SkillCoolTime(this));
 			broadcastUserInfo();
+			
+			// Notify to scripts
+			EventDispatcher.getInstance().notifyEventAsync(new OnPlayerTransform(this, 0), this);
 		}
 	}
 	
@@ -5354,7 +5261,7 @@ public final class L2PcInstance extends L2Playable
 			final L2PcInstance pk = killer.getActingPlayer();
 			if (pk != null)
 			{
-				pk.getEvents().onPvPKill(this);
+				EventDispatcher.getInstance().notifyEventAsync(new OnPlayerPvPKill(pk, this), this);
 				
 				TvTEvent.onKill(killer, this);
 				
@@ -8244,11 +8151,6 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public boolean removeHenna(int slot)
 	{
-		if (!fireHennaListeners(getHenna(slot + 1), false))
-		{
-			return false;
-		}
-		
 		if ((slot < 1) || (slot > 3))
 		{
 			return false;
@@ -8295,6 +8197,9 @@ public final class L2PcInstance extends L2Playable
 		sm.addLong(henna.getCancelCount());
 		sendPacket(sm);
 		sendPacket(SystemMessageId.SYMBOL_DELETED);
+		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerHennaRemove(this, henna), this);
 		return true;
 	}
 	
@@ -8305,10 +8210,6 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public boolean addHenna(L2Henna henna)
 	{
-		if (!fireHennaListeners(henna, true))
-		{
-			return false;
-		}
 		for (int i = 0; i < 3; i++)
 		{
 			if (_henna[i] == null)
@@ -8339,6 +8240,8 @@ public final class L2PcInstance extends L2Playable
 				sendPacket(new UserInfo(this));
 				sendPacket(new ExBrExtraUserInfo(this));
 				
+				// Notify to scripts
+				EventDispatcher.getInstance().notifyEventAsync(new OnPlayerHennaRemove(this, henna), this);
 				return true;
 			}
 		}
@@ -10409,7 +10312,9 @@ public final class L2PcInstance extends L2Playable
 		}
 		// Set the template of the L2PcInstance
 		setTemplate(pcTemplate);
-		fireProfessionChangeListeners(pcTemplate);
+		
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerProfessionChange(this, pcTemplate, isSubClassActive()), this);
 	}
 	
 	/**
@@ -10731,7 +10636,6 @@ public final class L2PcInstance extends L2Playable
 		{
 			checkPlayerSkills();
 		}
-		getEvents().onPlayerLogin();
 		
 		try
 		{
@@ -10744,6 +10648,8 @@ public final class L2PcInstance extends L2Playable
 		{
 			_log.log(Level.SEVERE, "", e);
 		}
+		
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLogin(this), this);
 	}
 	
 	public long getLastAccess()
@@ -11372,7 +11278,7 @@ public final class L2PcInstance extends L2Playable
 	
 	private synchronized void cleanup()
 	{
-		getEvents().onPlayerLogout();
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLogout(this), this);
 		
 		try
 		{
@@ -14340,121 +14246,13 @@ public final class L2PcInstance extends L2Playable
 		_canRevive = val;
 	}
 	
-	// LISTENERS
-	/**
-	 * Fires all the equipment listeners, if any.<br>
-	 * Action is cancelled if it returns false.
-	 * @param isEquiped
-	 * @param item
-	 * @return
-	 */
-	private boolean fireEquipmentListeners(boolean isEquiped, L2ItemInstance item)
-	{
-		if (item != null)
-		{
-			EquipmentEvent event = new EquipmentEvent();
-			event.setEquipped(!isEquiped);
-			event.setItem(item);
-			for (EquipmentListener listener : _equipmentListeners)
-			{
-				if (!listener.onEquip(event))
-				{
-					return false;
-				}
-			}
-			for (EquipmentListener listener : GLOBAL_EQUIPMENT_LISTENERS)
-			{
-				if (!listener.onEquip(event))
-				{
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fires all the transformation listeners, if any.<br>
-	 * If it returns false, the action is cancelled.<br>
-	 * @param transformation
-	 * @param isTransforming
-	 * @return
-	 */
-	private boolean fireTransformListeners(Transform transformation, boolean isTransforming)
-	{
-		if ((transformation != null) && !_transformListeners.isEmpty())
-		{
-			TransformEvent event = new TransformEvent();
-			event.setTransformation(transformation);
-			event.setTransforming(isTransforming);
-			for (TransformListener listener : _transformListeners)
-			{
-				if (!listener.onTransform(event))
-				{
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fires all the henna listeners, if any.<br>
-	 * The action is cancelled if it returns false
-	 * @param henna
-	 * @param isAdding
-	 * @return
-	 */
-	private boolean fireHennaListeners(L2Henna henna, boolean isAdding)
-	{
-		if ((henna != null) && !HENNA_LISTENERS.isEmpty())
-		{
-			HennaEvent event = new HennaEvent();
-			event.setAdd(isAdding);
-			event.setHenna(henna);
-			event.setPlayer(this);
-			for (HennaListener listener : HENNA_LISTENERS)
-			{
-				if (!listener.onRemoveHenna(event))
-				{
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Fires all the profession change listeners
-	 * @param t
-	 */
-	private void fireProfessionChangeListeners(L2PcTemplate t)
-	{
-		if (!_professionChangeListeners.isEmpty() || !GLOBAL_PROFESSION_CHANGE_LISTENERS.isEmpty())
-		{
-			ProfessionChangeEvent event = null;
-			event = new ProfessionChangeEvent();
-			event.setPlayer(this);
-			event.setSubClass(isSubClassActive());
-			event.setTemplate(t);
-			for (ProfessionChangeListener listener : _professionChangeListeners)
-			{
-				listener.professionChanged(event);
-			}
-			for (ProfessionChangeListener listener : GLOBAL_PROFESSION_CHANGE_LISTENERS)
-			{
-				listener.professionChanged(event);
-			}
-		}
-	}
-	
 	/**
 	 * @return {@code true} if player is on event, {@code false} otherwise.
 	 */
 	@Override
 	public boolean isOnEvent()
 	{
-		for (EventListener listener : _eventListeners)
+		for (IEventListener listener : _eventListeners)
 		{
 			if (listener.isOnEvent())
 			{
@@ -14466,7 +14264,7 @@ public final class L2PcInstance extends L2Playable
 	
 	public boolean isBlockedFromExit()
 	{
-		for (EventListener listener : _eventListeners)
+		for (IEventListener listener : _eventListeners)
 		{
 			if (listener.isOnEvent() && listener.isBlockingExit())
 			{
@@ -14478,7 +14276,7 @@ public final class L2PcInstance extends L2Playable
 	
 	public boolean isBlockedFromDeathPenalty()
 	{
-		for (EventListener listener : _eventListeners)
+		for (IEventListener listener : _eventListeners)
 		{
 			if (listener.isOnEvent() && listener.isBlockingDeathPenalty())
 			{
@@ -14536,137 +14334,11 @@ public final class L2PcInstance extends L2Playable
 		return vars != null ? vars : addScript(new AccountVariables(getAccountName()));
 	}
 	
-	/**
-	 * Adds a henna listener
-	 * @param listener
-	 */
-	public static void addHennaListener(HennaListener listener)
-	{
-		if (!HENNA_LISTENERS.contains(listener))
-		{
-			HENNA_LISTENERS.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes a henna listener
-	 * @param listener
-	 */
-	public static void removeHennaListener(HennaListener listener)
-	{
-		HENNA_LISTENERS.remove(listener);
-	}
-	
-	/**
-	 * Adds an equipment listener
-	 * @param listener
-	 */
-	public void addEquipmentListener(EquipmentListener listener)
-	{
-		if (!_equipmentListeners.contains(listener))
-		{
-			_equipmentListeners.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes an equipment listener
-	 * @param listener
-	 */
-	public void removeEquipmentListener(EquipmentListener listener)
-	{
-		_equipmentListeners.remove(listener);
-	}
-	
-	/**
-	 * Adds an equipment listener
-	 * @param listener
-	 */
-	public static void addGlobalEquipmentListener(EquipmentListener listener)
-	{
-		if (!GLOBAL_EQUIPMENT_LISTENERS.contains(listener))
-		{
-			GLOBAL_EQUIPMENT_LISTENERS.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes an equipment listener
-	 * @param listener
-	 */
-	public static void removeGlobalEquipmentListener(EquipmentListener listener)
-	{
-		GLOBAL_EQUIPMENT_LISTENERS.remove(listener);
-	}
-	
-	/**
-	 * Adds a transformation listener
-	 * @param listener
-	 */
-	public void addTransformListener(TransformListener listener)
-	{
-		if (!_transformListeners.contains(listener))
-		{
-			_transformListeners.add(listener);
-		}
-	}
-	
-	/**
-	 * Remove a transformation listener
-	 * @param listener
-	 */
-	public void removeTransformListener(TransformListener listener)
-	{
-		_transformListeners.remove(listener);
-	}
-	
-	/**
-	 * Adds a profession change listener
-	 * @param listener
-	 */
-	public void addProfessionChangeListener(ProfessionChangeListener listener)
-	{
-		if (!_professionChangeListeners.contains(listener))
-		{
-			_professionChangeListeners.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes a profession change listener
-	 * @param listener
-	 */
-	public void removeProfessionChangeListener(ProfessionChangeListener listener)
-	{
-		_professionChangeListeners.remove(listener);
-	}
-	
-	/**
-	 * Adds a global profession change listener
-	 * @param listener
-	 */
-	public static void addGlobalProfessionChangeListener(ProfessionChangeListener listener)
-	{
-		if (!GLOBAL_PROFESSION_CHANGE_LISTENERS.contains(listener))
-		{
-			GLOBAL_PROFESSION_CHANGE_LISTENERS.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes a global profession change listener
-	 * @param listener
-	 */
-	public static void removeGlobalProfessionChangeListener(ProfessionChangeListener listener)
-	{
-		GLOBAL_PROFESSION_CHANGE_LISTENERS.remove(listener);
-	}
-	
 	/**
 	 * Adds a event listener.
 	 * @param listener
 	 */
-	public void addEventListener(EventListener listener)
+	public void addEventListener(IEventListener listener)
 	{
 		_eventListeners.add(listener);
 	}
@@ -14675,15 +14347,15 @@ public final class L2PcInstance extends L2Playable
 	 * Removes event listener
 	 * @param listener
 	 */
-	public void removeEventListener(EventListener listener)
+	public void removeEventListener(IEventListener listener)
 	{
 		_eventListeners.remove(listener);
 	}
 	
-	public void removeEventListener(Class<? extends EventListener> clazz)
+	public void removeEventListener(Class<? extends IEventListener> clazz)
 	{
-		final Iterator<EventListener> it = _eventListeners.iterator();
-		EventListener event;
+		final Iterator<IEventListener> it = _eventListeners.iterator();
+		IEventListener event;
 		while (it.hasNext())
 		{
 			event = it.next();
@@ -14694,7 +14366,7 @@ public final class L2PcInstance extends L2Playable
 		}
 	}
 	
-	public Collection<EventListener> getEventListeners()
+	public Collection<IEventListener> getEventListeners()
 	{
 		return _eventListeners;
 	}

+ 6 - 19
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2QuestGuardInstance.java

@@ -18,14 +18,13 @@
  */
 package com.l2jserver.gameserver.model.actor.instance;
 
-import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.enums.InstanceType;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.actor.tasks.attackable.OnKillNotifyTask;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
-import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableAttack;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableKill;
 import com.l2jserver.gameserver.model.skills.Skill;
 
 /**
@@ -50,13 +49,7 @@ public final class L2QuestGuardInstance extends L2GuardInstance
 		
 		if (attacker instanceof L2Attackable)
 		{
-			if (getTemplate().getEventQuests(QuestEventType.ON_ATTACK) != null)
-			{
-				for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_ATTACK))
-				{
-					quest.notifyAttack(this, null, damage, false, skill);
-				}
-			}
+			EventDispatcher.getInstance().notifyEventAsync(new OnAttackableAttack(null, this, damage, skill, false), this);
 		}
 	}
 	
@@ -71,15 +64,9 @@ public final class L2QuestGuardInstance extends L2GuardInstance
 		
 		if (killer instanceof L2Attackable)
 		{
-			if (getTemplate().getEventQuests(QuestEventType.ON_KILL) != null)
-			{
-				for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_KILL))
-				{
-					ThreadPoolManager.getInstance().scheduleEffect(new OnKillNotifyTask(this, quest, null, false), _onKillDelay);
-				}
-			}
+			// Delayed notification
+			EventDispatcher.getInstance().notifyEventAsyncDelayed(new OnAttackableKill(null, this, false), this, _onKillDelay);
 		}
-		
 		return true;
 	}
 	

+ 6 - 9
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2SepulcherNpcInstance.java

@@ -18,7 +18,6 @@
  */
 package com.l2jserver.gameserver.model.actor.instance;
 
-import java.util.List;
 import java.util.concurrent.Future;
 
 import com.l2jserver.Config;
@@ -26,13 +25,14 @@ import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.datatables.DoorTable;
 import com.l2jserver.gameserver.enums.InstanceType;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.instancemanager.FourSepulchersManager;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcFirstTalk;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
-import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.network.NpcStringId;
 import com.l2jserver.gameserver.network.clientpackets.Say2;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
@@ -236,17 +236,14 @@ public class L2SepulcherNpcInstance extends L2Npc
 			
 			default:
 			{
-				List<Quest> qlsa = getTemplate().getEventQuests(QuestEventType.QUEST_START);
-				List<Quest> qlst = getTemplate().getEventQuests(QuestEventType.ON_FIRST_TALK);
-				
-				if ((qlsa != null) && !qlsa.isEmpty())
+				if (hasListener(EventType.ON_NPC_QUEST_START))
 				{
 					player.setLastQuestNpcObject(getObjectId());
 				}
 				
-				if ((qlst != null) && (qlst.size() == 1))
+				if (hasListener(EventType.ON_NPC_FIRST_TALK))
 				{
-					qlst.get(0).notifyFirstTalk(this, player);
+					EventDispatcher.getInstance().notifyEventAsync(new OnNpcFirstTalk(this, player), this);
 				}
 				else
 				{

+ 6 - 16
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2TrapInstance.java

@@ -24,7 +24,6 @@ import java.util.concurrent.ScheduledFuture;
 
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.enums.InstanceType;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.enums.TrapAction;
 import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Character;
@@ -33,11 +32,12 @@ import com.l2jserver.gameserver.model.actor.knownlist.TrapKnownList;
 import com.l2jserver.gameserver.model.actor.tasks.npc.trap.TrapTask;
 import com.l2jserver.gameserver.model.actor.tasks.npc.trap.TrapTriggerTask;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.trap.OnTrapAction;
 import com.l2jserver.gameserver.model.holders.SkillHolder;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.olympiad.OlympiadGameManager;
-import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.model.zone.ZoneId;
 import com.l2jserver.gameserver.network.SystemMessageId;
@@ -366,13 +366,9 @@ public final class L2TrapInstance extends L2Npc
 		
 		_playersWhoDetectedMe.add(detector.getObjectId());
 		
-		if (getTemplate().getEventQuests(QuestEventType.ON_TRAP_ACTION) != null)
-		{
-			for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_TRAP_ACTION))
-			{
-				quest.notifyTrapAction(this, detector, TrapAction.TRAP_DETECTED);
-			}
-		}
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnTrapAction(this, detector, TrapAction.TRAP_DETECTED), this);
+		
 		if (detector.isPlayable())
 		{
 			sendInfo(detector.getActingPlayer());
@@ -400,13 +396,7 @@ public final class L2TrapInstance extends L2Npc
 		broadcastPacket(new TrapInfo(this, null));
 		setTarget(target);
 		
-		if (getTemplate().getEventQuests(QuestEventType.ON_TRAP_ACTION) != null)
-		{
-			for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_TRAP_ACTION))
-			{
-				quest.notifyTrapAction(this, target, TrapAction.TRAP_TRIGGERED);
-			}
-		}
+		EventDispatcher.getInstance().notifyEventAsync(new OnTrapAction(this, target, TrapAction.TRAP_TRIGGERED), this);
 		
 		ThreadPoolManager.getInstance().scheduleGeneral(new TrapTriggerTask(this), 300);
 	}

+ 5 - 11
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/knownlist/NpcKnownList.java

@@ -19,13 +19,11 @@
 package com.l2jserver.gameserver.model.actor.knownlist;
 
 import java.util.Collection;
-import java.util.List;
 import java.util.concurrent.ScheduledFuture;
 
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.enums.InstanceType;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.instancemanager.WalkingManager;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.actor.L2Attackable;
@@ -33,7 +31,8 @@ import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2FestivalGuideInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
 
 public class NpcKnownList extends CharKnownList
 {
@@ -55,14 +54,9 @@ public class NpcKnownList extends CharKnownList
 		if (getActiveObject().isNpc() && (object instanceof L2Character))
 		{
 			final L2Npc npc = (L2Npc) getActiveObject();
-			final List<Quest> quests = npc.getTemplate().getEventQuests(QuestEventType.ON_SEE_CREATURE);
-			if (quests != null)
-			{
-				for (Quest quest : quests)
-				{
-					quest.notifySeeCreature(npc, (L2Character) object, object.isSummon());
-				}
-			}
+			
+			// Notify to scripts
+			EventDispatcher.getInstance().notifyEventAsync(new OnNpcCreatureSee(npc, (L2Character) object, object.isSummon()), npc);
 		}
 		return true;
 	}

+ 15 - 25
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java

@@ -30,6 +30,8 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
 import com.l2jserver.gameserver.model.actor.transform.TransformTemplate;
 import com.l2jserver.gameserver.model.entity.RecoBonus;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLevelChanged;
 import com.l2jserver.gameserver.model.quest.QuestState;
 import com.l2jserver.gameserver.model.stats.Formulas;
 import com.l2jserver.gameserver.model.stats.MoveType;
@@ -112,26 +114,6 @@ public class PcStat extends PlayableStat
 		return true;
 	}
 	
-	/**
-	 * Add Experience and SP rewards to the L2PcInstance, remove its Karma (if necessary) and Launch increase level task.<br>
-	 * <B><U>Actions </U>:</B>
-	 * <ul>
-	 * <li>Remove Karma when the player kills L2MonsterInstance</li>
-	 * <li>Send a Server->Client packet StatusUpdate to the L2PcInstance</li>
-	 * <li>Send a Server->Client System Message to the L2PcInstance</li>
-	 * <li>If the L2PcInstance increases it's level, send a Server->Client packet SocialAction (broadcast)</li>
-	 * <li>If the L2PcInstance increases it's level, manage the increase level task (Max MP, Max MP, Recommendation, Expertise and beginner skills...)</li>
-	 * <li>If the L2PcInstance increases it's level, send a Server->Client packet UserInfo to the L2PcInstance</li>
-	 * </ul>
-	 * @param addToExp The Experience value to add
-	 * @param addToSp The SP value to add
-	 */
-	@Override
-	public boolean addExpAndSp(long addToExp, int addToSp)
-	{
-		return addExpAndSp(addToExp, addToSp, false);
-	}
-	
 	public boolean addExpAndSp(long addToExp, int addToSp, boolean useBonuses)
 	{
 		L2PcInstance activeChar = getActiveChar();
@@ -182,7 +164,17 @@ public class PcStat extends PlayableStat
 			addToSp = (int) (addToSp * ratioTakenByPlayer);
 		}
 		
-		if (!super.addExpAndSp(addToExp, addToSp))
+		if (!addExp(addToExp))
+		{
+			addToExp = 0;
+		}
+		
+		if (!addSp(addToSp))
+		{
+			addToSp = 0;
+		}
+		
+		if ((addToExp == 0) && (addToSp == 0))
 		{
 			return false;
 		}
@@ -258,10 +250,8 @@ public class PcStat extends PlayableStat
 			return false;
 		}
 		
-		if (!getActiveChar().getEvents().onLevelChange(value))
-		{
-			return false;
-		}
+		// Notify to scripts
+		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLevelChanged(getActiveChar(), getLevel(), getLevel() + value), getActiveChar());
 		
 		boolean levelIncreased = super.addLevel(value);
 		if (levelIncreased)

+ 1 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PetStat.java

@@ -50,10 +50,9 @@ public class PetStat extends SummonStat
 		return true;
 	}
 	
-	@Override
 	public boolean addExpAndSp(long addToExp, int addToSp)
 	{
-		if (!super.addExpAndSp(addToExp, addToSp))
+		if (!addExp(addToExp))
 		{
 			return false;
 		}
@@ -62,7 +61,6 @@ public class PetStat extends SummonStat
 		sm.addLong(addToExp);
 		getActiveChar().updateAndBroadcastStatus(1);
 		getActiveChar().sendPacket(sm);
-		
 		return true;
 	}
 	

+ 9 - 21
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PlayableStat.java

@@ -27,6 +27,9 @@ import com.l2jserver.gameserver.instancemanager.ZoneManager;
 import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.character.playable.OnPlayableExpChanged;
+import com.l2jserver.gameserver.model.events.returns.TerminateReturn;
 import com.l2jserver.gameserver.model.zone.ZoneId;
 import com.l2jserver.gameserver.model.zone.type.L2SwampZone;
 import com.l2jserver.gameserver.network.communityserver.CommunityServerThread;
@@ -43,6 +46,12 @@ public class PlayableStat extends CharStat
 	
 	public boolean addExp(long value)
 	{
+		final TerminateReturn term = EventDispatcher.getInstance().notifyEvent(new OnPlayableExpChanged(getActiveChar(), getExp(), getExp() + value), getActiveChar(), TerminateReturn.class);
+		if ((term != null) && term.terminate())
+		{
+			return false;
+		}
+		
 		if (((getExp() + value) < 0) || ((value > 0) && (getExp() == (getExpForLevel(getMaxLevel()) - 1))))
 		{
 			return true;
@@ -53,11 +62,6 @@ public class PlayableStat extends CharStat
 			value = getExpForLevel(getMaxLevel()) - 1 - getExp();
 		}
 		
-		if (!getActiveChar().getEvents().onExperienceReceived(value))
-		{
-			return false;
-		}
-		
 		setExp(getExp() + value);
 		
 		byte minimumLevel = 1;
@@ -119,22 +123,6 @@ public class PlayableStat extends CharStat
 		return true;
 	}
 	
-	public boolean addExpAndSp(long addToExp, int addToSp)
-	{
-		boolean expAdded = false;
-		boolean spAdded = false;
-		if (addToExp >= 0)
-		{
-			expAdded = addExp(addToExp);
-		}
-		if (addToSp >= 0)
-		{
-			spAdded = addSp(addToSp);
-		}
-		
-		return expAdded || spAdded;
-	}
-	
 	public boolean removeExpAndSp(long removeExp, int removeSp)
 	{
 		boolean expRemoved = false;

+ 2 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2CharTemplate.java

@@ -23,6 +23,7 @@ import java.util.Collections;
 import java.util.Map;
 
 import com.l2jserver.gameserver.model.StatsSet;
+import com.l2jserver.gameserver.model.events.ListenersContainer;
 import com.l2jserver.gameserver.model.items.type.WeaponType;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.model.stats.MoveType;
@@ -31,7 +32,7 @@ import com.l2jserver.gameserver.model.stats.MoveType;
  * Character template.
  * @author Zoey76
  */
-public class L2CharTemplate
+public class L2CharTemplate extends ListenersContainer
 {
 	// BaseStats
 	private int _baseSTR;

+ 0 - 60
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2NpcTemplate.java

@@ -20,20 +20,15 @@ package com.l2jserver.gameserver.model.actor.templates;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
 
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.datatables.NpcData;
 import com.l2jserver.gameserver.enums.AISkillScope;
 import com.l2jserver.gameserver.enums.AIType;
 import com.l2jserver.gameserver.enums.NpcRace;
-import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.enums.Sex;
 import com.l2jserver.gameserver.model.L2MinionData;
 import com.l2jserver.gameserver.model.StatsSet;
@@ -43,7 +38,6 @@ import com.l2jserver.gameserver.model.drops.DropListScope;
 import com.l2jserver.gameserver.model.drops.IDropItem;
 import com.l2jserver.gameserver.model.holders.ItemHolder;
 import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
-import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.skills.Skill;
 
 /**
@@ -52,8 +46,6 @@ import com.l2jserver.gameserver.model.skills.Skill;
  */
 public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
 {
-	private static final Logger _log = Logger.getLogger(L2NpcTemplate.class.getName());
-	
 	private int _id;
 	private int _displayId;
 	private byte _level;
@@ -111,7 +103,6 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
 	
 	private final List<L2MinionData> _minions = new ArrayList<>();
 	private final List<ClassId> _teachInfo = new ArrayList<>();
-	private final Map<QuestEventType, List<Quest>> _questEvents = new ConcurrentHashMap<>();
 	
 	/**
 	 * Constructor of L2Character.
@@ -716,47 +707,6 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
 		return L2NpcTemplate.isAssignableTo(obj.getClass(), clazz);
 	}
 	
-	public void addQuestEvent(QuestEventType eventType, Quest q)
-	{
-		if (!_questEvents.containsKey(eventType))
-		{
-			_questEvents.put(eventType, new ArrayList<Quest>());
-		}
-		
-		if (!eventType.isMultipleRegistrationAllowed() && !_questEvents.get(eventType).isEmpty())
-		{
-			_log.warning("Quest event not allowed in multiple quests.  Skipped addition of Event Type \"" + eventType + "\" for NPC \"" + _name + "\" and quest \"" + q.getName() + "\".");
-		}
-		else
-		{
-			_questEvents.get(eventType).add(q);
-		}
-	}
-	
-	public void removeQuest(Quest q)
-	{
-		for (Entry<QuestEventType, List<Quest>> entry : _questEvents.entrySet())
-		{
-			if (entry.getValue().contains(q))
-			{
-				Iterator<Quest> it = entry.getValue().iterator();
-				while (it.hasNext())
-				{
-					Quest q1 = it.next();
-					if (q1 == q)
-					{
-						it.remove();
-					}
-				}
-				
-				if (entry.getValue().isEmpty())
-				{
-					_questEvents.remove(entry.getKey());
-				}
-			}
-		}
-	}
-	
 	public void addMinionData(L2MinionData minion)
 	{
 		_minions.add(minion);
@@ -773,16 +723,6 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
 		return _teachInfo.contains(classId);
 	}
 	
-	public Map<QuestEventType, List<Quest>> getEventQuests()
-	{
-		return _questEvents;
-	}
-	
-	public List<Quest> getEventQuests(QuestEventType EventType)
-	{
-		return _questEvents.get(EventType);
-	}
-	
 	/**
 	 * @return the list of all Minions that must be spawn with the L2NpcInstance using this L2NpcTemplate.
 	 */

+ 2 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/AbstractResidence.java

@@ -24,6 +24,7 @@ import java.util.List;
 import com.l2jserver.gameserver.datatables.SkillTreesData;
 import com.l2jserver.gameserver.model.L2SkillLearn;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.ListenersContainer;
 import com.l2jserver.gameserver.model.holders.SkillHolder;
 import com.l2jserver.gameserver.model.interfaces.INamable;
 import com.l2jserver.gameserver.model.zone.type.L2ResidenceZone;
@@ -31,7 +32,7 @@ import com.l2jserver.gameserver.model.zone.type.L2ResidenceZone;
 /**
  * @author xban1x
  */
-public abstract class AbstractResidence implements INamable
+public abstract class AbstractResidence extends ListenersContainer implements INamable
 {
 	private final int _residenceId;
 	private String _name;

+ 9 - 71
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/FortSiege.java

@@ -53,21 +53,19 @@ import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2FortCommanderInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.sieges.fort.OnFortSiegeFinish;
+import com.l2jserver.gameserver.model.events.impl.sieges.fort.OnFortSiegeStart;
 import com.l2jserver.gameserver.network.NpcStringId;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.clientpackets.Say2;
 import com.l2jserver.gameserver.network.serverpackets.NpcSay;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
-import com.l2jserver.gameserver.scripting.scriptengine.events.FortSiegeEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.impl.L2Script.EventStage;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.FortSiegeListener;
 
 public class FortSiege implements Siegable
 {
 	protected static final Logger _log = Logger.getLogger(FortSiege.class.getName());
 	
-	private static FastList<FortSiegeListener> fortSiegeListeners = new FastList<FortSiegeListener>().shared();
-	
 	// SQL
 	private static final String DELETE_FORT_SIEGECLANS_BY_CLAN_ID = "DELETE FROM fortsiege_clans WHERE fort_id = ? AND clan_id = ?";
 	private static final String DELETE_FORT_SIEGECLANS = "DELETE FROM fortsiege_clans WHERE fort_id = ?";
@@ -301,7 +299,9 @@ public class FortSiege implements Siegable
 			}
 			
 			_log.info("Siege of " + getFort().getName() + " fort finished.");
-			fireFortSiegeEventListeners(EventStage.END);
+			
+			// Notify to scripts.
+			EventDispatcher.getInstance().notifyEventAsync(new OnFortSiegeFinish(this), getFort());
 		}
 	}
 	
@@ -313,10 +313,6 @@ public class FortSiege implements Siegable
 	{
 		if (!isInProgress())
 		{
-			if (!fireFortSiegeEventListeners(EventStage.START))
-			{
-				return;
-			}
 			if (_siegeStartTask != null) // used admin command "admin_startfortsiege"
 			{
 				_siegeStartTask.cancel(true);
@@ -353,6 +349,9 @@ public class FortSiege implements Siegable
 			saveFortSiege();
 			
 			_log.info("Siege of " + getFort().getName() + " fort started.");
+			
+			// Notify to scripts.
+			EventDispatcher.getInstance().notifyEventAsync(new OnFortSiegeStart(this), getFort());
 		}
 	}
 	
@@ -1296,65 +1295,4 @@ public class FortSiege implements Siegable
 	public void updateSiege()
 	{
 	}
-	
-	// Listeners
-	/**
-	 * Fires all the FortSiegeListener.onStart() or onEnd() methods<br>
-	 * depending on the EventStage<br>
-	 * @param stage
-	 * @return if onStart() returns false, the siege is cancelled
-	 */
-	private boolean fireFortSiegeEventListeners(EventStage stage)
-	{
-		if (!fortSiegeListeners.isEmpty())
-		{
-			FortSiegeEvent event = new FortSiegeEvent();
-			event.setSiege(this);
-			event.setStage(stage);
-			switch (stage)
-			{
-				case START:
-				{
-					for (FortSiegeListener listener : fortSiegeListeners)
-					{
-						if (!listener.onStart(event))
-						{
-							return false;
-						}
-					}
-					break;
-				}
-				case END:
-				{
-					for (FortSiegeListener listener : fortSiegeListeners)
-					{
-						listener.onEnd(event);
-					}
-					break;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Adds a fort siege listener
-	 * @param listener
-	 */
-	public static void addFortSiegeListener(FortSiegeListener listener)
-	{
-		if (!fortSiegeListeners.contains(listener))
-		{
-			fortSiegeListeners.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes a fort siege listener
-	 * @param listener
-	 */
-	public static void removeFortSiegeListener(FortSiegeListener listener)
-	{
-		fortSiegeListeners.remove(listener);
-	}
 }

+ 13 - 80
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Siege.java

@@ -58,23 +58,22 @@ import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2ControlTowerInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2FlameTowerInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeFinish;
+import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeOwnerChange;
+import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeStart;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
 import com.l2jserver.gameserver.network.serverpackets.RelationChanged;
 import com.l2jserver.gameserver.network.serverpackets.SiegeInfo;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 import com.l2jserver.gameserver.network.serverpackets.UserInfo;
-import com.l2jserver.gameserver.scripting.scriptengine.events.SiegeEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.impl.L2Script.EventStage;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.SiegeListener;
 import com.l2jserver.gameserver.util.Broadcast;
 
 public class Siege implements Siegable
 {
 	protected static final Logger _log = Logger.getLogger(Siege.class.getName());
 	
-	private static final List<SiegeListener> siegeListeners = new FastList<SiegeListener>().shared();
-	
 	// typeId's
 	public static final byte OWNER = -1;
 	public static final byte DEFENDER = 0;
@@ -334,7 +333,9 @@ public class Siege implements Siegable
 			getCastle().getZone().setIsActive(false);
 			getCastle().getZone().updateZoneStatusForCharactersInside();
 			getCastle().getZone().setSiegeInstance(null);
-			fireSiegeListeners(EventStage.END);
+			
+			// Notify to scripts.
+			EventDispatcher.getInstance().notifyEventAsync(new OnCastleSiegeFinish(this), getCastle());
 		}
 	}
 	
@@ -462,7 +463,9 @@ public class Siege implements Siegable
 				spawnControlTower();
 				spawnFlameTower();
 				updatePlayerSiegeStateFlags(false);
-				fireSiegeListeners(EventStage.CONTROL_CHANGE);
+				
+				// Notify to scripts.
+				EventDispatcher.getInstance().notifyEventAsync(new OnCastleSiegeOwnerChange(this), getCastle());
 			}
 		}
 	}
@@ -476,10 +479,6 @@ public class Siege implements Siegable
 	{
 		if (!isInProgress())
 		{
-			if (!fireSiegeListeners(EventStage.START))
-			{
-				return;
-			}
 			_firstOwnerClanId = getCastle().getOwnerId();
 			
 			if (getAttackerClans().isEmpty())
@@ -525,6 +524,9 @@ public class Siege implements Siegable
 			SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SIEGE_OF_S1_HAS_STARTED);
 			sm.addCastleId(getCastle().getResidenceId());
 			Announcements.getInstance().announceToAll(sm);
+			
+			// Notify to scripts.
+			EventDispatcher.getInstance().notifyEventAsync(new OnCastleSiegeStart(this), getCastle());
 		}
 	}
 	
@@ -1781,73 +1783,4 @@ public class Siege implements Siegable
 	public void updateSiege()
 	{
 	}
-	
-	// Listeners
-	/**
-	 * Fires the appropriate SiegeListener<br>
-	 * If it returns false on EventStage.start, the siege is cancelled
-	 * @param stage
-	 * @return
-	 */
-	private boolean fireSiegeListeners(EventStage stage)
-	{
-		if (!siegeListeners.isEmpty())
-		{
-			SiegeEvent event = new SiegeEvent();
-			event.setSiege(this);
-			event.setStage(stage);
-			switch (stage)
-			{
-				case START:
-				{
-					for (SiegeListener listener : siegeListeners)
-					{
-						if (!listener.onStart(event))
-						{
-							return false;
-						}
-					}
-					break;
-				}
-				case END:
-				{
-					for (SiegeListener listener : siegeListeners)
-					{
-						listener.onEnd(event);
-					}
-					break;
-				}
-				case CONTROL_CHANGE:
-				{
-					for (SiegeListener listener : siegeListeners)
-					{
-						listener.onControlChange(event);
-					}
-					break;
-				}
-			}
-		}
-		return true;
-	}
-	
-	/**
-	 * Adds a siege listener
-	 * @param listener
-	 */
-	public static void addSiegeListener(SiegeListener listener)
-	{
-		if (!siegeListeners.contains(listener))
-		{
-			siegeListeners.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes a siege listener
-	 * @param listener
-	 */
-	public static void removeSiegeListener(SiegeListener listener)
-	{
-		siegeListeners.remove(listener);
-	}
 }

+ 14 - 91
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/TvTEvent.java

@@ -25,7 +25,6 @@ import java.util.Map.Entry;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import javolution.util.FastList;
 import javolution.util.FastMap;
 
 import com.l2jserver.Config;
@@ -47,6 +46,11 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.events.EventDispatcher;
+import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventStart;
 import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.network.SystemMessageId;
@@ -56,9 +60,6 @@ import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
 import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
 import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
-import com.l2jserver.gameserver.scripting.scriptengine.events.TvtKillEvent;
-import com.l2jserver.gameserver.scripting.scriptengine.impl.L2Script.EventStage;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.TvTListener;
 import com.l2jserver.util.Rnd;
 import com.l2jserver.util.StringUtil;
 
@@ -91,8 +92,6 @@ public class TvTEvent
 	/** Instance id<br> */
 	private static int _TvTEventInstance = 0;
 	
-	private static FastList<TvTListener> tvtListeners = new FastList<TvTListener>().shared();
-	
 	/**
 	 * No instance of this class!<br>
 	 */
@@ -155,7 +154,7 @@ public class TvTEvent
 		}
 		
 		setState(EventState.PARTICIPATING);
-		fireTvtEventListeners(EventStage.REGISTRATION_BEGIN);
+		EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventRegistrationStart());
 		return true;
 	}
 	
@@ -316,8 +315,9 @@ public class TvTEvent
 				}
 			}
 		}
-		fireTvtEventListeners(EventStage.START);
 		
+		// Notify to scripts.
+		EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventStart());
 		return true;
 	}
 	
@@ -361,7 +361,9 @@ public class TvTEvent
 		// Get team which has more points
 		TvTEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1];
 		rewardTeam(team);
-		fireTvtEventListeners(EventStage.END);
+		
+		// Notify to scripts.
+		EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventFinish());
 		return "TvT Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills.";
 	}
 	
@@ -867,7 +869,9 @@ public class TvTEvent
 					playerInstance.sendPacket(cs);
 				}
 			}
-			fireTvtKillListeners(killerPlayerInstance, killedPlayerInstance, killerTeam);
+			
+			// Notify to scripts.
+			EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventKill(killerPlayerInstance, killedPlayerInstance, killerTeam));
 		}
 	}
 	
@@ -1181,85 +1185,4 @@ public class TvTEvent
 	{
 		return _TvTEventInstance;
 	}
-	
-	// Listeners
-	/**
-	 * Fires all the TvTListener.onKill() methods, if any
-	 * @param killer
-	 * @param victim
-	 * @param killerTeam
-	 */
-	private static void fireTvtKillListeners(L2PcInstance killer, L2PcInstance victim, TvTEventTeam killerTeam)
-	{
-		if (!tvtListeners.isEmpty() && (killer != null) && (victim != null) && (killerTeam != null))
-		{
-			TvtKillEvent event = new TvtKillEvent();
-			event.setKiller(killer);
-			event.setVictim(victim);
-			event.setKillerTeam(killerTeam);
-			for (TvTListener listener : tvtListeners)
-			{
-				listener.onKill(event);
-			}
-		}
-	}
-	
-	/**
-	 * Fires the appropriate TvtEventListeners, if any
-	 * @param stage
-	 */
-	private static void fireTvtEventListeners(EventStage stage)
-	{
-		if (!tvtListeners.isEmpty())
-		{
-			switch (stage)
-			{
-				case REGISTRATION_BEGIN:
-				{
-					for (TvTListener listener : tvtListeners)
-					{
-						listener.onRegistrationStart();
-					}
-					break;
-				}
-				case START:
-				{
-					for (TvTListener listener : tvtListeners)
-					{
-						listener.onBegin();
-					}
-					break;
-				}
-				case END:
-				{
-					for (TvTListener listener : tvtListeners)
-					{
-						listener.onEnd();
-					}
-					break;
-				}
-			}
-		}
-	}
-	
-	/**
-	 * Adds a TvT listener
-	 * @param listener
-	 */
-	public static void addTvTListener(TvTListener listener)
-	{
-		if (!tvtListeners.contains(listener))
-		{
-			tvtListeners.add(listener);
-		}
-	}
-	
-	/**
-	 * Removes a TvT listener
-	 * @param listener
-	 */
-	public static void removeTvtListener(TvTListener listener)
-	{
-		tvtListeners.remove(listener);
-	}
 }

+ 12 - 10
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/TvTEventListener.java

@@ -19,23 +19,19 @@
 package com.l2jserver.gameserver.model.entity;
 
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.EventListener;
+import com.l2jserver.gameserver.model.interfaces.IEventListener;
 
 /**
  * @author UnAfraid
  */
-public final class TvTEventListener extends EventListener
+public final class TvTEventListener implements IEventListener
 {
-	protected TvTEventListener(L2PcInstance player)
-	{
-		super(player);
-	}
+	private final L2PcInstance _player;
 	
-	@Override
-	public void unregister()
+	protected TvTEventListener(L2PcInstance player)
 	{
-		super.unregister();
-		getPlayer().setCanRevive(true);
+		_player = player;
+		player.addEventListener(this);
 	}
 	
 	@Override
@@ -55,4 +51,10 @@ public final class TvTEventListener extends EventListener
 	{
 		return true;
 	}
+	
+	@Override
+	public L2PcInstance getPlayer()
+	{
+		return _player;
+	}
 }

+ 2458 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/AbstractScript.java

@@ -0,0 +1,2458 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javolution.util.FastList;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.GameTimeController;
+import com.l2jserver.gameserver.datatables.DoorTable;
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.NpcData;
+import com.l2jserver.gameserver.enums.QuestSound;
+import com.l2jserver.gameserver.idfactory.IdFactory;
+import com.l2jserver.gameserver.instancemanager.CastleManager;
+import com.l2jserver.gameserver.instancemanager.FortManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+import com.l2jserver.gameserver.instancemanager.ZoneManager;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.Location;
+import com.l2jserver.gameserver.model.actor.L2Attackable;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2TrapInstance;
+import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.entity.Castle;
+import com.l2jserver.gameserver.model.entity.Fort;
+import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.events.annotations.Npc;
+import com.l2jserver.gameserver.model.events.annotations.Npcs;
+import com.l2jserver.gameserver.model.events.annotations.RegisterEvent;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureKill;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureZoneEnter;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureZoneExit;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcCanBeSeen;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcEventReceived;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcFirstTalk;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveFinished;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveNodeArrived;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveRouteFinished;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSkillFinished;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSkillSee;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSpawn;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableAggroRangeEnter;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableAttack;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableFactionCall;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableHate;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableKill;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLogin;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLogout;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerProfessionChange;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerSkillLearn;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerSummonSpawn;
+import com.l2jserver.gameserver.model.events.impl.character.trap.OnTrapAction;
+import com.l2jserver.gameserver.model.events.impl.item.OnItemBypassEvent;
+import com.l2jserver.gameserver.model.events.impl.item.OnItemTalk;
+import com.l2jserver.gameserver.model.events.impl.olympiad.OnOlympiadMatchResult;
+import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeFinish;
+import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeOwnerChange;
+import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeStart;
+import com.l2jserver.gameserver.model.events.listeners.AbstractEventListener;
+import com.l2jserver.gameserver.model.events.listeners.AnnotationEventListener;
+import com.l2jserver.gameserver.model.events.listeners.ConsumerEventListener;
+import com.l2jserver.gameserver.model.events.listeners.DummyEventListener;
+import com.l2jserver.gameserver.model.events.listeners.FunctionEventListener;
+import com.l2jserver.gameserver.model.events.listeners.RunnableEventListener;
+import com.l2jserver.gameserver.model.events.returns.AbstractEventReturn;
+import com.l2jserver.gameserver.model.events.returns.TerminateReturn;
+import com.l2jserver.gameserver.model.holders.ItemHolder;
+import com.l2jserver.gameserver.model.interfaces.IPositionable;
+import com.l2jserver.gameserver.model.itemcontainer.Inventory;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.items.L2Item;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.model.olympiad.Olympiad;
+import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.model.stats.Stats;
+import com.l2jserver.gameserver.model.zone.L2ZoneType;
+import com.l2jserver.gameserver.network.NpcStringId;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
+import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
+import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.scripting.ManagedScript;
+import com.l2jserver.gameserver.util.MinionList;
+import com.l2jserver.util.Rnd;
+
+/**
+ * @author UnAfraid
+ */
+public abstract class AbstractScript extends ManagedScript
+{
+	protected static final Logger _log = Logger.getLogger(AbstractScript.class.getName());
+	private final Map<ListenerRegisterType, List<Integer>> _registeredIds = new ConcurrentHashMap<>();
+	private final List<AbstractEventListener> _listeners = new FastList<AbstractEventListener>().shared();
+	
+	public AbstractScript()
+	{
+		initializeAnnotationListeners();
+	}
+	
+	private void initializeAnnotationListeners()
+	{
+		final List<Integer> npcIds = new ArrayList<>();
+		for (Method method : getClass().getMethods())
+		{
+			if (method.isAnnotationPresent(RegisterEvent.class))
+			{
+				final RegisterEvent listener = method.getAnnotation(RegisterEvent.class);
+				final EventType eventType = listener.value();
+				if (method.getParameterCount() != 1)
+				{
+					_log.log(Level.WARNING, getClass().getSimpleName() + ": Non properly defined annotation listener on method: " + method.getName() + " expected parameter count is 1 but found: " + method.getParameterCount());
+					continue;
+				}
+				else if (!eventType.isEventClass(method.getParameterTypes()[0]))
+				{
+					_log.log(Level.WARNING, getClass().getSimpleName() + ": Non properly defined annotation listener on method: " + method.getName() + " expected parameter to be type of: " + eventType.getEventClass().getSimpleName() + " but found: " + method.getParameterTypes()[0].getSimpleName());
+					continue;
+				}
+				else if (!eventType.isReturnClass(method.getReturnType()))
+				{
+					_log.log(Level.WARNING, getClass().getSimpleName() + ": Non properly defined annotation listener on method: " + method.getName() + " expected return type to be one of: " + Arrays.toString(eventType.getReturnClasses()) + " but found: " + method.getReturnType().getSimpleName());
+					continue;
+				}
+				
+				// Clear the list
+				npcIds.clear();
+				
+				// Scan for possible Npc ID filters
+				for (Annotation annotation : method.getAnnotations())
+				{
+					if (annotation instanceof Npc)
+					{
+						final Npc npc = (Npc) annotation;
+						for (int id : npc.value())
+						{
+							npcIds.add(id);
+						}
+					}
+					else if (annotation instanceof Npcs)
+					{
+						final Npcs npcs = (Npcs) annotation;
+						for (Npc npc : npcs.value())
+						{
+							for (int id : npc.value())
+							{
+								npcIds.add(id);
+							}
+						}
+					}
+				}
+				
+				if (!npcIds.isEmpty())
+				{
+					if (!_registeredIds.containsKey(ListenerRegisterType.NPC))
+					{
+						_registeredIds.put(ListenerRegisterType.NPC, new FastList<Integer>().shared());
+					}
+					_registeredIds.get(ListenerRegisterType.NPC).addAll(npcIds);
+				}
+				
+				registerAnnotation(method, eventType, ListenerRegisterType.NPC, npcIds);
+			}
+		}
+	}
+	
+	/**
+	 * Unloads all listeners registered by this class.
+	 */
+	@Override
+	public boolean unload()
+	{
+		_listeners.forEach(AbstractEventListener::unregisterMe);
+		_listeners.clear();
+		return true;
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides delayed (Depending on {@link com.l2jserver.gameserver.model.actor.L2Attackable#getOnKillDelay()}) callback operation when L2Attackable dies from a player.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setAttackableKillId(Consumer<OnAttackableKill> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ATTACKABLE_KILL, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides delayed (Depending on {@link com.l2jserver.gameserver.model.actor.L2Attackable#getOnKillDelay()}) callback operation when L2Attackable dies from a player.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setAttackableKillId(Consumer<OnAttackableKill> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ATTACKABLE_KILL, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when L2Attackable dies from a player with return type.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> addCreatureKillId(Function<OnCreatureKill, ? extends AbstractEventReturn> callback, int... npcIds)
+	{
+		return registerFunction(callback, EventType.ON_CREATURE_KILL, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when L2Attackable dies from a player.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCreatureKillId(Consumer<OnCreatureKill> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_CREATURE_KILL, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Attackable} dies from a {@link L2PcInstance}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCreatureKillId(Consumer<OnCreatureKill> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_CREATURE_KILL, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc} for first time.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcFirstTalkId(Consumer<OnNpcFirstTalk> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_FIRST_TALK, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc} for first time.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcFirstTalkId(Consumer<OnNpcFirstTalk> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_FIRST_TALK, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc}.
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcTalkId(Collection<Integer> npcIds)
+	{
+		return registerDummy(EventType.ON_NPC_TALK, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc}.
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcTalkId(int... npcIds)
+	{
+		return registerDummy(EventType.ON_NPC_TALK, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc} and must receive quest state.
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcQuestStartId(int... npcIds)
+	{
+		return registerDummy(EventType.ON_NPC_QUEST_START, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc} and must receive quest state.
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcQuestStartId(Collection<Integer> npcIds)
+	{
+		return registerDummy(EventType.ON_NPC_QUEST_START, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when L2Npc sees skill from a player.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcSkillSeeId(Consumer<OnNpcSkillSee> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_SKILL_SEE, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when L2Npc sees skill from a player.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcSkillSeeId(Consumer<OnNpcSkillSee> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_SKILL_SEE, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when L2Npc casts skill on a player.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcSkillFinishedId(Consumer<OnNpcSkillFinished> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_SKILL_FINISHED, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when L2Npc casts skill on a player.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcSkillFinishedId(Consumer<OnNpcSkillFinished> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_SKILL_FINISHED, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when L2Npc is spawned.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcSpawnId(Consumer<OnNpcSpawn> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_SPAWN, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when L2Npc is spawned.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcSpawnId(Consumer<OnNpcSpawn> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_SPAWN, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} receives event from another {@link L2Npc}
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcEventReceivedId(Consumer<OnNpcEventReceived> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_EVENT_RECEIVED, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} receives event from another {@link L2Npc}
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcEventReceivedId(Consumer<OnNpcEventReceived> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_EVENT_RECEIVED, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} finishes to move.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcMoveFinishedId(Consumer<OnNpcMoveFinished> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_MOVE_FINISHED, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} finishes to move.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcMoveFinishedId(Consumer<OnNpcMoveFinished> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_MOVE_FINISHED, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} arrive to node of its route
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcMoveNodeArrivedId(Consumer<OnNpcMoveNodeArrived> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_MOVE_NODE_ARRIVED, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} arrive to node of its route
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcMoveNodeArrivedId(Consumer<OnNpcMoveNodeArrived> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_MOVE_NODE_ARRIVED, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} finishes to move on its route.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcMoveRouteFinishedId(Consumer<OnNpcMoveRouteFinished> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_MOVE_ROUTE_FINISHED, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} finishes to move on its route.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcMoveRouteFinishedId(Consumer<OnNpcMoveRouteFinished> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_MOVE_ROUTE_FINISHED, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcHateId(Consumer<OnAttackableHate> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_HATE, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcHateId(Consumer<OnAttackableHate> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_HATE, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> addNpcHateId(Function<OnAttackableHate, TerminateReturn> callback, int... npcIds)
+	{
+		return registerFunction(callback, EventType.ON_NPC_HATE, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> addNpcHateId(Function<OnAttackableHate, TerminateReturn> callback, Collection<Integer> npcIds)
+	{
+		return registerFunction(callback, EventType.ON_NPC_HATE, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcCanBeSeenId(Consumer<OnNpcCanBeSeen> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_CAN_BE_SEEN, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcCanBeSeenId(Consumer<OnNpcCanBeSeen> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_CAN_BE_SEEN, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcCanBeSeenId(Function<OnNpcCanBeSeen, TerminateReturn> callback, int... npcIds)
+	{
+		return registerFunction(callback, EventType.ON_NPC_CAN_BE_SEEN, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcCanBeSeenId(Function<OnNpcCanBeSeen, TerminateReturn> callback, Collection<Integer> npcIds)
+	{
+		return registerFunction(callback, EventType.ON_NPC_CAN_BE_SEEN, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} sees another creature.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Npc} sees another creature.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when L2Attackable is under attack to other clan mates.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setAttackableFactionIdId(Consumer<OnAttackableFactionCall> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ATTACKABLE_FACTION_CALL, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when L2Attackable is under attack to other clan mates.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setAttackableFactionIdId(Consumer<OnAttackableFactionCall> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ATTACKABLE_FACTION_CALL, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when L2Attackable is attacked from a player.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setAttackableAttackId(Consumer<OnAttackableAttack> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ATTACKABLE_ATTACK, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when L2Attackable is attacked from a player.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setAttackableAttackId(Consumer<OnAttackableAttack> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ATTACKABLE_ATTACK, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} enters in {@link L2Attackable}'s aggressive range.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setAttackableAggroRangeEnterId(Consumer<OnAttackableAggroRangeEnter> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ATTACKABLE_AGGRO_RANGE_ENTER, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} enters in {@link L2Attackable}'s aggressive range.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setAttackableAggroRangeEnterId(Consumer<OnAttackableAggroRangeEnter> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ATTACKABLE_AGGRO_RANGE_ENTER, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} learn's a {@link Skill}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setPlayerSkillLearnId(Consumer<OnPlayerSkillLearn> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_PLAYER_SKILL_LEARN, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} learn's a {@link Skill}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setPlayerSkillLearnId(Consumer<OnPlayerSkillLearn> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_PLAYER_SKILL_LEARN, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} summons a servitor or a pet
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setPlayerSummonSpawnId(Consumer<OnPlayerSummonSpawn> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_PLAYER_SUMMON_SPAWN, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} summons a servitor or a pet
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setPlayerSummonSpawnId(Consumer<OnPlayerSummonSpawn> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_PLAYER_SUMMON_SPAWN, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} summons a servitor or a pet
+	 * @param callback
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setPlayerLoginId(Consumer<OnPlayerLogin> callback)
+	{
+		return registerConsumer(callback, EventType.ON_PLAYER_LOGIN, ListenerRegisterType.GLOBAL);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} summons a servitor or a pet
+	 * @param callback
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setPlayerLogoutId(Consumer<OnPlayerLogout> callback)
+	{
+		return registerConsumer(callback, EventType.ON_PLAYER_LOGOUT, ListenerRegisterType.GLOBAL);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.L2Character} Enters on a {@link L2ZoneType}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCreatureZoneEnterId(Consumer<OnCreatureZoneEnter> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_CREATURE_ZONE_ENTER, ListenerRegisterType.ZONE, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.L2Character} Enters on a {@link L2ZoneType}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCreatureZoneEnterId(Consumer<OnCreatureZoneEnter> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_CREATURE_ZONE_ENTER, ListenerRegisterType.ZONE, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.L2Character} Exits on a {@link L2ZoneType}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCreatureZoneExitId(Consumer<OnCreatureZoneExit> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_CREATURE_ZONE_EXIT, ListenerRegisterType.ZONE, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.L2Character} Exits on a {@link L2ZoneType}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCreatureZoneExitId(Consumer<OnCreatureZoneExit> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_CREATURE_ZONE_EXIT, ListenerRegisterType.ZONE, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.instance.L2TrapInstance} acts.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setTrapActionId(Consumer<OnTrapAction> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_TRAP_ACTION, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.instance.L2TrapInstance} acts.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setTrapActionId(Consumer<OnTrapAction> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_TRAP_ACTION, ListenerRegisterType.NPC, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2Item} receives an event from {@link L2PcInstance}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setItemBypassEvenId(Consumer<OnItemBypassEvent> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ITEM_BYPASS_EVENT, ListenerRegisterType.ITEM, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2Item} receives an event from {@link L2PcInstance}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setItemBypassEvenId(Consumer<OnItemBypassEvent> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ITEM_BYPASS_EVENT, ListenerRegisterType.ITEM, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Item}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setItemTalkId(Consumer<OnItemTalk> callback, int... npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ITEM_TALK, ListenerRegisterType.ITEM, npcIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Item}.
+	 * @param callback
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setItemTalkId(Consumer<OnItemTalk> callback, Collection<Integer> npcIds)
+	{
+		return registerConsumer(callback, EventType.ON_ITEM_TALK, ListenerRegisterType.ITEM, npcIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when Olympiad match finishes.
+	 * @param callback
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setOlympiadMatchResult(Consumer<OnOlympiadMatchResult> callback)
+	{
+		return registerConsumer(callback, EventType.ON_OLYMPIAD_MATCH_RESULT, ListenerRegisterType.OLYMPIAD);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when castle siege begins
+	 * @param callback
+	 * @param castleIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCastleSiegeStartId(Consumer<OnCastleSiegeStart> callback, int... castleIds)
+	{
+		return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_START, ListenerRegisterType.CASTLE, castleIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when castle siege begins
+	 * @param callback
+	 * @param castleIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCastleSiegeStartId(Consumer<OnCastleSiegeStart> callback, Collection<Integer> castleIds)
+	{
+		return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_START, ListenerRegisterType.CASTLE, castleIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when Castle owner has changed during a siege
+	 * @param callback
+	 * @param castleIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCastleSiegeOwnerChangeId(Consumer<OnCastleSiegeOwnerChange> callback, int... castleIds)
+	{
+		return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_OWNER_CHANGE, ListenerRegisterType.CASTLE, castleIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when Castle owner has changed during a siege
+	 * @param callback
+	 * @param castleIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCastleSiegeOwnerChangeId(Consumer<OnCastleSiegeOwnerChange> callback, Collection<Integer> castleIds)
+	{
+		return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_OWNER_CHANGE, ListenerRegisterType.CASTLE, castleIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when castle siege ends
+	 * @param callback
+	 * @param castleIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCastleSiegeFinishId(Consumer<OnCastleSiegeFinish> callback, int... castleIds)
+	{
+		return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_FINISH, ListenerRegisterType.CASTLE, castleIds);
+	}
+	
+	/**
+	 * Provides instant callback operation when castle siege ends
+	 * @param callback
+	 * @param castleIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setCastleSiegeFinishId(Consumer<OnCastleSiegeFinish> callback, Collection<Integer> castleIds)
+	{
+		return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_FINISH, ListenerRegisterType.CASTLE, castleIds);
+	}
+	
+	// ---------------------------------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Provides instant callback operation when player's profession has change
+	 * @param callback
+	 * @return
+	 */
+	protected final List<AbstractEventListener> setPlayerProfessionChangeId(Consumer<OnPlayerProfessionChange> callback)
+	{
+		return registerConsumer(callback, EventType.ON_PLAYER_PROFESSION_CHANGE, ListenerRegisterType.GLOBAL);
+	}
+	
+	// --------------------------------------------------------------------------------------------------
+	// --------------------------------Default listener register methods---------------------------------
+	// --------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Method that registers Function type of listeners (Listeners that need parameters but doesn't return objects)
+	 * @param callback
+	 * @param type
+	 * @param registerType
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerConsumer(Consumer<? extends IBaseEvent> callback, EventType type, ListenerRegisterType registerType, int... npcIds)
+	{
+		return registerListener((container) -> new ConsumerEventListener(container, type, callback, this), registerType, npcIds);
+	}
+	
+	/**
+	 * Method that registers Function type of listeners (Listeners that need parameters but doesn't return objects)
+	 * @param callback
+	 * @param type
+	 * @param registerType
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerConsumer(Consumer<? extends IBaseEvent> callback, EventType type, ListenerRegisterType registerType, Collection<Integer> npcIds)
+	{
+		return registerListener((container) -> new ConsumerEventListener(container, type, callback, this), registerType, npcIds);
+	}
+	
+	/**
+	 * Method that registers Function type of listeners (Listeners that need parameters and return objects)
+	 * @param callback
+	 * @param type
+	 * @param registerType
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerFunction(Function<? extends IBaseEvent, ? extends AbstractEventReturn> callback, EventType type, ListenerRegisterType registerType, int... npcIds)
+	{
+		return registerListener((container) -> new FunctionEventListener(container, type, callback, this), registerType, npcIds);
+	}
+	
+	/**
+	 * Method that registers Function type of listeners (Listeners that need parameters and return objects)
+	 * @param callback
+	 * @param type
+	 * @param registerType
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerFunction(Function<? extends IBaseEvent, ? extends AbstractEventReturn> callback, EventType type, ListenerRegisterType registerType, Collection<Integer> npcIds)
+	{
+		return registerListener((container) -> new FunctionEventListener(container, type, callback, this), registerType, npcIds);
+	}
+	
+	/**
+	 * Method that registers runnable type of listeners (Listeners that doesn't needs parameters or return objects)
+	 * @param callback
+	 * @param type
+	 * @param registerType
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerRunnable(Runnable callback, EventType type, ListenerRegisterType registerType, int... npcIds)
+	{
+		return registerListener((container) -> new RunnableEventListener(container, type, callback, this), registerType, npcIds);
+	}
+	
+	/**
+	 * Method that registers runnable type of listeners (Listeners that doesn't needs parameters or return objects)
+	 * @param callback
+	 * @param type
+	 * @param registerType
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerRunnable(Runnable callback, EventType type, ListenerRegisterType registerType, Collection<Integer> npcIds)
+	{
+		return registerListener((container) -> new RunnableEventListener(container, type, callback, this), registerType, npcIds);
+	}
+	
+	/**
+	 * Method that registers runnable type of listeners (Listeners that doesn't needs parameters or return objects)
+	 * @param callback
+	 * @param type
+	 * @param registerType
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerAnnotation(Method callback, EventType type, ListenerRegisterType registerType, int... npcIds)
+	{
+		return registerListener((container) -> new AnnotationEventListener(container, type, callback, this), registerType, npcIds);
+	}
+	
+	/**
+	 * Method that registers runnable type of listeners (Listeners that doesn't needs parameters or return objects)
+	 * @param callback
+	 * @param type
+	 * @param registerType
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerAnnotation(Method callback, EventType type, ListenerRegisterType registerType, Collection<Integer> npcIds)
+	{
+		return registerListener((container) -> new AnnotationEventListener(container, type, callback, this), registerType, npcIds);
+	}
+	
+	/**
+	 * Method that registers dummy type of listeners (Listeners doesn't gets notification but just used to check if their type present or not)
+	 * @param type
+	 * @param registerType
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerDummy(EventType type, ListenerRegisterType registerType, int... npcIds)
+	{
+		return registerListener((container) -> new DummyEventListener(container, type, this), registerType, npcIds);
+	}
+	
+	/**
+	 * Method that registers dummy type of listeners (Listeners doesn't gets notification but just used to check if their type present or not)
+	 * @param type
+	 * @param registerType
+	 * @param npcIds
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerDummy(EventType type, ListenerRegisterType registerType, Collection<Integer> npcIds)
+	{
+		return registerListener((container) -> new DummyEventListener(container, type, this), registerType, npcIds);
+	}
+	
+	// --------------------------------------------------------------------------------------------------
+	// --------------------------------------Register methods--------------------------------------------
+	// --------------------------------------------------------------------------------------------------
+	
+	/**
+	 * Generic listener register method
+	 * @param action
+	 * @param registerType
+	 * @param ids
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerListener(Function<ListenersContainer, AbstractEventListener> action, ListenerRegisterType registerType, int... ids)
+	{
+		final List<AbstractEventListener> listeners = new ArrayList<>(ids.length > 0 ? ids.length : 1);
+		if (ids.length > 0)
+		{
+			for (int id : ids)
+			{
+				switch (registerType)
+				{
+					case NPC:
+					{
+						final L2NpcTemplate template = NpcData.getInstance().getTemplate(id);
+						if (template != null)
+						{
+							listeners.add(template.addListener(action.apply(template)));
+						}
+						break;
+					}
+					case ZONE:
+					{
+						final L2ZoneType template = ZoneManager.getInstance().getZoneById(id);
+						if (template != null)
+						{
+							listeners.add(template.addListener(action.apply(template)));
+						}
+						break;
+					}
+					case ITEM:
+					{
+						final L2Item template = ItemTable.getInstance().getTemplate(id);
+						if (template != null)
+						{
+							listeners.add(template.addListener(action.apply(template)));
+						}
+						break;
+					}
+					case CASTLE:
+					{
+						final Castle template = CastleManager.getInstance().getCastleById(id);
+						if (template != null)
+						{
+							listeners.add(template.addListener(action.apply(template)));
+						}
+						break;
+					}
+					case FORTRESS:
+					{
+						final Fort template = FortManager.getInstance().getFortById(id);
+						if (template != null)
+						{
+							listeners.add(template.addListener(action.apply(template)));
+						}
+						break;
+					}
+					default:
+					{
+						_log.log(Level.WARNING, getClass().getSimpleName() + ": Unhandled register type: " + registerType);
+					}
+				}
+				
+				if (!_registeredIds.containsKey(registerType))
+				{
+					_registeredIds.put(registerType, new FastList<Integer>().shared());
+				}
+				_registeredIds.get(registerType).add(id);
+			}
+		}
+		else
+		{
+			switch (registerType)
+			{
+				case OLYMPIAD:
+				{
+					final Olympiad template = Olympiad.getInstance();
+					listeners.add(template.addListener(action.apply(template)));
+					break;
+				}
+				default: // Global Listener
+				{
+					final EventDispatcher template = EventDispatcher.getInstance();
+					listeners.add(template.addListener(action.apply(template)));
+				}
+			}
+		}
+		
+		_listeners.addAll(listeners);
+		return listeners;
+	}
+	
+	/**
+	 * Generic listener register method
+	 * @param action
+	 * @param registerType
+	 * @param ids
+	 * @return
+	 */
+	protected final List<AbstractEventListener> registerListener(Function<ListenersContainer, AbstractEventListener> action, ListenerRegisterType registerType, Collection<Integer> ids)
+	{
+		final List<AbstractEventListener> listeners = new ArrayList<>(!ids.isEmpty() ? ids.size() : 1);
+		if (!ids.isEmpty())
+		{
+			for (int id : ids)
+			{
+				switch (registerType)
+				{
+					case NPC:
+					{
+						final L2NpcTemplate template = NpcData.getInstance().getTemplate(id);
+						if (template != null)
+						{
+							listeners.add(template.addListener(action.apply(template)));
+						}
+						break;
+					}
+					case ZONE:
+					{
+						final L2ZoneType template = ZoneManager.getInstance().getZoneById(id);
+						if (template != null)
+						{
+							listeners.add(template.addListener(action.apply(template)));
+						}
+						break;
+					}
+					case ITEM:
+					{
+						final L2Item template = ItemTable.getInstance().getTemplate(id);
+						if (template != null)
+						{
+							listeners.add(template.addListener(action.apply(template)));
+						}
+						break;
+					}
+					case CASTLE:
+					{
+						final Castle template = CastleManager.getInstance().getCastleById(id);
+						if (template != null)
+						{
+							listeners.add(template.addListener(action.apply(template)));
+						}
+						break;
+					}
+					case FORTRESS:
+					{
+						final Fort template = FortManager.getInstance().getFortById(id);
+						if (template != null)
+						{
+							listeners.add(template.addListener(action.apply(template)));
+						}
+						break;
+					}
+					default:
+					{
+						_log.log(Level.WARNING, getClass().getSimpleName() + ": Unhandled register type: " + registerType);
+					}
+				}
+			}
+			if (!_registeredIds.containsKey(registerType))
+			{
+				_registeredIds.put(registerType, new FastList<Integer>().shared());
+			}
+			_registeredIds.get(registerType).addAll(ids);
+		}
+		else
+		{
+			switch (registerType)
+			{
+				case OLYMPIAD:
+				{
+					final Olympiad template = Olympiad.getInstance();
+					listeners.add(template.addListener(action.apply(template)));
+					break;
+				}
+				default: // Global Listener
+				{
+					final EventDispatcher template = EventDispatcher.getInstance();
+					listeners.add(template.addListener(action.apply(template)));
+				}
+			}
+		}
+		_listeners.addAll(listeners);
+		return listeners;
+	}
+	
+	public List<Integer> getRegisteredIds(ListenerRegisterType type)
+	{
+		return _registeredIds.containsKey(type) ? _registeredIds.get(type) : Collections.emptyList();
+	}
+	
+	public List<AbstractEventListener> getListeners()
+	{
+		return _listeners;
+	}
+	
+	/**
+	 * -------------------------------------------------------------------------------------------------------
+	 */
+	
+	/**
+	 * Show an on screen message to the player.
+	 * @param player the player to display the message to
+	 * @param text the message to display
+	 * @param time the duration of the message in milliseconds
+	 */
+	public static void showOnScreenMsg(L2PcInstance player, String text, int time)
+	{
+		player.sendPacket(new ExShowScreenMessage(text, time));
+	}
+	
+	/**
+	 * Show an on screen message to the player.
+	 * @param player the player to display the message to
+	 * @param npcString the NPC string to display
+	 * @param position the position of the message on the screen
+	 * @param time the duration of the message in milliseconds
+	 * @param params values of parameters to replace in the NPC String (like S1, C1 etc.)
+	 */
+	public static void showOnScreenMsg(L2PcInstance player, NpcStringId npcString, int position, int time, String... params)
+	{
+		player.sendPacket(new ExShowScreenMessage(npcString, position, time, params));
+	}
+	
+	/**
+	 * Show an on screen message to the player.
+	 * @param player the player to display the message to
+	 * @param systemMsg the system message to display
+	 * @param position the position of the message on the screen
+	 * @param time the duration of the message in milliseconds
+	 * @param params values of parameters to replace in the system message (like S1, C1 etc.)
+	 */
+	public static void showOnScreenMsg(L2PcInstance player, SystemMessageId systemMsg, int position, int time, String... params)
+	{
+		player.sendPacket(new ExShowScreenMessage(systemMsg, position, time, params));
+	}
+	
+	/**
+	 * Add a temporary spawn of the specified NPC.
+	 * @param npcId the ID of the NPC to spawn
+	 * @param pos the object containing the spawn location coordinates
+	 * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
+	 * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
+	 * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
+	 */
+	public static L2Npc addSpawn(int npcId, IPositionable pos)
+	{
+		return addSpawn(npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), false, 0, false, 0);
+	}
+	
+	/**
+	 * Add a temporary spawn of the specified NPC.
+	 * @param npcId the ID of the NPC to spawn
+	 * @param pos the object containing the spawn location coordinates
+	 * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
+	 * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
+	 * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
+	 * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
+	 */
+	public static L2Npc addSpawn(int npcId, IPositionable pos, boolean isSummonSpawn)
+	{
+		return addSpawn(npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), false, 0, isSummonSpawn, 0);
+	}
+	
+	/**
+	 * Add a temporary spawn of the specified NPC.
+	 * @param npcId the ID of the NPC to spawn
+	 * @param pos the object containing the spawn location coordinates
+	 * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
+	 * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
+	 * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
+	 * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
+	 * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
+	 */
+	public static L2Npc addSpawn(int npcId, IPositionable pos, boolean randomOffset, long despawnDelay)
+	{
+		return addSpawn(npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), randomOffset, despawnDelay, false, 0);
+	}
+	
+	/**
+	 * Add a temporary spawn of the specified NPC.
+	 * @param npcId the ID of the NPC to spawn
+	 * @param pos the object containing the spawn location coordinates
+	 * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
+	 * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
+	 * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
+	 * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
+	 * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
+	 * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
+	 */
+	public static L2Npc addSpawn(int npcId, IPositionable pos, boolean randomOffset, long despawnDelay, boolean isSummonSpawn)
+	{
+		return addSpawn(npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), randomOffset, despawnDelay, isSummonSpawn, 0);
+	}
+	
+	/**
+	 * Add a temporary spawn of the specified NPC.
+	 * @param npcId the ID of the NPC to spawn
+	 * @param pos the object containing the spawn location coordinates
+	 * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
+	 * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
+	 * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
+	 * @param instanceId the ID of the instance to spawn the NPC in (0 - the open world)
+	 * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
+	 * @see #addSpawn(int, IPositionable)
+	 * @see #addSpawn(int, IPositionable, boolean)
+	 * @see #addSpawn(int, IPositionable, boolean, long)
+	 * @see #addSpawn(int, IPositionable, boolean, long, boolean)
+	 * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
+	 */
+	public static L2Npc addSpawn(int npcId, IPositionable pos, boolean randomOffset, long despawnDelay, boolean isSummonSpawn, int instanceId)
+	{
+		return addSpawn(npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), randomOffset, despawnDelay, isSummonSpawn, instanceId);
+	}
+	
+	/**
+	 * Add a temporary spawn of the specified NPC.
+	 * @param npcId the ID of the NPC to spawn
+	 * @param x the X coordinate of the spawn location
+	 * @param y the Y coordinate of the spawn location
+	 * @param z the Z coordinate (height) of the spawn location
+	 * @param heading the heading of the NPC
+	 * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
+	 * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
+	 * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
+	 * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
+	 * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
+	 */
+	public static L2Npc addSpawn(int npcId, int x, int y, int z, int heading, boolean randomOffset, long despawnDelay)
+	{
+		return addSpawn(npcId, x, y, z, heading, randomOffset, despawnDelay, false, 0);
+	}
+	
+	/**
+	 * Add a temporary spawn of the specified NPC.
+	 * @param npcId the ID of the NPC to spawn
+	 * @param x the X coordinate of the spawn location
+	 * @param y the Y coordinate of the spawn location
+	 * @param z the Z coordinate (height) of the spawn location
+	 * @param heading the heading of the NPC
+	 * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
+	 * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
+	 * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
+	 * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
+	 * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
+	 * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
+	 */
+	public static L2Npc addSpawn(int npcId, int x, int y, int z, int heading, boolean randomOffset, long despawnDelay, boolean isSummonSpawn)
+	{
+		return addSpawn(npcId, x, y, z, heading, randomOffset, despawnDelay, isSummonSpawn, 0);
+	}
+	
+	/**
+	 * Add a temporary spawn of the specified NPC.
+	 * @param npcId the ID of the NPC to spawn
+	 * @param x the X coordinate of the spawn location
+	 * @param y the Y coordinate of the spawn location
+	 * @param z the Z coordinate (height) of the spawn location
+	 * @param heading the heading of the NPC
+	 * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
+	 * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
+	 * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
+	 * @param instanceId the ID of the instance to spawn the NPC in (0 - the open world)
+	 * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
+	 * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
+	 * @see #addSpawn(int, int, int, int, int, boolean, long)
+	 * @see #addSpawn(int, int, int, int, int, boolean, long, boolean)
+	 */
+	public static L2Npc addSpawn(int npcId, int x, int y, int z, int heading, boolean randomOffset, long despawnDelay, boolean isSummonSpawn, int instanceId)
+	{
+		try
+		{
+			L2NpcTemplate template = NpcData.getInstance().getTemplate(npcId);
+			if (template == null)
+			{
+				_log.log(Level.SEVERE, "addSpawn(): no NPC template found for NPC #" + npcId + "!");
+			}
+			else
+			{
+				if ((x == 0) && (y == 0))
+				{
+					_log.log(Level.SEVERE, "addSpawn(): invalid spawn coordinates for NPC #" + npcId + "!");
+					return null;
+				}
+				if (randomOffset)
+				{
+					int offset = Rnd.get(50, 100);
+					if (Rnd.nextBoolean())
+					{
+						offset *= -1;
+					}
+					x += offset;
+					
+					offset = Rnd.get(50, 100);
+					if (Rnd.nextBoolean())
+					{
+						offset *= -1;
+					}
+					y += offset;
+				}
+				L2Spawn spawn = new L2Spawn(template);
+				spawn.setInstanceId(instanceId);
+				spawn.setHeading(heading);
+				spawn.setX(x);
+				spawn.setY(y);
+				spawn.setZ(z);
+				spawn.stopRespawn();
+				L2Npc result = spawn.spawnOne(isSummonSpawn);
+				
+				if (despawnDelay > 0)
+				{
+					result.scheduleDespawn(despawnDelay);
+				}
+				
+				return result;
+			}
+		}
+		catch (Exception e1)
+		{
+			_log.warning("Could not spawn NPC #" + npcId + "; error: " + e1.getMessage());
+		}
+		
+		return null;
+	}
+	
+	/**
+	 * @param trapId
+	 * @param x
+	 * @param y
+	 * @param z
+	 * @param heading
+	 * @param skill
+	 * @param instanceId
+	 * @return
+	 */
+	public L2TrapInstance addTrap(int trapId, int x, int y, int z, int heading, Skill skill, int instanceId)
+	{
+		final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(trapId);
+		L2TrapInstance trap = new L2TrapInstance(IdFactory.getInstance().getNextId(), npcTemplate, instanceId, -1);
+		trap.setCurrentHp(trap.getMaxHp());
+		trap.setCurrentMp(trap.getMaxMp());
+		trap.setIsInvul(true);
+		trap.setHeading(heading);
+		trap.spawnMe(x, y, z);
+		return trap;
+	}
+	
+	/**
+	 * @param master
+	 * @param minionId
+	 * @return
+	 */
+	public L2Npc addMinion(L2MonsterInstance master, int minionId)
+	{
+		return MinionList.spawnMinion(master, minionId);
+	}
+	
+	/**
+	 * Get the amount of an item in player's inventory.
+	 * @param player the player whose inventory to check
+	 * @param itemId the ID of the item whose amount to get
+	 * @return the amount of the specified item in player's inventory
+	 */
+	public static long getQuestItemsCount(L2PcInstance player, int itemId)
+	{
+		return player.getInventory().getInventoryItemCount(itemId, -1);
+	}
+	
+	/**
+	 * Get the total amount of all specified items in player's inventory.
+	 * @param player the player whose inventory to check
+	 * @param itemIds a list of IDs of items whose amount to get
+	 * @return the summary amount of all listed items in player's inventory
+	 */
+	public long getQuestItemsCount(L2PcInstance player, int... itemIds)
+	{
+		long count = 0;
+		for (L2ItemInstance item : player.getInventory().getItems())
+		{
+			if (item == null)
+			{
+				continue;
+			}
+			
+			for (int itemId : itemIds)
+			{
+				if (item.getId() == itemId)
+				{
+					if ((count + item.getCount()) > Long.MAX_VALUE)
+					{
+						return Long.MAX_VALUE;
+					}
+					count += item.getCount();
+				}
+			}
+		}
+		return count;
+	}
+	
+	/**
+	 * Check if the player has the specified item in his inventory.
+	 * @param player the player whose inventory to check for the specified item
+	 * @param item the {@link ItemHolder} object containing the ID and count of the item to check
+	 * @return {@code true} if the player has the required count of the item
+	 */
+	protected static boolean hasItem(L2PcInstance player, ItemHolder item)
+	{
+		return hasItem(player, item, true);
+	}
+	
+	/**
+	 * Check if the player has the required count of the specified item in his inventory.
+	 * @param player the player whose inventory to check for the specified item
+	 * @param item the {@link ItemHolder} object containing the ID and count of the item to check
+	 * @param checkCount if {@code true}, check if each item is at least of the count specified in the ItemHolder,<br>
+	 *            otherwise check only if the player has the item at all
+	 * @return {@code true} if the player has the item
+	 */
+	protected static boolean hasItem(L2PcInstance player, ItemHolder item, boolean checkCount)
+	{
+		if (item == null)
+		{
+			return false;
+		}
+		if (checkCount)
+		{
+			return (getQuestItemsCount(player, item.getId()) >= item.getCount());
+		}
+		return hasQuestItems(player, item.getId());
+	}
+	
+	/**
+	 * Check if the player has all the specified items in his inventory and, if necessary, if their count is also as required.
+	 * @param player the player whose inventory to check for the specified item
+	 * @param checkCount if {@code true}, check if each item is at least of the count specified in the ItemHolder,<br>
+	 *            otherwise check only if the player has the item at all
+	 * @param itemList a list of {@link ItemHolder} objects containing the IDs of the items to check
+	 * @return {@code true} if the player has all the items from the list
+	 */
+	protected static boolean hasAllItems(L2PcInstance player, boolean checkCount, ItemHolder... itemList)
+	{
+		if ((itemList == null) || (itemList.length == 0))
+		{
+			return false;
+		}
+		for (ItemHolder item : itemList)
+		{
+			if (!hasItem(player, item, checkCount))
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+	
+	/**
+	 * Check for an item in player's inventory.
+	 * @param player the player whose inventory to check for quest items
+	 * @param itemId the ID of the item to check for
+	 * @return {@code true} if the item exists in player's inventory, {@code false} otherwise
+	 */
+	public static boolean hasQuestItems(L2PcInstance player, int itemId)
+	{
+		return (player.getInventory().getItemByItemId(itemId) != null);
+	}
+	
+	/**
+	 * Check for multiple items in player's inventory.
+	 * @param player the player whose inventory to check for quest items
+	 * @param itemIds a list of item IDs to check for
+	 * @return {@code true} if all items exist in player's inventory, {@code false} otherwise
+	 */
+	public static boolean hasQuestItems(L2PcInstance player, int... itemIds)
+	{
+		if ((itemIds == null) || (itemIds.length == 0))
+		{
+			return false;
+		}
+		final PcInventory inv = player.getInventory();
+		for (int itemId : itemIds)
+		{
+			if (inv.getItemByItemId(itemId) == null)
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+	
+	/**
+	 * Check for multiple items in player's inventory.
+	 * @param player the player whose inventory to check for quest items
+	 * @param itemIds a list of item IDs to check for
+	 * @return {@code true} if at least one items exist in player's inventory, {@code false} otherwise
+	 */
+	public boolean hasAtLeastOneQuestItem(L2PcInstance player, int... itemIds)
+	{
+		final PcInventory inv = player.getInventory();
+		for (int itemId : itemIds)
+		{
+			if (inv.getItemByItemId(itemId) != null)
+			{
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * Get the enchantment level of an item in player's inventory.
+	 * @param player the player whose item to check
+	 * @param itemId the ID of the item whose enchantment level to get
+	 * @return the enchantment level of the item or 0 if the item was not found
+	 */
+	public static int getEnchantLevel(L2PcInstance player, int itemId)
+	{
+		final L2ItemInstance enchantedItem = player.getInventory().getItemByItemId(itemId);
+		if (enchantedItem == null)
+		{
+			return 0;
+		}
+		return enchantedItem.getEnchantLevel();
+	}
+	
+	/**
+	 * Give Adena to the player.
+	 * @param player the player to whom to give the Adena
+	 * @param count the amount of Adena to give
+	 * @param applyRates if {@code true} quest rates will be applied to the amount
+	 */
+	public void giveAdena(L2PcInstance player, long count, boolean applyRates)
+	{
+		if (applyRates)
+		{
+			rewardItems(player, Inventory.ADENA_ID, count);
+		}
+		else
+		{
+			giveItems(player, Inventory.ADENA_ID, count);
+		}
+	}
+	
+	/**
+	 * Give a reward to player using multipliers.
+	 * @param player the player to whom to give the item
+	 * @param holder
+	 */
+	public static void rewardItems(L2PcInstance player, ItemHolder holder)
+	{
+		rewardItems(player, holder.getId(), holder.getCount());
+	}
+	
+	/**
+	 * Give a reward to player using multipliers.
+	 * @param player the player to whom to give the item
+	 * @param itemId the ID of the item to give
+	 * @param count the amount of items to give
+	 */
+	public static void rewardItems(L2PcInstance player, int itemId, long count)
+	{
+		if (count <= 0)
+		{
+			return;
+		}
+		
+		final L2ItemInstance _tmpItem = ItemTable.getInstance().createDummyItem(itemId);
+		if (_tmpItem == null)
+		{
+			return;
+		}
+		
+		try
+		{
+			if (itemId == Inventory.ADENA_ID)
+			{
+				count *= Config.RATE_QUEST_REWARD_ADENA;
+			}
+			else if (Config.RATE_QUEST_REWARD_USE_MULTIPLIERS)
+			{
+				if (_tmpItem.isEtcItem())
+				{
+					switch (_tmpItem.getEtcItem().getItemType())
+					{
+						case POTION:
+							count *= Config.RATE_QUEST_REWARD_POTION;
+							break;
+						case SCRL_ENCHANT_WP:
+						case SCRL_ENCHANT_AM:
+						case SCROLL:
+							count *= Config.RATE_QUEST_REWARD_SCROLL;
+							break;
+						case RECIPE:
+							count *= Config.RATE_QUEST_REWARD_RECIPE;
+							break;
+						case MATERIAL:
+							count *= Config.RATE_QUEST_REWARD_MATERIAL;
+							break;
+						default:
+							count *= Config.RATE_QUEST_REWARD;
+					}
+				}
+			}
+			else
+			{
+				count *= Config.RATE_QUEST_REWARD;
+			}
+		}
+		catch (Exception e)
+		{
+			count = Long.MAX_VALUE;
+		}
+		
+		// Add items to player's inventory
+		L2ItemInstance item = player.getInventory().addItem("Quest", itemId, count, player, player.getTarget());
+		if (item == null)
+		{
+			return;
+		}
+		
+		sendItemGetMessage(player, item, count);
+	}
+	
+	/**
+	 * Send the system message and the status update packets to the player.
+	 * @param player the player that has got the item
+	 * @param item the item obtain by the player
+	 * @param count the item count
+	 */
+	private static void sendItemGetMessage(L2PcInstance player, L2ItemInstance item, long count)
+	{
+		// If item for reward is gold, send message of gold reward to client
+		if (item.getId() == Inventory.ADENA_ID)
+		{
+			SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S1_ADENA);
+			smsg.addLong(count);
+			player.sendPacket(smsg);
+		}
+		// Otherwise, send message of object reward to client
+		else
+		{
+			if (count > 1)
+			{
+				SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+				smsg.addItemName(item);
+				smsg.addLong(count);
+				player.sendPacket(smsg);
+			}
+			else
+			{
+				SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+				smsg.addItemName(item);
+				player.sendPacket(smsg);
+			}
+		}
+		// send packets
+		StatusUpdate su = new StatusUpdate(player);
+		su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad());
+		player.sendPacket(su);
+	}
+	
+	/**
+	 * Give item/reward to the player
+	 * @param player
+	 * @param itemId
+	 * @param count
+	 */
+	public static void giveItems(L2PcInstance player, int itemId, long count)
+	{
+		giveItems(player, itemId, count, 0);
+	}
+	
+	/**
+	 * Give item/reward to the player
+	 * @param player
+	 * @param holder
+	 */
+	protected static void giveItems(L2PcInstance player, ItemHolder holder)
+	{
+		giveItems(player, holder.getId(), holder.getCount());
+	}
+	
+	/**
+	 * @param player
+	 * @param itemId
+	 * @param count
+	 * @param enchantlevel
+	 */
+	public static void giveItems(L2PcInstance player, int itemId, long count, int enchantlevel)
+	{
+		if (count <= 0)
+		{
+			return;
+		}
+		
+		// Add items to player's inventory
+		final L2ItemInstance item = player.getInventory().addItem("Quest", itemId, count, player, player.getTarget());
+		if (item == null)
+		{
+			return;
+		}
+		
+		// set enchant level for item if that item is not adena
+		if ((enchantlevel > 0) && (itemId != Inventory.ADENA_ID))
+		{
+			item.setEnchantLevel(enchantlevel);
+		}
+		
+		sendItemGetMessage(player, item, count);
+	}
+	
+	/**
+	 * @param player
+	 * @param itemId
+	 * @param count
+	 * @param attributeId
+	 * @param attributeLevel
+	 */
+	public static void giveItems(L2PcInstance player, int itemId, long count, byte attributeId, int attributeLevel)
+	{
+		if (count <= 0)
+		{
+			return;
+		}
+		
+		// Add items to player's inventory
+		final L2ItemInstance item = player.getInventory().addItem("Quest", itemId, count, player, player.getTarget());
+		if (item == null)
+		{
+			return;
+		}
+		
+		// set enchant level for item if that item is not adena
+		if ((attributeId >= 0) && (attributeLevel > 0))
+		{
+			item.setElementAttr(attributeId, attributeLevel);
+			if (item.isEquipped())
+			{
+				item.updateElementAttrBonus(player);
+			}
+			
+			InventoryUpdate iu = new InventoryUpdate();
+			iu.addModifiedItem(item);
+			player.sendPacket(iu);
+		}
+		
+		sendItemGetMessage(player, item, count);
+	}
+	
+	/**
+	 * Give the specified player a set amount of items if he is lucky enough.<br>
+	 * Not recommended to use this for non-stacking items.
+	 * @param player the player to give the item(s) to
+	 * @param itemId the ID of the item to give
+	 * @param amountToGive the amount of items to give
+	 * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached. 0 - no limit.
+	 * @param dropChance the drop chance as a decimal digit from 0 to 1
+	 * @param playSound if true, plays ItemSound.quest_itemget when items are given and ItemSound.quest_middle when the limit is reached
+	 * @return {@code true} if limit > 0 and the limit was reached or if limit <= 0 and items were given; {@code false} in all other cases
+	 */
+	public static boolean giveItemRandomly(L2PcInstance player, int itemId, long amountToGive, long limit, double dropChance, boolean playSound)
+	{
+		return giveItemRandomly(player, null, itemId, amountToGive, amountToGive, limit, dropChance, playSound);
+	}
+	
+	/**
+	 * Give the specified player a set amount of items if he is lucky enough.<br>
+	 * Not recommended to use this for non-stacking items.
+	 * @param player the player to give the item(s) to
+	 * @param npc the NPC that "dropped" the item (can be null)
+	 * @param itemId the ID of the item to give
+	 * @param amountToGive the amount of items to give
+	 * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached. 0 - no limit.
+	 * @param dropChance the drop chance as a decimal digit from 0 to 1
+	 * @param playSound if true, plays ItemSound.quest_itemget when items are given and ItemSound.quest_middle when the limit is reached
+	 * @return {@code true} if limit > 0 and the limit was reached or if limit <= 0 and items were given; {@code false} in all other cases
+	 */
+	public static boolean giveItemRandomly(L2PcInstance player, L2Npc npc, int itemId, long amountToGive, long limit, double dropChance, boolean playSound)
+	{
+		return giveItemRandomly(player, npc, itemId, amountToGive, amountToGive, limit, dropChance, playSound);
+	}
+	
+	/**
+	 * Give the specified player a random amount of items if he is lucky enough.<br>
+	 * Not recommended to use this for non-stacking items.
+	 * @param player the player to give the item(s) to
+	 * @param npc the NPC that "dropped" the item (can be null)
+	 * @param itemId the ID of the item to give
+	 * @param minAmount the minimum amount of items to give
+	 * @param maxAmount the maximum amount of items to give (will give a random amount between min/maxAmount multiplied by quest rates)
+	 * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached. 0 - no limit.
+	 * @param dropChance the drop chance as a decimal digit from 0 to 1
+	 * @param playSound if true, plays ItemSound.quest_itemget when items are given and ItemSound.quest_middle when the limit is reached
+	 * @return {@code true} if limit > 0 and the limit was reached or if limit <= 0 and items were given; {@code false} in all other cases
+	 */
+	public static boolean giveItemRandomly(L2PcInstance player, L2Npc npc, int itemId, long minAmount, long maxAmount, long limit, double dropChance, boolean playSound)
+	{
+		final long currentCount = getQuestItemsCount(player, itemId);
+		
+		if ((limit > 0) && (currentCount >= limit))
+		{
+			return true;
+		}
+		
+		minAmount *= Config.RATE_QUEST_DROP;
+		maxAmount *= Config.RATE_QUEST_DROP;
+		dropChance *= Config.RATE_QUEST_DROP; // TODO separate configs for rate and amount
+		if ((npc != null) && Config.L2JMOD_CHAMPION_ENABLE && npc.isChampion())
+		{
+			dropChance *= Config.L2JMOD_CHAMPION_REWARDS;
+			if ((itemId == Inventory.ADENA_ID) || (itemId == Inventory.ANCIENT_ADENA_ID))
+			{
+				minAmount *= Config.L2JMOD_CHAMPION_ADENAS_REWARDS;
+				maxAmount *= Config.L2JMOD_CHAMPION_ADENAS_REWARDS;
+			}
+			else
+			{
+				minAmount *= Config.L2JMOD_CHAMPION_REWARDS;
+				maxAmount *= Config.L2JMOD_CHAMPION_REWARDS;
+			}
+		}
+		
+		long amountToGive = ((minAmount == maxAmount) ? minAmount : Rnd.get(minAmount, maxAmount));
+		final double random = Rnd.nextDouble();
+		// Inventory slot check (almost useless for non-stacking items)
+		if ((dropChance >= random) && (amountToGive > 0) && player.getInventory().validateCapacityByItemId(itemId))
+		{
+			if ((limit > 0) && ((currentCount + amountToGive) > limit))
+			{
+				amountToGive = limit - currentCount;
+			}
+			
+			// Give the item to player
+			L2ItemInstance item = player.addItem("Quest", itemId, amountToGive, npc, true);
+			if (item != null)
+			{
+				// limit reached (if there is no limit, this block doesn't execute)
+				if ((currentCount + amountToGive) == limit)
+				{
+					if (playSound)
+					{
+						playSound(player, QuestSound.ITEMSOUND_QUEST_MIDDLE);
+					}
+					return true;
+				}
+				
+				if (playSound)
+				{
+					playSound(player, QuestSound.ITEMSOUND_QUEST_ITEMGET);
+				}
+				// if there is no limit, return true every time an item is given
+				if (limit <= 0)
+				{
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * Take an amount of a specified item from player's inventory.
+	 * @param player the player whose item to take
+	 * @param itemId the ID of the item to take
+	 * @param amount the amount to take
+	 * @return {@code true} if any items were taken, {@code false} otherwise
+	 */
+	public static boolean takeItems(L2PcInstance player, int itemId, long amount)
+	{
+		// Get object item from player's inventory list
+		final L2ItemInstance item = player.getInventory().getItemByItemId(itemId);
+		if (item == null)
+		{
+			return false;
+		}
+		
+		// Tests on count value in order not to have negative value
+		if ((amount < 0) || (amount > item.getCount()))
+		{
+			amount = item.getCount();
+		}
+		
+		// Destroy the quantity of items wanted
+		if (item.isEquipped())
+		{
+			final L2ItemInstance[] unequiped = player.getInventory().unEquipItemInBodySlotAndRecord(item.getItem().getBodyPart());
+			InventoryUpdate iu = new InventoryUpdate();
+			for (L2ItemInstance itm : unequiped)
+			{
+				iu.addModifiedItem(itm);
+			}
+			player.sendPacket(iu);
+			player.broadcastUserInfo();
+		}
+		return player.destroyItemByItemId("Quest", itemId, amount, player, true);
+	}
+	
+	/**
+	 * Take a set amount of a specified item from player's inventory.
+	 * @param player the player whose item to take
+	 * @param holder the {@link ItemHolder} object containing the ID and count of the item to take
+	 * @return {@code true} if the item was taken, {@code false} otherwise
+	 */
+	protected static boolean takeItem(L2PcInstance player, ItemHolder holder)
+	{
+		if (holder == null)
+		{
+			return false;
+		}
+		return takeItems(player, holder.getId(), holder.getCount());
+	}
+	
+	/**
+	 * Take a set amount of all specified items from player's inventory.
+	 * @param player the player whose items to take
+	 * @param itemList the list of {@link ItemHolder} objects containing the IDs and counts of the items to take
+	 * @return {@code true} if all items were taken, {@code false} otherwise
+	 */
+	protected static boolean takeAllItems(L2PcInstance player, ItemHolder... itemList)
+	{
+		if ((itemList == null) || (itemList.length == 0))
+		{
+			return false;
+		}
+		// first check if the player has all items to avoid taking half the items from the list
+		if (!hasAllItems(player, true, itemList))
+		{
+			return false;
+		}
+		for (ItemHolder item : itemList)
+		{
+			// this should never be false, but just in case
+			if (!takeItem(player, item))
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+	
+	/**
+	 * Take an amount of all specified items from player's inventory.
+	 * @param player the player whose items to take
+	 * @param amount the amount to take of each item
+	 * @param itemIds a list or an array of IDs of the items to take
+	 * @return {@code true} if all items were taken, {@code false} otherwise
+	 */
+	public static boolean takeItems(L2PcInstance player, int amount, int... itemIds)
+	{
+		boolean check = true;
+		if (itemIds != null)
+		{
+			for (int item : itemIds)
+			{
+				check &= takeItems(player, item, amount);
+			}
+		}
+		return check;
+	}
+	
+	/**
+	 * Send a packet in order to play a sound to the player.
+	 * @param player the player whom to send the packet
+	 * @param sound the name of the sound to play
+	 */
+	public static void playSound(L2PcInstance player, String sound)
+	{
+		player.sendPacket(QuestSound.getSound(sound));
+	}
+	
+	/**
+	 * Send a packet in order to play a sound to the player.
+	 * @param player the player whom to send the packet
+	 * @param sound the {@link QuestSound} object of the sound to play
+	 */
+	public static void playSound(L2PcInstance player, QuestSound sound)
+	{
+		player.sendPacket(sound.getPacket());
+	}
+	
+	/**
+	 * Add EXP and SP as quest reward.
+	 * @param player the player whom to reward with the EXP/SP
+	 * @param exp the amount of EXP to give to the player
+	 * @param sp the amount of SP to give to the player
+	 */
+	public static void addExpAndSp(L2PcInstance player, long exp, int sp)
+	{
+		player.addExpAndSp((long) player.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_QUEST_REWARD_XP, null, null), (int) player.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_QUEST_REWARD_SP, null, null));
+	}
+	
+	/**
+	 * Get a random integer from 0 (inclusive) to {@code max} (exclusive).<br>
+	 * Use this method instead of importing {@link com.l2jserver.util.Rnd} utility.
+	 * @param max the maximum value for randomization
+	 * @return a random integer number from 0 to {@code max - 1}
+	 */
+	public static int getRandom(int max)
+	{
+		return Rnd.get(max);
+	}
+	
+	/**
+	 * Get a random integer from {@code min} (inclusive) to {@code max} (inclusive).<br>
+	 * Use this method instead of importing {@link com.l2jserver.util.Rnd} utility.
+	 * @param min the minimum value for randomization
+	 * @param max the maximum value for randomization
+	 * @return a random integer number from {@code min} to {@code max}
+	 */
+	public static int getRandom(int min, int max)
+	{
+		return Rnd.get(min, max);
+	}
+	
+	/**
+	 * Get a random boolean.<br>
+	 * Use this method instead of importing {@link com.l2jserver.util.Rnd} utility.
+	 * @return {@code true} or {@code false} randomly
+	 */
+	public static boolean getRandomBoolean()
+	{
+		return Rnd.nextBoolean();
+	}
+	
+	/**
+	 * Get the ID of the item equipped in the specified inventory slot of the player.
+	 * @param player the player whose inventory to check
+	 * @param slot the location in the player's inventory to check
+	 * @return the ID of the item equipped in the specified inventory slot or 0 if the slot is empty or item is {@code null}.
+	 */
+	public static int getItemEquipped(L2PcInstance player, int slot)
+	{
+		return player.getInventory().getPaperdollItemId(slot);
+	}
+	
+	/**
+	 * @return the number of ticks from the {@link com.l2jserver.gameserver.GameTimeController}.
+	 */
+	public static int getGameTicks()
+	{
+		return GameTimeController.getInstance().getGameTicks();
+	}
+	
+	/**
+	 * Execute a procedure for each player depending on the parameters.
+	 * @param player the player on which the procedure will be executed
+	 * @param npc the related NPC
+	 * @param isSummon {@code true} if the event that called this method was originated by the player's summon, {@code false} otherwise
+	 * @param includeParty if {@code true}, #actionForEachPlayer(L2PcInstance, L2Npc, boolean) will be called with the player's party members
+	 * @param includeCommandChannel if {@code true}, {@link #actionForEachPlayer(L2PcInstance, L2Npc, boolean)} will be called with the player's command channel members
+	 * @see #actionForEachPlayer(L2PcInstance, L2Npc, boolean)
+	 */
+	public final void executeForEachPlayer(L2PcInstance player, final L2Npc npc, final boolean isSummon, boolean includeParty, boolean includeCommandChannel)
+	{
+		if ((includeParty || includeCommandChannel) && player.isInParty())
+		{
+			if (includeCommandChannel && player.getParty().isInCommandChannel())
+			{
+				player.getParty().getCommandChannel().forEachMember(member ->
+				{
+					actionForEachPlayer(member, npc, isSummon);
+					return true;
+				});
+			}
+			else if (includeParty)
+			{
+				player.getParty().forEachMember(member ->
+				{
+					actionForEachPlayer(member, npc, isSummon);
+					return true;
+				});
+			}
+		}
+		else
+		{
+			actionForEachPlayer(player, npc, isSummon);
+		}
+	}
+	
+	/**
+	 * Overridable method called from {@link #executeForEachPlayer(L2PcInstance, L2Npc, boolean, boolean, boolean)}
+	 * @param player the player on which the action will be run
+	 * @param npc the NPC related to this action
+	 * @param isSummon {@code true} if the event that called this method was originated by the player's summon
+	 */
+	public void actionForEachPlayer(L2PcInstance player, L2Npc npc, boolean isSummon)
+	{
+		// To be overridden in quest scripts.
+	}
+	
+	/**
+	 * Open a door if it is present on the instance and its not open.
+	 * @param doorId the ID of the door to open
+	 * @param instanceId the ID of the instance the door is in (0 if the door is not not inside an instance)
+	 */
+	public void openDoor(int doorId, int instanceId)
+	{
+		final L2DoorInstance door = getDoor(doorId, instanceId);
+		if (door == null)
+		{
+			_log.log(Level.WARNING, getClass().getSimpleName() + ": called openDoor(" + doorId + ", " + instanceId + "); but door wasnt found!", new NullPointerException());
+		}
+		else if (!door.getOpen())
+		{
+			door.openMe();
+		}
+	}
+	
+	/**
+	 * Close a door if it is present in a specified the instance and its open.
+	 * @param doorId the ID of the door to close
+	 * @param instanceId the ID of the instance the door is in (0 if the door is not not inside an instance)
+	 */
+	public void closeDoor(int doorId, int instanceId)
+	{
+		final L2DoorInstance door = getDoor(doorId, instanceId);
+		if (door == null)
+		{
+			_log.log(Level.WARNING, getClass().getSimpleName() + ": called closeDoor(" + doorId + ", " + instanceId + "); but door wasnt found!", new NullPointerException());
+		}
+		else if (door.getOpen())
+		{
+			door.closeMe();
+		}
+	}
+	
+	/**
+	 * Retrieve a door from an instance or the real world.
+	 * @param doorId the ID of the door to get
+	 * @param instanceId the ID of the instance the door is in (0 if the door is not not inside an instance)
+	 * @return the found door or {@code null} if no door with that ID and instance ID was found
+	 */
+	public L2DoorInstance getDoor(int doorId, int instanceId)
+	{
+		L2DoorInstance door = null;
+		if (instanceId <= 0)
+		{
+			door = DoorTable.getInstance().getDoor(doorId);
+		}
+		else
+		{
+			final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
+			if (inst != null)
+			{
+				door = inst.getDoor(doorId);
+			}
+		}
+		return door;
+	}
+	
+	/**
+	 * Teleport a player into/out of an instance.
+	 * @param player the player to teleport
+	 * @param loc the {@link Location} object containing the destination coordinates
+	 * @param instanceId the ID of the instance to teleport the player to (0 to teleport out of an instance)
+	 */
+	public void teleportPlayer(L2PcInstance player, Location loc, int instanceId)
+	{
+		teleportPlayer(player, loc, instanceId, true);
+	}
+	
+	/**
+	 * Teleport a player into/out of an instance.
+	 * @param player the player to teleport
+	 * @param loc the {@link Location} object containing the destination coordinates
+	 * @param instanceId the ID of the instance to teleport the player to (0 to teleport out of an instance)
+	 * @param allowRandomOffset if {@code true}, will randomize the teleport coordinates by +/-Config.MAX_OFFSET_ON_TELEPORT
+	 */
+	public void teleportPlayer(L2PcInstance player, Location loc, int instanceId, boolean allowRandomOffset)
+	{
+		loc.setInstanceId(instanceId);
+		player.teleToLocation(loc, allowRandomOffset);
+	}
+	
+	/**
+	 * Sends the special camera packet to the player.
+	 * @param player the player
+	 * @param creature the watched creature
+	 * @param force
+	 * @param angle1
+	 * @param angle2
+	 * @param time
+	 * @param range
+	 * @param duration
+	 * @param relYaw
+	 * @param relPitch
+	 * @param isWide
+	 * @param relAngle
+	 */
+	public static final void specialCamera(L2PcInstance player, L2Character creature, int force, int angle1, int angle2, int time, int range, int duration, int relYaw, int relPitch, int isWide, int relAngle)
+	{
+		player.sendPacket(new SpecialCamera(creature, force, angle1, angle2, time, range, duration, relYaw, relPitch, isWide, relAngle));
+	}
+	
+	/**
+	 * Sends the special camera packet to the player.
+	 * @param player
+	 * @param creature
+	 * @param force
+	 * @param angle1
+	 * @param angle2
+	 * @param time
+	 * @param duration
+	 * @param relYaw
+	 * @param relPitch
+	 * @param isWide
+	 * @param relAngle
+	 */
+	public static final void specialCameraEx(L2PcInstance player, L2Character creature, int force, int angle1, int angle2, int time, int duration, int relYaw, int relPitch, int isWide, int relAngle)
+	{
+		player.sendPacket(new SpecialCamera(creature, player, force, angle1, angle2, time, duration, relYaw, relPitch, isWide, relAngle));
+	}
+	
+	/**
+	 * Sends the special camera packet to the player.
+	 * @param player
+	 * @param creature
+	 * @param force
+	 * @param angle1
+	 * @param angle2
+	 * @param time
+	 * @param range
+	 * @param duration
+	 * @param relYaw
+	 * @param relPitch
+	 * @param isWide
+	 * @param relAngle
+	 * @param unk
+	 */
+	public static final void specialCamera3(L2PcInstance player, L2Character creature, int force, int angle1, int angle2, int time, int range, int duration, int relYaw, int relPitch, int isWide, int relAngle, int unk)
+	{
+		player.sendPacket(new SpecialCamera(creature, force, angle1, angle2, time, range, duration, relYaw, relPitch, isWide, relAngle, unk));
+	}
+}

+ 250 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/EventDispatcher.java

@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events;
+
+import java.util.Queue;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.events.listeners.AbstractEventListener;
+import com.l2jserver.gameserver.model.events.returns.AbstractEventReturn;
+
+/**
+ * @author UnAfraid
+ */
+public class EventDispatcher extends ListenersContainer
+{
+	private static final Logger _log = Logger.getLogger(EventDispatcher.class.getName());
+	
+	protected EventDispatcher()
+	{
+	}
+	
+	/**
+	 * @param <T>
+	 * @param event
+	 * @return
+	 */
+	public <T extends AbstractEventReturn> T notifyEvent(IBaseEvent event)
+	{
+		return notifyEvent(event, null, null);
+	}
+	
+	/**
+	 * @param <T>
+	 * @param event
+	 * @param callbackClass
+	 * @return
+	 */
+	public <T extends AbstractEventReturn> T notifyEvent(IBaseEvent event, Class<T> callbackClass)
+	{
+		return notifyEvent(event, null, callbackClass);
+	}
+	
+	/**
+	 * @param <T>
+	 * @param event
+	 * @param container
+	 * @param callbackClass
+	 * @return
+	 */
+	public <T extends AbstractEventReturn> T notifyEvent(IBaseEvent event, ListenersContainer container, Class<T> callbackClass)
+	{
+		try
+		{
+			return notifyEventImpl(event, container, callbackClass);
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't notify event " + event.getClass().getSimpleName(), e);
+		}
+		return null;
+	}
+	
+	/**
+	 * @param <T>
+	 * @param event
+	 * @param containers
+	 * @param callbackClass
+	 * @return
+	 */
+	public <T extends AbstractEventReturn> T notifyEventToMultipleContainers(IBaseEvent event, ListenersContainer[] containers, Class<T> callbackClass)
+	{
+		try
+		{
+			if (event == null)
+			{
+				throw new NullPointerException("Event cannot be null!");
+			}
+			
+			T callback = null;
+			if (containers != null)
+			{
+				// Local listeners container first.
+				for (ListenersContainer container : containers)
+				{
+					if ((callback == null) || !callback.abort())
+					{
+						callback = notifyToListeners(container.getListeners(event.getType()), event, callbackClass, callback);
+					}
+				}
+			}
+			
+			// Global listener container.
+			if ((callback == null) || !callback.abort())
+			{
+				callback = notifyToListeners(getListeners(event.getType()), event, callbackClass, callback);
+			}
+			
+			return callback;
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't notify event " + event.getClass().getSimpleName(), e);
+		}
+		return null;
+	}
+	
+	/**
+	 * @param <T>
+	 * @param event
+	 * @param container
+	 * @param callbackClass
+	 * @return {@link AbstractEventReturn} object that may keep data from the first listener, or last that breaks notification.
+	 */
+	private <T extends AbstractEventReturn> T notifyEventImpl(IBaseEvent event, ListenersContainer container, Class<T> callbackClass)
+	{
+		if (event == null)
+		{
+			throw new NullPointerException("Event cannot be null!");
+		}
+		
+		T callback = null;
+		// Local listener container first.
+		if (container != null)
+		{
+			callback = notifyToListeners(container.getListeners(event.getType()), event, callbackClass, callback);
+		}
+		
+		// Global listener container.
+		if ((callback == null) || !callback.abort())
+		{
+			callback = notifyToListeners(getListeners(event.getType()), event, callbackClass, callback);
+		}
+		
+		return callback;
+	}
+	
+	/**
+	 * @param <T>
+	 * @param listeners
+	 * @param event
+	 * @param returnBackClass
+	 * @param callback
+	 * @return
+	 */
+	private <T extends AbstractEventReturn> T notifyToListeners(Queue<AbstractEventListener> listeners, IBaseEvent event, Class<T> returnBackClass, T callback)
+	{
+		for (AbstractEventListener listener : listeners)
+		{
+			try
+			{
+				final T rb = listener.executeEvent(event, returnBackClass);
+				if (rb == null)
+				{
+					continue;
+				}
+				else if ((callback == null) || rb.override()) // Let's check if this listener wants to override previous return object or we simply don't have one
+				{
+					callback = rb;
+				}
+				else if (rb.abort()) // This listener wants to abort the notification to others.
+				{
+					break;
+				}
+			}
+			catch (Exception e)
+			{
+				_log.log(Level.WARNING, getClass().getSimpleName() + ": Exception during notification of event: " + event.getClass().getSimpleName() + " listener: " + listener.getClass().getSimpleName(), e);
+			}
+		}
+		
+		return callback;
+	}
+	
+	/**
+	 * Executing global listener notification asynchronously
+	 * @param event
+	 */
+	public void notifyEventAsync(final IBaseEvent event)
+	{
+		notifyEventAsync(event);
+	}
+	
+	/**
+	 * Executing current listener notification asynchronously
+	 * @param event
+	 * @param containers
+	 */
+	public void notifyEventAsync(final IBaseEvent event, ListenersContainer... containers)
+	{
+		if (event == null)
+		{
+			throw new NullPointerException("Event cannot be null!");
+		}
+		
+		ThreadPoolManager.getInstance().executeEvent(() -> notifyEventToMultipleContainers(event, containers, null));
+	}
+	
+	/**
+	 * Scheduling current listener notification asynchronously after specified delay.
+	 * @param event
+	 * @param container
+	 * @param delay
+	 */
+	public void notifyEventAsyncDelayed(final IBaseEvent event, ListenersContainer container, long delay)
+	{
+		ThreadPoolManager.getInstance().scheduleEvent(() -> notifyEvent(event, container, null), delay);
+	}
+	
+	/**
+	 * Scheduling current listener notification asynchronously after specified delay.
+	 * @param event
+	 * @param container
+	 * @param delay
+	 * @param unit
+	 */
+	public void notifyEventAsyncDelayed(final IBaseEvent event, ListenersContainer container, long delay, TimeUnit unit)
+	{
+		ThreadPoolManager.getInstance().scheduleEvent(() -> notifyEvent(event, container, null), delay, unit);
+	}
+	
+	public static final EventDispatcher getInstance()
+	{
+		return SingletonHolder._instance;
+	}
+	
+	private static class SingletonHolder
+	{
+		protected static final EventDispatcher _instance = new EventDispatcher();
+	}
+}

+ 242 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/EventType.java

@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events;
+
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureAttack;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureDamage;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureKill;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureSkillUse;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureTeleported;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureZoneEnter;
+import com.l2jserver.gameserver.model.events.impl.character.OnCreatureZoneExit;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcCanBeSeen;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcEventReceived;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcFirstTalk;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveFinished;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveNodeArrived;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveRouteFinished;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSkillFinished;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSkillSee;
+import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSpawn;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableAggroRangeEnter;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableAttack;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableFactionCall;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableHate;
+import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableKill;
+import com.l2jserver.gameserver.model.events.impl.character.playable.OnPlayableExpChanged;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerAugment;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerBypass;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerChat;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerCreate;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerDelete;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerDlgAnswer;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerEquipItem;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerFameChanged;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerHennaAdd;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerHennaRemove;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerKarmaChanged;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLevelChanged;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLogin;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLogout;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerPKChanged;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerProfessionChange;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerPvPChanged;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerPvPKill;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerRestore;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerSelect;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerSkillLearn;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerSummonSpawn;
+import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerTransform;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanCreate;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanDestroy;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanJoin;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanLeaderChange;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanLeft;
+import com.l2jserver.gameserver.model.events.impl.character.player.clan.OnPlayerClanLvlUp;
+import com.l2jserver.gameserver.model.events.impl.character.player.clanwh.OnPlayerClanWHItemAdd;
+import com.l2jserver.gameserver.model.events.impl.character.player.clanwh.OnPlayerClanWHItemDestroy;
+import com.l2jserver.gameserver.model.events.impl.character.player.clanwh.OnPlayerClanWHItemTransfer;
+import com.l2jserver.gameserver.model.events.impl.character.player.inventory.OnPlayerItemAdd;
+import com.l2jserver.gameserver.model.events.impl.character.player.inventory.OnPlayerItemDestroy;
+import com.l2jserver.gameserver.model.events.impl.character.player.inventory.OnPlayerItemDrop;
+import com.l2jserver.gameserver.model.events.impl.character.player.inventory.OnPlayerItemPickup;
+import com.l2jserver.gameserver.model.events.impl.character.player.inventory.OnPlayerItemTransfer;
+import com.l2jserver.gameserver.model.events.impl.character.trap.OnTrapAction;
+import com.l2jserver.gameserver.model.events.impl.clan.OnClanWarFinish;
+import com.l2jserver.gameserver.model.events.impl.clan.OnClanWarStart;
+import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventFinish;
+import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventKill;
+import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventRegistrationStart;
+import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventStart;
+import com.l2jserver.gameserver.model.events.impl.item.OnItemBypassEvent;
+import com.l2jserver.gameserver.model.events.impl.item.OnItemCreate;
+import com.l2jserver.gameserver.model.events.impl.item.OnItemTalk;
+import com.l2jserver.gameserver.model.events.impl.olympiad.OnOlympiadMatchResult;
+import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeFinish;
+import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeOwnerChange;
+import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeStart;
+import com.l2jserver.gameserver.model.events.impl.sieges.fort.OnFortSiegeFinish;
+import com.l2jserver.gameserver.model.events.impl.sieges.fort.OnFortSiegeStart;
+import com.l2jserver.gameserver.model.events.returns.ChatFilterReturn;
+import com.l2jserver.gameserver.model.events.returns.TerminateReturn;
+import com.l2jserver.gameserver.util.Util;
+
+/**
+ * @author UnAfraid
+ */
+public enum EventType
+{
+	// Attackable events
+	ON_ATTACKABLE_AGGRO_RANGE_ENTER(OnAttackableAggroRangeEnter.class, void.class),
+	ON_ATTACKABLE_ATTACK(OnAttackableAttack.class, void.class),
+	ON_ATTACKABLE_FACTION_CALL(OnAttackableFactionCall.class, void.class),
+	ON_ATTACKABLE_KILL(OnAttackableKill.class, void.class),
+	
+	// Castle events
+	ON_CASTLE_SIEGE_FINISH(OnCastleSiegeFinish.class, void.class),
+	ON_CASTLE_SIEGE_OWNER_CHANGE(OnCastleSiegeOwnerChange.class, void.class),
+	ON_CASTLE_SIEGE_START(OnCastleSiegeStart.class, void.class),
+	
+	// Clan events
+	ON_CLAN_WAR_FINISH(OnClanWarFinish.class, void.class),
+	ON_CLAN_WAR_START(OnClanWarStart.class, void.class),
+	
+	// Creature events
+	ON_CREATURE_ATTACK(OnCreatureAttack.class, void.class, TerminateReturn.class),
+	ON_CREATURE_DAMAGE(OnCreatureDamage.class, void.class, TerminateReturn.class),
+	ON_CREATURE_KILL(OnCreatureKill.class, void.class, TerminateReturn.class),
+	ON_CREATURE_SKILL_USE(OnCreatureSkillUse.class, void.class, TerminateReturn.class),
+	ON_CREATURE_TELEPORTED(OnCreatureTeleported.class, void.class),
+	ON_CREATURE_ZONE_ENTER(OnCreatureZoneEnter.class, void.class),
+	ON_CREATURE_ZONE_EXIT(OnCreatureZoneExit.class, void.class),
+	
+	// Fortress events
+	ON_FORT_SIEGE_FINISH(OnFortSiegeFinish.class, void.class),
+	ON_FORT_SIEGE_START(OnFortSiegeStart.class, void.class),
+	
+	// Item events
+	ON_ITEM_BYPASS_EVENT(OnItemBypassEvent.class, void.class),
+	ON_ITEM_CREATE(OnItemCreate.class, void.class),
+	ON_ITEM_TALK(OnItemTalk.class, void.class),
+	
+	// Npcs events
+	ON_NPC_CAN_BE_SEEN(OnNpcCanBeSeen.class, void.class, TerminateReturn.class),
+	ON_NPC_CREATURE_SEE(OnNpcCreatureSee.class, void.class),
+	ON_NPC_EVENT_RECEIVED(OnNpcEventReceived.class, void.class),
+	ON_NPC_FIRST_TALK(OnNpcFirstTalk.class, void.class),
+	ON_NPC_HATE(OnAttackableHate.class, void.class, TerminateReturn.class),
+	ON_NPC_MOVE_FINISHED(OnNpcMoveFinished.class, void.class),
+	ON_NPC_MOVE_NODE_ARRIVED(OnNpcMoveNodeArrived.class, void.class),
+	ON_NPC_MOVE_ROUTE_FINISHED(OnNpcMoveRouteFinished.class, void.class),
+	ON_NPC_QUEST_START(null, void.class),
+	ON_NPC_SKILL_FINISHED(OnNpcSkillFinished.class, void.class),
+	ON_NPC_SKILL_SEE(OnNpcSkillSee.class, void.class),
+	ON_NPC_SPAWN(OnNpcSpawn.class, void.class),
+	ON_NPC_TALK(null, void.class),
+	
+	// Olympiad events
+	ON_OLYMPIAD_MATCH_RESULT(OnOlympiadMatchResult.class, void.class),
+	
+	// Playable events
+	ON_PLAYABLE_EXP_CHANGED(OnPlayableExpChanged.class, void.class, TerminateReturn.class),
+	
+	// Player events
+	ON_PLAYER_AUGMENT(OnPlayerAugment.class, void.class),
+	ON_PLAYER_BYPASS(OnPlayerBypass.class, void.class),
+	ON_PLAYER_CHAT(OnPlayerChat.class, void.class, ChatFilterReturn.class),
+	// Clan events
+	ON_PLAYER_CLAN_CREATE(OnPlayerClanCreate.class, void.class),
+	ON_PLAYER_CLAN_DESTROY(OnPlayerClanDestroy.class, void.class),
+	ON_PLAYER_CLAN_JOIN(OnPlayerClanJoin.class, void.class),
+	ON_PLAYER_CLAN_LEADER_CHANGE(OnPlayerClanLeaderChange.class, void.class),
+	ON_PLAYER_CLAN_LEFT(OnPlayerClanLeft.class, void.class),
+	ON_PLAYER_CLAN_LVLUP(OnPlayerClanLvlUp.class, void.class),
+	// Clan warehouse events
+	ON_PLAYER_CLAN_WH_ITEM_ADD(OnPlayerClanWHItemAdd.class, void.class),
+	ON_PLAYER_CLAN_WH_ITEM_DESTROY(OnPlayerClanWHItemDestroy.class, void.class),
+	ON_PLAYER_CLAN_WH_ITEM_TRANSFER(OnPlayerClanWHItemTransfer.class, void.class),
+	ON_PLAYER_CREATE(OnPlayerCreate.class, void.class),
+	ON_PLAYER_DELETE(OnPlayerDelete.class, void.class),
+	ON_PLAYER_DLG_ANSWER(OnPlayerDlgAnswer.class, void.class, TerminateReturn.class),
+	ON_PLAYER_EQUIP_ITEM(OnPlayerEquipItem.class, void.class),
+	ON_PLAYER_FAME_CHANGED(OnPlayerFameChanged.class, void.class),
+	// Henna events
+	ON_PLAYER_HENNA_ADD(OnPlayerHennaAdd.class, void.class),
+	ON_PLAYER_HENNA_REMOVE(OnPlayerHennaRemove.class, void.class),
+	// Inventory events
+	ON_PLAYER_ITEM_ADD(OnPlayerItemAdd.class, void.class),
+	ON_PLAYER_ITEM_DESTROY(OnPlayerItemDestroy.class, void.class),
+	ON_PLAYER_ITEM_DROP(OnPlayerItemDrop.class, void.class),
+	ON_PLAYER_ITEM_PICKUP(OnPlayerItemPickup.class, void.class),
+	ON_PLAYER_ITEM_TRANSFER(OnPlayerItemTransfer.class, void.class),
+	// Other player events
+	ON_PLAYER_KARMA_CHANGED(OnPlayerKarmaChanged.class, void.class),
+	ON_PLAYER_LEVEL_CHANGED(OnPlayerLevelChanged.class, void.class),
+	ON_PLAYER_LOGIN(OnPlayerLogin.class, void.class),
+	ON_PLAYER_LOGOUT(OnPlayerLogout.class, void.class),
+	ON_PLAYER_PK_CHANGED(OnPlayerPKChanged.class, void.class),
+	ON_PLAYER_PROFESSION_CHANGE(OnPlayerProfessionChange.class, void.class),
+	ON_PLAYER_PVP_CHANGED(OnPlayerPvPChanged.class, void.class),
+	ON_PLAYER_PVP_KILL(OnPlayerPvPKill.class, void.class),
+	ON_PLAYER_RESTORE(OnPlayerRestore.class, void.class),
+	ON_PLAYER_SELECT(OnPlayerSelect.class, void.class),
+	ON_PLAYER_SKILL_LEARN(OnPlayerSkillLearn.class, void.class),
+	ON_PLAYER_SUMMON_SPAWN(OnPlayerSummonSpawn.class, void.class),
+	ON_PLAYER_TRANSFORM(OnPlayerTransform.class, void.class),
+	
+	// Trap events
+	ON_TRAP_ACTION(OnTrapAction.class, void.class),
+	
+	// TvT events.
+	ON_TVT_EVENT_FINISH(OnTvTEventFinish.class, void.class),
+	ON_TVT_EVENT_KILL(OnTvTEventKill.class, void.class),
+	ON_TVT_EVENT_REGISTRATION_START(OnTvTEventRegistrationStart.class, void.class),
+	ON_TVT_EVENT_START(OnTvTEventStart.class, void.class);
+	
+	private final Class<? extends IBaseEvent> _eventClass;
+	private final Class<?>[] _returnClass;
+	
+	private EventType(Class<? extends IBaseEvent> eventClass, Class<?>... returnClasss)
+	{
+		_eventClass = eventClass;
+		_returnClass = returnClasss;
+	}
+	
+	public Class<? extends IBaseEvent> getEventClass()
+	{
+		return _eventClass;
+	}
+	
+	public Class<?>[] getReturnClasses()
+	{
+		return _returnClass;
+	}
+	
+	public boolean isEventClass(Class<?> clazz)
+	{
+		return _eventClass == clazz;
+	}
+	
+	public boolean isReturnClass(Class<?> clazz)
+	{
+		return Util.contains(_returnClass, clazz);
+	}
+}

+ 10 - 5
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/impl/L2Event.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/ListenerRegisterType.java

@@ -16,13 +16,18 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.events.impl;
+package com.l2jserver.gameserver.model.events;
 
 /**
- * Convenience interface for all events
- * @author TheOne
+ * @author UnAfraid
  */
-public interface L2Event
+public enum ListenerRegisterType
 {
-	
+	NPC,
+	ZONE,
+	ITEM,
+	CASTLE,
+	FORTRESS,
+	OLYMPIAD,
+	GLOBAL
 }

+ 107 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/ListenersContainer.java

@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events;
+
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.PriorityBlockingQueue;
+
+import com.l2jserver.gameserver.model.events.listeners.AbstractEventListener;
+import com.l2jserver.util.EmptyQueue;
+
+/**
+ * @author UnAfraid
+ */
+public class ListenersContainer
+{
+	private volatile Map<EventType, Queue<AbstractEventListener>> _listeners = null;
+	
+	/**
+	 * Registers listener for a callback when specified event is executed.
+	 * @param listener
+	 * @return
+	 */
+	public AbstractEventListener addListener(AbstractEventListener listener)
+	{
+		if ((listener == null))
+		{
+			throw new NullPointerException("Listener cannot be null!");
+		}
+		getListeners().computeIfAbsent(listener.getType(), k -> new PriorityBlockingQueue<>()).add(listener);
+		return listener;
+	}
+	
+	/**
+	 * Unregisters listener for a callback when specified event is executed.
+	 * @param listener
+	 * @return
+	 */
+	public AbstractEventListener removeListener(AbstractEventListener listener)
+	{
+		if ((listener == null))
+		{
+			throw new NullPointerException("Listener cannot be null!");
+		}
+		else if (_listeners == null)
+		{
+			throw new NullPointerException("Listeners container is not initialized!");
+		}
+		else if (!_listeners.containsKey(listener.getType()))
+		{
+			throw new IllegalAccessError("Listeners container doesn't had " + listener.getType() + " event type added!");
+		}
+		
+		_listeners.get(listener.getType()).remove(listener);
+		return listener;
+	}
+	
+	/**
+	 * @param type
+	 * @return {@code List} of {@link AbstractEventListener} by the specified type
+	 */
+	public Queue<AbstractEventListener> getListeners(EventType type)
+	{
+		return (_listeners != null) && _listeners.containsKey(type) ? _listeners.get(type) : EmptyQueue.emptyQueue();
+	}
+	
+	public boolean hasListener(EventType type)
+	{
+		return !getListeners(type).isEmpty();
+	}
+	
+	/**
+	 * Creates the listeners container map if doesn't exists.
+	 * @return the listeners container map.
+	 */
+	private Map<EventType, Queue<AbstractEventListener>> getListeners()
+	{
+		if (_listeners == null)
+		{
+			synchronized (this)
+			{
+				if (_listeners == null)
+				{
+					return _listeners = new ConcurrentHashMap<>();
+				}
+			}
+		}
+		return _listeners;
+	}
+}

+ 6 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/annotations/Message.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/annotations/Npc.java

@@ -16,9 +16,10 @@
  * 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 com.l2jserver.gameserver.model.actor.events.annotations;
+package com.l2jserver.gameserver.model.events.annotations;
 
 import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
@@ -26,9 +27,10 @@ import java.lang.annotation.Target;
 /**
  * @author UnAfraid
  */
+@Repeatable(Npcs.class)
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface Message
+@Target(ElementType.METHOD)
+public @interface Npc
 {
-	int[] value();
+	public int[] value();
 }

+ 4 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/annotations/SkillId.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/annotations/Npcs.java

@@ -16,7 +16,7 @@
  * 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 com.l2jserver.gameserver.model.actor.events.annotations;
+package com.l2jserver.gameserver.model.events.annotations;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -27,8 +27,8 @@ import java.lang.annotation.Target;
  * @author UnAfraid
  */
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface SkillId
+@Target(ElementType.METHOD)
+public @interface Npcs
 {
-	int[] value();
+	public Npc[] value();
 }

+ 6 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/annotations/SkillLevel.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/annotations/RegisterEvent.java

@@ -16,19 +16,21 @@
  * 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 com.l2jserver.gameserver.model.actor.events.annotations;
+package com.l2jserver.gameserver.model.events.annotations;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import com.l2jserver.gameserver.model.events.EventType;
+
 /**
  * @author UnAfraid
  */
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface SkillLevel
+@Target(ElementType.METHOD)
+public @interface RegisterEvent
 {
-	int[] value();
+	public EventType value();
 }

+ 5 - 5
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/ITeleportedEventListener.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/IBaseEvent.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2014 L2J Server
+ * Copyright (C) 2004-2013 L2J Server
  * 
  * This file is part of L2J Server.
  * 
@@ -16,14 +16,14 @@
  * 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 com.l2jserver.gameserver.model.actor.events.listeners;
+package com.l2jserver.gameserver.model.events.impl;
 
-import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.events.EventType;
 
 /**
  * @author UnAfraid
  */
-public interface ITeleportedEventListener extends IEventListener
+public interface IBaseEvent
 {
-	public void onTeleported(L2Character target);
+	public EventType getType();
 }

+ 55 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureAttack.java

@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character;
+
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * An instantly executed event when L2Character is attacked by L2Character.
+ * @author UnAfraid
+ */
+public class OnCreatureAttack implements IBaseEvent
+{
+	private final L2Character _attacker;
+	private final L2Character _target;
+	
+	public OnCreatureAttack(L2Character attacker, L2Character target)
+	{
+		_attacker = attacker;
+		_target = target;
+	}
+	
+	public final L2Character getAttacker()
+	{
+		return _attacker;
+	}
+	
+	public final L2Character getTarget()
+	{
+		return _target;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_CREATURE_ATTACK;
+	}
+}

+ 84 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureDamage.java

@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character;
+
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.skills.Skill;
+
+/**
+ * An instantly executed event when L2Character is attacked by L2Character.
+ * @author UnAfraid
+ */
+public class OnCreatureDamage implements IBaseEvent
+{
+	private final L2Character _attacker;
+	private final L2Character _target;
+	private final double _damage;
+	private final Skill _skill;
+	private final boolean _crit;
+	private final boolean _damageOverTime;
+	
+	public OnCreatureDamage(L2Character attacker, L2Character target, double damage, Skill skill, boolean crit, boolean damageOverTime)
+	{
+		_attacker = attacker;
+		_target = target;
+		_damage = damage;
+		_skill = skill;
+		_crit = crit;
+		_damageOverTime = damageOverTime;
+	}
+	
+	public final L2Character getAttacker()
+	{
+		return _attacker;
+	}
+	
+	public final L2Character getTarget()
+	{
+		return _target;
+	}
+	
+	public double getDamage()
+	{
+		return _damage;
+	}
+	
+	public Skill getSkill()
+	{
+		return _skill;
+	}
+	
+	public boolean isCritical()
+	{
+		return _crit;
+	}
+	
+	public boolean isDamageOverTime()
+	{
+		return _damageOverTime;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_CREATURE_DAMAGE;
+	}
+}

+ 55 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureKill.java

@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character;
+
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * An instantly executed event when L2Character is killed by L2Character.
+ * @author UnAfraid
+ */
+public class OnCreatureKill implements IBaseEvent
+{
+	private final L2Character _attacker;
+	private final L2Character _target;
+	
+	public OnCreatureKill(L2Character attacker, L2Character target)
+	{
+		_attacker = attacker;
+		_target = target;
+	}
+	
+	public final L2Character getAttacker()
+	{
+		return _attacker;
+	}
+	
+	public final L2Character getTarget()
+	{
+		return _target;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_CREATURE_KILL;
+	}
+}

+ 31 - 52
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/SkillUseEvent.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureSkillUse.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2014 L2J Server
+ * Copyright (C) 2004-2013 L2J Server
  * 
  * This file is part of L2J Server.
  * 
@@ -16,84 +16,63 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.events;
+package com.l2jserver.gameserver.model.events.impl.character;
 
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 import com.l2jserver.gameserver.model.skills.Skill;
-import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
 
 /**
- * @author TheOne
+ * An instantly executed event when L2Character is attacked by L2Character.
+ * @author UnAfraid
  */
-public class SkillUseEvent implements L2Event
+public class OnCreatureSkillUse implements IBaseEvent
 {
-	private L2Character _caster;
-	private Skill _skill;
-	private L2Character _target;
-	private L2Object[] _targets;
+	private final L2Character _caster;
+	private final Skill _skill;
+	private final boolean _simultaneously;
+	private final L2Character _target;
+	private final L2Object[] _targets;
 	
-	/**
-	 * @return the caster
-	 */
-	public L2Character getCaster()
-	{
-		return _caster;
-	}
-	
-	/**
-	 * @param caster the caster to set
-	 */
-	public void setCaster(L2Character caster)
+	public OnCreatureSkillUse(L2Character caster, Skill skill, boolean simultaneously, L2Character target, L2Object[] targets)
 	{
 		_caster = caster;
+		_skill = skill;
+		_simultaneously = simultaneously;
+		_target = target;
+		_targets = targets;
 	}
 	
-	/**
-	 * @return the targets
-	 */
-	public L2Object[] getTargets()
-	{
-		return _targets;
-	}
-	
-	/**
-	 * @param targets the targets to set
-	 */
-	public void setTargets(L2Object[] targets)
+	public final L2Character getCaster()
 	{
-		_targets = targets;
+		return _caster;
 	}
 	
-	/**
-	 * @return the skill
-	 */
 	public Skill getSkill()
 	{
 		return _skill;
 	}
 	
-	/**
-	 * @param skill the skill to set
-	 */
-	public void setSkill(Skill skill)
+	public boolean isSimultaneously()
 	{
-		_skill = skill;
+		return _simultaneously;
 	}
 	
-	/**
-	 * @return Caster's selected target.
-	 */
-	public L2Character getTarget()
+	public final L2Character getTarget()
 	{
 		return _target;
 	}
 	
-	/**
-	 * @param target
-	 */
-	public void setTarget(L2Character target)
+	public L2Object[] getTargets()
+	{
+		return _targets;
+	}
+	
+	@Override
+	public EventType getType()
 	{
-		_target = target;
+		return EventType.ON_CREATURE_SKILL_USE;
 	}
-}
+}

+ 21 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IDamageReceivedEventListener.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureTeleported.java

@@ -16,15 +16,32 @@
  * 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 com.l2jserver.gameserver.model.actor.events.listeners;
+package com.l2jserver.gameserver.model.events.impl.character;
 
 import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.skills.Skill;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
  * @author UnAfraid
  */
-public interface IDamageReceivedEventListener extends IEventListener
+public class OnCreatureTeleported implements IBaseEvent
 {
-	public void onDamageReceivedEvent(L2Character attacker, L2Character target, double damage, Skill skill, boolean crit, boolean damageOverTime);
+	private final L2Character _creature;
+	
+	public OnCreatureTeleported(L2Character creature)
+	{
+		_creature = creature;
+	}
+	
+	public L2Character getCreature()
+	{
+		return _creature;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_CREATURE_TELEPORTED;
+	}
 }

+ 19 - 26
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/AttackEvent.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureZoneEnter.java

@@ -16,48 +16,41 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.events;
+package com.l2jserver.gameserver.model.events.impl.character;
 
 import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.zone.L2ZoneType;
 
 /**
- * @author TheOne
+ * @author UnAfraid
  */
-public class AttackEvent implements L2Event
+public class OnCreatureZoneEnter implements IBaseEvent
 {
-	private L2Character attacker;
-	private L2Character target;
+	private final L2Character _creature;
+	private final L2ZoneType _zone;
 	
-	/**
-	 * @return the attacker
-	 */
-	public L2Character getAttacker()
+	public OnCreatureZoneEnter(L2Character creature, L2ZoneType zone)
 	{
-		return attacker;
+		_creature = creature;
+		_zone = zone;
 	}
 	
-	/**
-	 * @param attacker the attacker to set
-	 */
-	public void setAttacker(L2Character attacker)
+	public L2Character getCreature()
 	{
-		this.attacker = attacker;
+		return _creature;
 	}
 	
-	/**
-	 * @return the target
-	 */
-	public L2Character getTarget()
+	public L2ZoneType getZone()
 	{
-		return target;
+		return _zone;
 	}
 	
-	/**
-	 * @param target the target to set
-	 */
-	public void setTarget(L2Character target)
+	@Override
+	public EventType getType()
 	{
-		this.target = target;
+		return EventType.ON_CREATURE_ZONE_ENTER;
 	}
+	
 }

+ 19 - 26
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/DeathEvent.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/OnCreatureZoneExit.java

@@ -16,48 +16,41 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.events;
+package com.l2jserver.gameserver.model.events.impl.character;
 
 import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.zone.L2ZoneType;
 
 /**
- * @author TheOne
+ * @author UnAfraid
  */
-public class DeathEvent implements L2Event
+public class OnCreatureZoneExit implements IBaseEvent
 {
-	private L2Character victim;
-	private L2Character killer;
+	private final L2Character _creature;
+	private final L2ZoneType _zone;
 	
-	/**
-	 * @return the victim
-	 */
-	public L2Character getVictim()
+	public OnCreatureZoneExit(L2Character creature, L2ZoneType zone)
 	{
-		return victim;
+		_creature = creature;
+		_zone = zone;
 	}
 	
-	/**
-	 * @param victim the victim to set
-	 */
-	public void setVictim(L2Character victim)
+	public L2Character getCreature()
 	{
-		this.victim = victim;
+		return _creature;
 	}
 	
-	/**
-	 * @return the killer
-	 */
-	public L2Character getKiller()
+	public L2ZoneType getZone()
 	{
-		return killer;
+		return _zone;
 	}
 	
-	/**
-	 * @param killer the killer to set
-	 */
-	public void setKiller(L2Character killer)
+	@Override
+	public EventType getType()
 	{
-		this.killer = killer;
+		return EventType.ON_CREATURE_ZONE_EXIT;
 	}
+	
 }

+ 21 - 24
L2J_Server_BETA/java/com/l2jserver/gameserver/model/quest/AITasks/AggroRangeEnter.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcCanBeSeen.java

@@ -16,43 +16,40 @@
  * 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 com.l2jserver.gameserver.model.quest.AITasks;
+package com.l2jserver.gameserver.model.events.impl.character.npc;
 
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
- * Aggro Range Enter AI task.
- * @author Zoey76
+ * @author UnAfraid
  */
-public final class AggroRangeEnter implements Runnable
+public class OnNpcCanBeSeen implements IBaseEvent
 {
-	private final Quest _quest;
 	private final L2Npc _npc;
-	private final L2PcInstance _pc;
-	private final boolean _isSummon;
+	private final L2PcInstance _activeChar;
 	
-	public AggroRangeEnter(Quest quest, L2Npc npc, L2PcInstance pc, boolean isSummon)
+	public OnNpcCanBeSeen(L2Npc npc, L2PcInstance activeChar)
 	{
-		_quest = quest;
 		_npc = npc;
-		_pc = pc;
-		_isSummon = isSummon;
+		_activeChar = activeChar;
+	}
+	
+	public L2Npc getNpc()
+	{
+		return _npc;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
 	}
 	
 	@Override
-	public void run()
+	public EventType getType()
 	{
-		String res = null;
-		try
-		{
-			res = _quest.onAggroRangeEnter(_npc, _pc, _isSummon);
-		}
-		catch (Exception e)
-		{
-			_quest.showError(_pc, e);
-		}
-		_quest.showResult(_pc, res);
+		return EventType.ON_NPC_CAN_BE_SEEN;
 	}
-}
+}

+ 25 - 32
L2J_Server_BETA/java/com/l2jserver/gameserver/model/quest/AITasks/SeeCreature.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcCreatureSee.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2014 L2J Server
+ * Copyright (C) 2004-2013 L2J Server
  * 
  * This file is part of L2J Server.
  * 
@@ -16,55 +16,48 @@
  * 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 com.l2jserver.gameserver.model.quest.AITasks;
+package com.l2jserver.gameserver.model.events.impl.character.npc;
 
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Npc;
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
- * See Creature AI task.
- * @author Zoey76
+ * An instantly executed event when L2Character is killed by L2Character.
+ * @author UnAfraid
  */
-public final class SeeCreature implements Runnable
+public class OnNpcCreatureSee implements IBaseEvent
 {
-	private final Quest _quest;
 	private final L2Npc _npc;
 	private final L2Character _creature;
 	private final boolean _isSummon;
 	
-	public SeeCreature(Quest quest, L2Npc npc, L2Character creature, boolean isSummon)
+	public OnNpcCreatureSee(L2Npc npc, L2Character creature, boolean isSummon)
 	{
-		_quest = quest;
 		_npc = npc;
 		_creature = creature;
 		_isSummon = isSummon;
 	}
 	
+	public final L2Npc getNpc()
+	{
+		return _npc;
+	}
+	
+	public final L2Character getCreature()
+	{
+		return _creature;
+	}
+	
+	public boolean isSummon()
+	{
+		return _isSummon;
+	}
+	
 	@Override
-	public void run()
+	public EventType getType()
 	{
-		L2PcInstance player = null;
-		if (_isSummon || _creature.isPlayer())
-		{
-			player = _creature.getActingPlayer();
-		}
-		String res = null;
-		try
-		{
-			res = _quest.onSeeCreature(_npc, _creature, _isSummon);
-		}
-		catch (Exception e)
-		{
-			if (player != null)
-			{
-				_quest.showError(player, e);
-			}
-		}
-		if (player != null)
-		{
-			_quest.showResult(player, res);
-		}
+		return EventType.ON_NPC_CREATURE_SEE;
 	}
 }

+ 69 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcEventReceived.java

@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.npc;
+
+import com.l2jserver.gameserver.model.L2Object;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnNpcEventReceived implements IBaseEvent
+{
+	private final String _eventName;
+	private final L2Npc _sender;
+	private final L2Npc _receiver;
+	private final L2Object _reference;
+	
+	public OnNpcEventReceived(String eventName, L2Npc sender, L2Npc receiver, L2Object reference)
+	{
+		_eventName = eventName;
+		_sender = sender;
+		_receiver = receiver;
+		_reference = reference;
+	}
+	
+	public String getEventName()
+	{
+		return _eventName;
+	}
+	
+	public L2Npc getSender()
+	{
+		return _sender;
+	}
+	
+	public L2Npc getReceiver()
+	{
+		return _receiver;
+	}
+	
+	public L2Object getReference()
+	{
+		return _reference;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_NPC_EVENT_RECEIVED;
+	}
+}

+ 55 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcFirstTalk.java

@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.npc;
+
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnNpcFirstTalk implements IBaseEvent
+{
+	private final L2Npc _npc;
+	private final L2PcInstance _activeChar;
+	
+	public OnNpcFirstTalk(L2Npc npc, L2PcInstance activeChar)
+	{
+		_npc = npc;
+		_activeChar = activeChar;
+	}
+	
+	public L2Npc getNpc()
+	{
+		return _npc;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_NPC_FIRST_TALK;
+	}
+}

+ 22 - 8
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/annotations/PlayerOnly.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcMoveFinished.java

@@ -16,18 +16,32 @@
  * 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 com.l2jserver.gameserver.model.actor.events.annotations;
+package com.l2jserver.gameserver.model.events.impl.character.npc;
 
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
  * @author UnAfraid
  */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface PlayerOnly
+public class OnNpcMoveFinished implements IBaseEvent
 {
+	private final L2Npc _npc;
+	
+	public OnNpcMoveFinished(L2Npc npc)
+	{
+		_npc = npc;
+	}
+	
+	public L2Npc getNpc()
+	{
+		return _npc;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_NPC_MOVE_FINISHED;
+	}
 }

+ 47 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcMoveNodeArrived.java

@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.npc;
+
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnNpcMoveNodeArrived implements IBaseEvent
+{
+	private final L2Npc _npc;
+	
+	public OnNpcMoveNodeArrived(L2Npc npc)
+	{
+		_npc = npc;
+	}
+	
+	public L2Npc getNpc()
+	{
+		return _npc;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_NPC_MOVE_NODE_ARRIVED;
+	}
+}

+ 47 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcMoveRouteFinished.java

@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.npc;
+
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnNpcMoveRouteFinished implements IBaseEvent
+{
+	private final L2Npc _npc;
+	
+	public OnNpcMoveRouteFinished(L2Npc npc)
+	{
+		_npc = npc;
+	}
+	
+	public L2Npc getNpc()
+	{
+		return _npc;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_NPC_MOVE_ROUTE_FINISHED;
+	}
+}

+ 63 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcSkillFinished.java

@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.npc;
+
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.skills.Skill;
+
+/**
+ * @author UnAfraid
+ */
+public class OnNpcSkillFinished implements IBaseEvent
+{
+	private final L2Npc _caster;
+	private final L2PcInstance _target;
+	private final Skill _skill;
+	
+	public OnNpcSkillFinished(L2Npc caster, L2PcInstance target, Skill skill)
+	{
+		_caster = caster;
+		_target = target;
+		_skill = skill;
+	}
+	
+	public L2PcInstance getTarget()
+	{
+		return _target;
+	}
+	
+	public L2Npc getCaster()
+	{
+		return _caster;
+	}
+	
+	public Skill getSkill()
+	{
+		return _skill;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_NPC_SKILL_FINISHED;
+	}
+}

+ 34 - 20
L2J_Server_BETA/java/com/l2jserver/gameserver/model/quest/AITasks/SkillSee.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcSkillSee.java

@@ -16,30 +16,28 @@
  * 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 com.l2jserver.gameserver.model.quest.AITasks;
+package com.l2jserver.gameserver.model.events.impl.character.npc;
 
 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.quest.Quest;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 import com.l2jserver.gameserver.model.skills.Skill;
 
 /**
- * Skill See AI task.
- * @author Zoey76
+ * @author UnAfraid
  */
-public class SkillSee implements Runnable
+public class OnNpcSkillSee implements IBaseEvent
 {
-	private final Quest _quest;
 	private final L2Npc _npc;
 	private final L2PcInstance _caster;
 	private final Skill _skill;
 	private final L2Object[] _targets;
 	private final boolean _isSummon;
 	
-	public SkillSee(Quest quest, L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
+	public OnNpcSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
 	{
-		_quest = quest;
 		_npc = npc;
 		_caster = caster;
 		_skill = skill;
@@ -47,18 +45,34 @@ public class SkillSee implements Runnable
 		_isSummon = isSummon;
 	}
 	
+	public L2Npc getTarget()
+	{
+		return _npc;
+	}
+	
+	public L2PcInstance getCaster()
+	{
+		return _caster;
+	}
+	
+	public Skill getSkill()
+	{
+		return _skill;
+	}
+	
+	public L2Object[] getTargets()
+	{
+		return _targets;
+	}
+	
+	public boolean isSummon()
+	{
+		return _isSummon;
+	}
+	
 	@Override
-	public void run()
+	public EventType getType()
 	{
-		String res = null;
-		try
-		{
-			res = _quest.onSkillSee(_npc, _caster, _skill, _targets, _isSummon);
-		}
-		catch (Exception e)
-		{
-			_quest.showError(_caster, e);
-		}
-		_quest.showResult(_caster, res);
+		return EventType.ON_NPC_SKILL_SEE;
 	}
-}
+}

+ 21 - 13
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/PlayerDespawnListener.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/OnNpcSpawn.java

@@ -16,31 +16,39 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+package com.l2jserver.gameserver.model.events.impl.character.npc;
 
-import com.l2jserver.gameserver.model.actor.events.AbstractCharEvents;
-import com.l2jserver.gameserver.model.actor.events.listeners.IPlayerLogoutEventListener;
-import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
- * @author TheOne
+ * @author UnAfraid
  */
-public abstract class PlayerDespawnListener extends L2JListener implements IPlayerLogoutEventListener
+public class OnNpcSpawn implements IBaseEvent
 {
-	public PlayerDespawnListener()
+	private final L2Npc _npc;
+	private final boolean _isTeleporting;
+	
+	public OnNpcSpawn(L2Npc npc, boolean isTeleporting)
 	{
-		register();
+		_npc = npc;
+		_isTeleporting = isTeleporting;
 	}
 	
-	@Override
-	public void register()
+	public L2Npc getNpc()
+	{
+		return _npc;
+	}
+	
+	public boolean isTeleporting()
 	{
-		AbstractCharEvents.registerStaticListener(this);
+		return _isTeleporting;
 	}
 	
 	@Override
-	public void unregister()
+	public EventType getType()
 	{
-		AbstractCharEvents.unregisterStaticListener(this);
+		return EventType.ON_NPC_SPAWN;
 	}
 }

+ 62 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/attackable/OnAttackableAggroRangeEnter.java

@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.npc.attackable;
+
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnAttackableAggroRangeEnter implements IBaseEvent
+{
+	private final L2Npc _npc;
+	private final L2PcInstance _activeChar;
+	private final boolean _isSummon;
+	
+	public OnAttackableAggroRangeEnter(L2Npc npc, L2PcInstance attacker, boolean isSummon)
+	{
+		_npc = npc;
+		_activeChar = attacker;
+		_isSummon = isSummon;
+	}
+	
+	public L2Npc getNpc()
+	{
+		return _npc;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public boolean isSummon()
+	{
+		return _isSummon;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_ATTACKABLE_AGGRO_RANGE_ENTER;
+	}
+}

+ 78 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/attackable/OnAttackableAttack.java

@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.npc.attackable;
+
+import com.l2jserver.gameserver.model.actor.L2Attackable;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.skills.Skill;
+
+/**
+ * An instantly executed event when L2Attackable is attacked by L2PcInstance.
+ * @author UnAfraid
+ */
+public class OnAttackableAttack implements IBaseEvent
+{
+	private final L2PcInstance _attacker;
+	private final L2Attackable _target;
+	private final int _damage;
+	private final Skill _skill;
+	private final boolean _isSummon;
+	
+	public OnAttackableAttack(L2PcInstance attacker, L2Attackable target, int damage, Skill skill, boolean isSummon)
+	{
+		_attacker = attacker;
+		_target = target;
+		_damage = damage;
+		_skill = skill;
+		_isSummon = isSummon;
+	}
+	
+	public final L2PcInstance getAttacker()
+	{
+		return _attacker;
+	}
+	
+	public final L2Attackable getTarget()
+	{
+		return _target;
+	}
+	
+	public int getDamage()
+	{
+		return _damage;
+	}
+	
+	public Skill getSkill()
+	{
+		return _skill;
+	}
+	
+	public boolean isSummon()
+	{
+		return _isSummon;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_ATTACKABLE_ATTACK;
+	}
+}

+ 69 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/attackable/OnAttackableFactionCall.java

@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.npc.attackable;
+
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnAttackableFactionCall implements IBaseEvent
+{
+	private final L2Npc _npc;
+	private final L2Npc _caller;
+	private final L2PcInstance _attacker;
+	private final boolean _isSummon;
+	
+	public OnAttackableFactionCall(L2Npc npc, L2Npc caller, L2PcInstance attacker, boolean isSummon)
+	{
+		_npc = npc;
+		_caller = caller;
+		_attacker = attacker;
+		_isSummon = isSummon;
+	}
+	
+	public L2Npc getNpc()
+	{
+		return _npc;
+	}
+	
+	public L2Npc getCaller()
+	{
+		return _caller;
+	}
+	
+	public L2PcInstance getAttacker()
+	{
+		return _attacker;
+	}
+	
+	public boolean isSummon()
+	{
+		return _isSummon;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_ATTACKABLE_FACTION_CALL;
+	}
+}

+ 62 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/attackable/OnAttackableHate.java

@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.npc.attackable;
+
+import com.l2jserver.gameserver.model.actor.L2Attackable;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnAttackableHate implements IBaseEvent
+{
+	private final L2Attackable _npc;
+	private final L2PcInstance _activeChar;
+	private final boolean _isSummon;
+	
+	public OnAttackableHate(L2Attackable npc, L2PcInstance activeChar, boolean isSummon)
+	{
+		_npc = npc;
+		_activeChar = activeChar;
+		_isSummon = isSummon;
+	}
+	
+	public final L2Attackable getNpc()
+	{
+		return _npc;
+	}
+	
+	public final L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public boolean isSummon()
+	{
+		return _isSummon;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_NPC_HATE;
+	}
+}

+ 63 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/npc/attackable/OnAttackableKill.java

@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.npc.attackable;
+
+import com.l2jserver.gameserver.model.actor.L2Attackable;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * An instantly executed event when L2Attackable is killed by L2PcInstance.
+ * @author UnAfraid
+ */
+public class OnAttackableKill implements IBaseEvent
+{
+	private final L2PcInstance _attacker;
+	private final L2Attackable _target;
+	private final boolean _isSummon;
+	
+	public OnAttackableKill(L2PcInstance attacker, L2Attackable target, boolean isSummon)
+	{
+		_attacker = attacker;
+		_target = target;
+		_isSummon = isSummon;
+	}
+	
+	public final L2PcInstance getAttacker()
+	{
+		return _attacker;
+	}
+	
+	public final L2Attackable getTarget()
+	{
+		return _target;
+	}
+	
+	public final boolean isSummon()
+	{
+		return _isSummon;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_ATTACKABLE_KILL;
+	}
+}

+ 35 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/ILevelChangeEventListener.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/playable/OnPlayableExpChanged.java

@@ -16,14 +16,46 @@
  * 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 com.l2jserver.gameserver.model.actor.events.listeners;
+package com.l2jserver.gameserver.model.events.impl.character.playable;
 
 import com.l2jserver.gameserver.model.actor.L2Playable;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
  * @author UnAfraid
  */
-public interface ILevelChangeEventListener extends IEventListener
+public class OnPlayableExpChanged implements IBaseEvent
 {
-	public boolean onLevelChange(L2Playable playable, byte levels);
+	private final L2Playable _activeChar;
+	private final long _oldExp;
+	private final long _newExp;
+	
+	public OnPlayableExpChanged(L2Playable activeChar, long oldExp, long newExp)
+	{
+		_activeChar = activeChar;
+		_oldExp = oldExp;
+		_newExp = newExp;
+	}
+	
+	public L2Playable getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public long getOldExp()
+	{
+		return _oldExp;
+	}
+	
+	public long getNewExp()
+	{
+		return _newExp;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYABLE_EXP_CHANGED;
+	}
 }

+ 70 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerAugment.java

@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.L2Augmentation;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerAugment implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final L2ItemInstance _item;
+	private final L2Augmentation _augmentation;
+	private final boolean _isAugment; // true = is being augmented // false = augment is being removed
+	
+	public OnPlayerAugment(L2PcInstance activeChar, L2ItemInstance item, L2Augmentation augment, boolean isAugment)
+	{
+		_activeChar = activeChar;
+		_item = item;
+		_augmentation = augment;
+		_isAugment = isAugment;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public L2ItemInstance getItem()
+	{
+		return _item;
+	}
+	
+	public L2Augmentation getAugmentation()
+	{
+		return _augmentation;
+	}
+	
+	public boolean isAugment()
+	{
+		return _isAugment;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_AUGMENT;
+	}
+}

+ 13 - 10
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/RequestBypassToServerEvent.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerBypass.java

@@ -16,22 +16,24 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.events;
+package com.l2jserver.gameserver.model.events.impl.character.player;
 
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
  * @author UnAfraid
  */
-public class RequestBypassToServerEvent implements L2Event
+public class OnPlayerBypass implements IBaseEvent
 {
-	private L2PcInstance _activeChar;
-	private String _command;
+	private final L2PcInstance _activeChar;
+	private final String _command;
 	
-	public void setActiveChar(L2PcInstance activeChar)
+	public OnPlayerBypass(L2PcInstance activeChar, String command)
 	{
 		_activeChar = activeChar;
+		_command = command;
 	}
 	
 	public L2PcInstance getActiveChar()
@@ -39,13 +41,14 @@ public class RequestBypassToServerEvent implements L2Event
 		return _activeChar;
 	}
 	
-	public void setCommand(String command)
+	public String getCommand()
 	{
-		_command = command;
+		return _command;
 	}
 	
-	public String getCommand()
+	@Override
+	public EventType getType()
 	{
-		return _command;
+		return EventType.ON_PLAYER_BYPASS;
 	}
 }

+ 68 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerChat.java

@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerChat implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final L2PcInstance _target;
+	private final String _text;
+	private final int _type;
+	
+	public OnPlayerChat(L2PcInstance activeChar, L2PcInstance target, String text, int type)
+	{
+		_activeChar = activeChar;
+		_target = target;
+		_text = text;
+		_type = type;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public L2PcInstance getTarget()
+	{
+		return _target;
+	}
+	
+	public String getText()
+	{
+		return _text;
+	}
+	
+	public int getChatType()
+	{
+		return _type;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_CHAT;
+	}
+}

+ 69 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerCreate.java

@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.network.L2GameClient;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerCreate implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final int _objectId;
+	private final String _name;
+	private final L2GameClient _client;
+	
+	public OnPlayerCreate(L2PcInstance activeChar, int objectId, String name, L2GameClient client)
+	{
+		_activeChar = activeChar;
+		_objectId = objectId;
+		_name = name;
+		_client = client;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public int getObjectId()
+	{
+		return _objectId;
+	}
+	
+	public String getName()
+	{
+		return _name;
+	}
+	
+	public L2GameClient getClient()
+	{
+		return _client;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_CREATE;
+	}
+}

+ 15 - 21
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/PlayerEvent.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerDelete.java

@@ -16,28 +16,26 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.events;
+package com.l2jserver.gameserver.model.events.impl.character.player;
 
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 import com.l2jserver.gameserver.network.L2GameClient;
-import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
 
 /**
  * @author UnAfraid
  */
-public class PlayerEvent implements L2Event
+public class OnPlayerDelete implements IBaseEvent
 {
-	private int _objectId;
-	private String _name;
-	private L2GameClient _client;
+	private final int _objectId;
+	private final String _name;
+	private final L2GameClient _client;
 	
-	public PlayerEvent()
-	{
-		
-	}
-	
-	public void setObjectId(int objectId)
+	public OnPlayerDelete(int objectId, String name, L2GameClient client)
 	{
 		_objectId = objectId;
+		_name = name;
+		_client = client;
 	}
 	
 	public int getObjectId()
@@ -45,23 +43,19 @@ public class PlayerEvent implements L2Event
 		return _objectId;
 	}
 	
-	public void setName(String name)
-	{
-		_name = name;
-	}
-	
 	public String getName()
 	{
 		return _name;
 	}
 	
-	public void setClient(L2GameClient client)
+	public L2GameClient getClient()
 	{
-		_client = client;
+		return _client;
 	}
 	
-	public L2GameClient getClient()
+	@Override
+	public EventType getType()
 	{
-		return _client;
+		return EventType.ON_PLAYER_DELETE;
 	}
 }

+ 18 - 28
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/DlgAnswerEvent.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerDlgAnswer.java

@@ -16,25 +16,28 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.events;
+package com.l2jserver.gameserver.model.events.impl.character.player;
 
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.network.SystemMessageId;
-import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
  * @author UnAfraid
  */
-public class DlgAnswerEvent implements L2Event
+public class OnPlayerDlgAnswer implements IBaseEvent
 {
-	private L2PcInstance _activeChar;
-	private int _messageId;
-	private int _answer;
-	private int _requesterId;
+	private final L2PcInstance _activeChar;
+	private final int _messageId;
+	private final int _answer;
+	private final int _requesterId;
 	
-	public void setActiveChar(L2PcInstance activeChar)
+	public OnPlayerDlgAnswer(L2PcInstance activeChar, int messageId, int answer, int requesterId)
 	{
 		_activeChar = activeChar;
+		_messageId = messageId;
+		_answer = answer;
+		_requesterId = requesterId;
 	}
 	
 	public L2PcInstance getActiveChar()
@@ -42,38 +45,25 @@ public class DlgAnswerEvent implements L2Event
 		return _activeChar;
 	}
 	
-	public void setMessageId(int messageId)
-	{
-		_messageId = messageId;
-	}
-	
 	public int getMessageId()
 	{
 		return _messageId;
 	}
 	
-	public SystemMessageId getSystemMessageId()
-	{
-		return SystemMessageId.getSystemMessageId(_messageId);
-	}
-	
-	public void setAnswer(int answer)
-	{
-		_answer = answer;
-	}
-	
 	public int getAnswer()
 	{
 		return _answer;
 	}
 	
-	public void setRequesterId(int req)
+	public int getRequesterId()
 	{
-		_requesterId = req;
+		return _requesterId;
 	}
 	
-	public int getRequesterId()
+	@Override
+	public EventType getType()
 	{
-		return _requesterId;
+		return EventType.ON_PLAYER_DLG_ANSWER;
 	}
+	
 }

+ 17 - 26
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/AddToInventoryEvent.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerEquipItem.java

@@ -16,49 +16,40 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.events;
+package com.l2jserver.gameserver.model.events.impl.character.player;
 
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
-import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
 
 /**
- * @author TheOne
+ * @author UnAfraid
  */
-public class AddToInventoryEvent implements L2Event
+public class OnPlayerEquipItem implements IBaseEvent
 {
-	private L2ItemInstance item;
-	private L2PcInstance player;
+	private final L2PcInstance _activeChar;
+	private final L2ItemInstance _item;
 	
-	/**
-	 * @return the item
-	 */
-	public L2ItemInstance getItem()
+	public OnPlayerEquipItem(L2PcInstance activeChar, L2ItemInstance item)
 	{
-		return item;
+		_activeChar = activeChar;
+		_item = item;
 	}
 	
-	/**
-	 * @param item the item to set
-	 */
-	public void setItem(L2ItemInstance item)
+	public L2PcInstance getActiveChar()
 	{
-		this.item = item;
+		return _activeChar;
 	}
 	
-	/**
-	 * @return the player
-	 */
-	public L2PcInstance getPlayer()
+	public L2ItemInstance getItem()
 	{
-		return player;
+		return _item;
 	}
 	
-	/**
-	 * @param player the player to set
-	 */
-	public void setPlayer(L2PcInstance player)
+	@Override
+	public EventType getType()
 	{
-		this.player = player;
+		return EventType.ON_PLAYER_EQUIP_ITEM;
 	}
 }

+ 61 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerFameChanged.java

@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerFameChanged implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final int _oldFame;
+	private final int _newFame;
+	
+	public OnPlayerFameChanged(L2PcInstance activeChar, int oldFame, int newFame)
+	{
+		_activeChar = activeChar;
+		_oldFame = oldFame;
+		_newFame = newFame;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public int getOldFame()
+	{
+		return _oldFame;
+	}
+	
+	public int getNewFame()
+	{
+		return _newFame;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_FAME_CHANGED;
+	}
+}

+ 55 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerHennaAdd.java

@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.items.L2Henna;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerHennaAdd implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final L2Henna _henna;
+	
+	public OnPlayerHennaAdd(L2PcInstance activeChar, L2Henna henna)
+	{
+		_activeChar = activeChar;
+		_henna = henna;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public L2Henna getHenna()
+	{
+		return _henna;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_HENNA_ADD;
+	}
+}

+ 16 - 42
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/HennaEvent.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerHennaRemove.java

@@ -16,66 +16,40 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.events;
+package com.l2jserver.gameserver.model.events.impl.character.player;
 
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 import com.l2jserver.gameserver.model.items.L2Henna;
-import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
 
 /**
- * @author TheOne
+ * @author UnAfraid
  */
-public class HennaEvent implements L2Event
+public class OnPlayerHennaRemove implements IBaseEvent
 {
-	private L2PcInstance player;
-	private L2Henna henna;
-	private boolean add;
+	private final L2PcInstance _activeChar;
+	private final L2Henna _henna;
 	
-	/**
-	 * @return the player
-	 */
-	public L2PcInstance getPlayer()
+	public OnPlayerHennaRemove(L2PcInstance activeChar, L2Henna henna)
 	{
-		return player;
+		_activeChar = activeChar;
+		_henna = henna;
 	}
 	
-	/**
-	 * @param p the player to set
-	 */
-	public void setPlayer(L2PcInstance p)
+	public L2PcInstance getActiveChar()
 	{
-		player = p;
+		return _activeChar;
 	}
 	
-	/**
-	 * @return the henna
-	 */
 	public L2Henna getHenna()
 	{
-		return henna;
+		return _henna;
 	}
 	
-	/**
-	 * @param h
-	 */
-	public void setHenna(L2Henna h)
+	@Override
+	public EventType getType()
 	{
-		henna = h;
-	}
-	
-	/**
-	 * @return the add
-	 */
-	public boolean isAdd()
-	{
-		return add;
-	}
-	
-	/**
-	 * @param add the add to set
-	 */
-	public void setAdd(boolean add)
-	{
-		this.add = add;
+		return EventType.ON_PLAYER_HENNA_REMOVE;
 	}
 }

+ 61 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerKarmaChanged.java

@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerKarmaChanged implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final int _oldKarma;
+	private final int _newKarma;
+	
+	public OnPlayerKarmaChanged(L2PcInstance activeChar, int oldKarma, int newKarma)
+	{
+		_activeChar = activeChar;
+		_oldKarma = oldKarma;
+		_newKarma = newKarma;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public int getOldKarma()
+	{
+		return _oldKarma;
+	}
+	
+	public int getNewKarma()
+	{
+		return _newKarma;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_KARMA_CHANGED;
+	}
+}

+ 61 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerLevelChanged.java

@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerLevelChanged implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final int _oldLevel;
+	private final int _newLevel;
+	
+	public OnPlayerLevelChanged(L2PcInstance activeChar, int oldLevel, int newLevel)
+	{
+		_activeChar = activeChar;
+		_oldLevel = oldLevel;
+		_newLevel = newLevel;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public int getOldLevel()
+	{
+		return _oldLevel;
+	}
+	
+	public int getNewLevel()
+	{
+		return _newLevel;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_LEVEL_CHANGED;
+	}
+}

+ 21 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IFamePointsChangeEventListener.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerLogin.java

@@ -16,14 +16,32 @@
  * 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 com.l2jserver.gameserver.model.actor.events.listeners;
+package com.l2jserver.gameserver.model.events.impl.character.player;
 
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
  * @author UnAfraid
  */
-public interface IFamePointsChangeEventListener extends IEventListener
+public class OnPlayerLogin implements IBaseEvent
 {
-	public boolean onFamePointsChange(L2PcInstance player, int oldFame, int newFame);
+	private final L2PcInstance _activeChar;
+	
+	public OnPlayerLogin(L2PcInstance activeChar)
+	{
+		_activeChar = activeChar;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_LOGIN;
+	}
 }

+ 21 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IPKPointsChangeEventListener.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerLogout.java

@@ -16,14 +16,32 @@
  * 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 com.l2jserver.gameserver.model.actor.events.listeners;
+package com.l2jserver.gameserver.model.events.impl.character.player;
 
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
  * @author UnAfraid
  */
-public interface IPKPointsChangeEventListener extends IEventListener
+public class OnPlayerLogout implements IBaseEvent
 {
-	public boolean onPKPointsChange(L2PcInstance player, int oldPKPoints, int newPKPoints);
+	private final L2PcInstance _activeChar;
+	
+	public OnPlayerLogout(L2PcInstance activeChar)
+	{
+		_activeChar = activeChar;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_LOGOUT;
+	}
 }

+ 61 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerPKChanged.java

@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerPKChanged implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final int _oldPoints;
+	private final int _newPoints;
+	
+	public OnPlayerPKChanged(L2PcInstance activeChar, int oldPoints, int newPoints)
+	{
+		_activeChar = activeChar;
+		_oldPoints = oldPoints;
+		_newPoints = newPoints;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public int getOldPoints()
+	{
+		return _oldPoints;
+	}
+	
+	public int getNewPoints()
+	{
+		return _newPoints;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_PK_CHANGED;
+	}
+}

+ 21 - 40
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/events/ProfessionChangeEvent.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerProfessionChange.java

@@ -16,66 +16,47 @@
  * 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 com.l2jserver.gameserver.scripting.scriptengine.events;
+package com.l2jserver.gameserver.model.events.impl.character.player;
 
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.templates.L2PcTemplate;
-import com.l2jserver.gameserver.scripting.scriptengine.events.impl.L2Event;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
- * @author TheOne
+ * @author UnAfraid
  */
-public class ProfessionChangeEvent implements L2Event
+public class OnPlayerProfessionChange implements IBaseEvent
 {
-	private L2PcInstance player;
-	private boolean isSubClass;
-	private L2PcTemplate template;
+	private final L2PcInstance _activeChar;
+	private final L2PcTemplate _template;
+	private final boolean _isSubClass;
 	
-	/**
-	 * @return the player
-	 */
-	public L2PcInstance getPlayer()
+	public OnPlayerProfessionChange(L2PcInstance activeChar, L2PcTemplate template, boolean isSubClass)
 	{
-		return player;
+		_activeChar = activeChar;
+		_template = template;
+		_isSubClass = isSubClass;
 	}
 	
-	/**
-	 * @param player the player to set
-	 */
-	public void setPlayer(L2PcInstance player)
+	public L2PcInstance getActiveChar()
 	{
-		this.player = player;
+		return _activeChar;
 	}
 	
-	/**
-	 * @return the isSubClass
-	 */
-	public boolean isSubClass()
-	{
-		return isSubClass;
-	}
-	
-	/**
-	 * @param isSubClass the isSubClass to set
-	 */
-	public void setSubClass(boolean isSubClass)
+	public L2PcTemplate getTemplate()
 	{
-		this.isSubClass = isSubClass;
+		return _template;
 	}
 	
-	/**
-	 * @return the template
-	 */
-	public L2PcTemplate getTemplate()
+	public boolean isSubClass()
 	{
-		return template;
+		return _isSubClass;
 	}
 	
-	/**
-	 * @param template the template to set
-	 */
-	public void setTemplate(L2PcTemplate template)
+	@Override
+	public EventType getType()
 	{
-		this.template = template;
+		return EventType.ON_PLAYER_PROFESSION_CHANGE;
 	}
 }

+ 61 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerPvPChanged.java

@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerPvPChanged implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final int _oldPoints;
+	private final int _newPoints;
+	
+	public OnPlayerPvPChanged(L2PcInstance activeChar, int oldPoints, int newPoints)
+	{
+		_activeChar = activeChar;
+		_oldPoints = oldPoints;
+		_newPoints = newPoints;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public int getOldPoints()
+	{
+		return _oldPoints;
+	}
+	
+	public int getNewPoints()
+	{
+		return _newPoints;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_PVP_CHANGED;
+	}
+}

+ 28 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/listeners/IKarmaChangeEventListener.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerPvPKill.java

@@ -16,14 +16,39 @@
  * 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 com.l2jserver.gameserver.model.actor.events.listeners;
+package com.l2jserver.gameserver.model.events.impl.character.player;
 
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
  * @author UnAfraid
  */
-public interface IKarmaChangeEventListener extends IEventListener
+public class OnPlayerPvPKill implements IBaseEvent
 {
-	public boolean onKarmaChange(L2PcInstance player, int oldKarma, int newKarma);
+	private final L2PcInstance _activeChar;
+	private final L2PcInstance _target;
+	
+	public OnPlayerPvPKill(L2PcInstance activeChar, L2PcInstance target)
+	{
+		_activeChar = activeChar;
+		_target = target;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public L2PcInstance getTarget()
+	{
+		return _target;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_PVP_KILL;
+	}
 }

+ 61 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerRestore.java

@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.network.L2GameClient;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerRestore implements IBaseEvent
+{
+	private final int _objectId;
+	private final String _name;
+	private final L2GameClient _client;
+	
+	public OnPlayerRestore(int objectId, String name, L2GameClient client)
+	{
+		_objectId = objectId;
+		_name = name;
+		_client = client;
+	}
+	
+	public int getObjectId()
+	{
+		return _objectId;
+	}
+	
+	public String getName()
+	{
+		return _name;
+	}
+	
+	public L2GameClient getClient()
+	{
+		return _client;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_RESTORE;
+	}
+}

+ 69 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerSelect.java

@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.network.L2GameClient;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerSelect implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final int _objectId;
+	private final String _name;
+	private final L2GameClient _client;
+	
+	public OnPlayerSelect(L2PcInstance activeChar, int objectId, String name, L2GameClient client)
+	{
+		_activeChar = activeChar;
+		_objectId = objectId;
+		_name = name;
+		_client = client;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public int getObjectId()
+	{
+		return _objectId;
+	}
+	
+	public String getName()
+	{
+		return _name;
+	}
+	
+	public L2GameClient getClient()
+	{
+		return _client;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_SELECT;
+	}
+}

+ 71 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerSkillLearn.java

@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.base.AcquireSkillType;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+import com.l2jserver.gameserver.model.skills.Skill;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerSkillLearn implements IBaseEvent
+{
+	private final L2Npc _trainer;
+	private final L2PcInstance _activeChar;
+	private final Skill _skill;
+	private final AcquireSkillType _type;
+	
+	public OnPlayerSkillLearn(L2Npc trainer, L2PcInstance activeChar, Skill skill, AcquireSkillType type)
+	{
+		_trainer = trainer;
+		_activeChar = activeChar;
+		_skill = skill;
+		_type = type;
+	}
+	
+	public L2Npc getTrainer()
+	{
+		return _trainer;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public Skill getSkill()
+	{
+		return _skill;
+	}
+	
+	public AcquireSkillType getAcquireType()
+	{
+		return _type;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_SKILL_LEARN;
+	}
+}

+ 15 - 7
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/events/SummonEvents.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerSummonSpawn.java

@@ -16,24 +16,32 @@
  * 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 com.l2jserver.gameserver.model.actor.events;
+package com.l2jserver.gameserver.model.events.impl.character.player;
 
-import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
 
 /**
  * @author UnAfraid
  */
-public class SummonEvents extends PlayableEvents
+public class OnPlayerSummonSpawn implements IBaseEvent
 {
-	public SummonEvents(L2Playable activeChar)
+	private final L2Summon _summon;
+	
+	public OnPlayerSummonSpawn(L2Summon summon)
+	{
+		_summon = summon;
+	}
+	
+	public L2Summon getSummon()
 	{
-		super(activeChar);
+		return _summon;
 	}
 	
 	@Override
-	public L2Summon getActingPlayer()
+	public EventType getType()
 	{
-		return (L2Summon) super.getActingPlayer();
+		return EventType.ON_PLAYER_SUMMON_SPAWN;
 	}
 }

+ 54 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/events/impl/character/player/OnPlayerTransform.java

@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2004-2014 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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 Server 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 com.l2jserver.gameserver.model.events.impl.character.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.events.EventType;
+import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
+
+/**
+ * @author UnAfraid
+ */
+public class OnPlayerTransform implements IBaseEvent
+{
+	private final L2PcInstance _activeChar;
+	private final int _transformId;
+	
+	public OnPlayerTransform(L2PcInstance activeChar, int transformId)
+	{
+		_activeChar = activeChar;
+		_transformId = transformId;
+	}
+	
+	public L2PcInstance getActiveChar()
+	{
+		return _activeChar;
+	}
+	
+	public int getTransformId()
+	{
+		return _transformId;
+	}
+	
+	@Override
+	public EventType getType()
+	{
+		return EventType.ON_PLAYER_TRANSFORM;
+	}
+}

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác