Ver Fonte

BETA: Implementation of Listeners thanks theone
A bit cleaned and tweaked by me and Zoey76.

Rumen Nikiforov há 13 anos atrás
pai
commit
3d5d7b168a
38 ficheiros alterados com 4325 adições e 42 exclusões
  1. 35 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/ItemTable.java
  2. 117 10
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/ClanWarehouse.java
  3. 130 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Clan.java
  4. 207 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java
  5. 230 12
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
  6. 61 4
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
  7. 36 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/FortSiege.java
  8. 40 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Siege.java
  9. 54 9
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/TvTEvent.java
  10. 70 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemcontainer/PcInventory.java
  11. 73 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/instance/L2ItemInstance.java
  12. 32 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java
  13. 99 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/Say2.java
  14. 53 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/impl/L2JListener.java
  15. 1496 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/impl/L2Script.java
  16. 73 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/character/AttackListener.java
  17. 96 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/character/DeathListener.java
  18. 118 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/character/SkillUseListener.java
  19. 56 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/clan/ClanCreationListener.java
  20. 68 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/clan/ClanMembershipListener.java
  21. 58 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/clan/ClanWarListener.java
  22. 87 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/clan/ClanWarehouseListener.java
  23. 54 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/FortSiegeListener.java
  24. 60 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/SiegeListener.java
  25. 67 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/TvTListener.java
  26. 60 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/AugmentListener.java
  27. 65 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/DropListener.java
  28. 79 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/EquipmentListener.java
  29. 58 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/HennaListener.java
  30. 91 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/ItemTracker.java
  31. 61 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/NewItemListener.java
  32. 43 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/PlayerDespawnListener.java
  33. 63 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/PlayerLevelListener.java
  34. 50 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/PlayerSpawnListener.java
  35. 62 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/ProfessionChangeListener.java
  36. 63 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/TransformListener.java
  37. 55 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/talk/ChatFilterListener.java
  38. 105 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/talk/ChatListener.java

+ 35 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/ItemTable.java

@@ -25,6 +25,7 @@ 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;
@@ -46,6 +47,7 @@ import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance.ItemLocation;
 import com.l2jserver.gameserver.model.items.type.L2ArmorType;
 import com.l2jserver.gameserver.model.items.type.L2WeaponType;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.NewItemListener;
 import com.l2jserver.gameserver.util.GMAudit;
 
 /**
@@ -58,6 +60,8 @@ 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> _materials = new FastMap<String, Integer>();
 	public static final Map<String, Integer> _crystalTypes = new FastMap<String, Integer>();
 	public static final Map<String, Integer> _slots = new FastMap<String, Integer>();
@@ -245,7 +249,7 @@ public class ItemTable
 	 */
 	public L2Item getTemplate(int id)
 	{
-		if (id >= _allTemplates.length)
+		if (id >= _allTemplates.length || id < 0)
 			return null;
 		
 		return _allTemplates[id];
@@ -268,6 +272,14 @@ public class ItemTable
 	 */
 	public L2ItemInstance createItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
 	{
+		for (NewItemListener listener : newItemListeners)
+		{
+			if (listener.containsItemId(itemId))
+			{
+				if (!listener.onCreate(itemId, actor))
+					return null;
+			}
+		}
 		// Create and Init the L2ItemInstance corresponding to the Item Identifier
 		L2ItemInstance item = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
 		
@@ -479,4 +491,26 @@ public class ItemTable
 	{
 		protected static final ItemTable _instance = new ItemTable();
 	}
+	
+	// Listeners
+	/**
+	 * 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);
+	}
 }

+ 117 - 10
L2J_Server_BETA/java/com/l2jserver/gameserver/model/ClanWarehouse.java

@@ -14,37 +14,144 @@
  */
 package com.l2jserver.gameserver.model;
 
+import javolution.util.FastList;
+
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.itemcontainer.ItemContainer;
 import com.l2jserver.gameserver.model.itemcontainer.Warehouse;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance.ItemLocation;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.clan.ClanWarehouseListener;
 
 public final class ClanWarehouse extends Warehouse
 {
-	//private static final Logger _log = Logger.getLogger(PcWarehouse.class.getName());
-	
 	private L2Clan _clan;
 	
+	private FastList<ClanWarehouseListener> clanWarehouseListeners = new FastList<ClanWarehouseListener>().shared();
+	
 	public ClanWarehouse(L2Clan clan)
 	{
 		_clan = clan;
 	}
 	
 	@Override
-	public String getName() { return "ClanWarehouse"; }
+	public String getName()
+	{
+		return "ClanWarehouse";
+	}
 	
 	@Override
-	public int getOwnerId() { return _clan.getClanId(); }
+	public int getOwnerId()
+	{
+		return _clan.getClanId();
+	}
+	
 	@Override
-	public L2PcInstance getOwner() { return _clan.getLeader().getPlayerInstance(); }
+	public L2PcInstance getOwner()
+	{
+		return _clan.getLeader().getPlayerInstance();
+	}
+	
 	@Override
-	public ItemLocation getBaseLocation() { return ItemLocation.CLANWH; }
-	public String getLocationId() { return "0"; }
-	public int getLocationId(boolean dummy) { return 0; }
-	public void setLocationId(L2PcInstance dummy) { }
+	public ItemLocation getBaseLocation()
+	{
+		return ItemLocation.CLANWH;
+	}
+	
+	public String getLocationId()
+	{
+		return "0";
+	}
+	
+	public int getLocationId(boolean dummy)
+	{
+		return 0;
+	}
+	
+	public void setLocationId(L2PcInstance dummy)
+	{
+	}
+	
 	@Override
 	public boolean validateCapacity(int slots)
 	{
 		return (_items.size() + slots <= Config.WAREHOUSE_SLOTS_CLAN);
 	}
-}
+	
+	@Override
+	public L2ItemInstance addItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
+	{
+		L2ItemInstance item = getItemByItemId(itemId);
+		for (ClanWarehouseListener listener : clanWarehouseListeners)
+		{
+			if (!listener.onAddItem(process, item, actor))
+			{
+				return null;
+			}
+		}
+		return super.addItem(process, item, actor, reference);
+	}
+	
+	@Override
+	public L2ItemInstance addItem(String process, L2ItemInstance item, L2PcInstance actor, Object reference)
+	{
+		for (ClanWarehouseListener listener : clanWarehouseListeners)
+		{
+			if (!listener.onAddItem(process, item, actor))
+			{
+				return null;
+			}
+		}
+		return super.addItem(process, item, actor, reference);
+	}
+	
+	@Override
+	public L2ItemInstance destroyItem(String process, L2ItemInstance item, long count, L2PcInstance actor, Object reference)
+	{
+		for (ClanWarehouseListener listener : clanWarehouseListeners)
+		{
+			if (!listener.onDeleteItem(process, item, count, actor))
+			{
+				return null;
+			}
+		}
+		return super.destroyItem(process, item, count, actor, reference);
+	}
+	
+	@Override
+	public L2ItemInstance transferItem(String process, int objectId, long count, ItemContainer target, L2PcInstance actor, Object reference)
+	{
+		L2ItemInstance sourceitem = getItemByObjectId(objectId);
+		for (ClanWarehouseListener listener : clanWarehouseListeners)
+		{
+			if (!listener.onTransferItem(process, sourceitem, count, target, actor))
+			{
+				return null;
+			}
+		}
+		return super.transferItem(process, objectId, count, target, actor, reference);
+	}
+	
+	// Listeners
+	/**
+	 * Adds a clan warehouse listener
+	 * @param listener
+	 */
+	public void addWarehouseListener(ClanWarehouseListener listener)
+	{
+		if (!clanWarehouseListeners.contains(listener))
+		{
+			clanWarehouseListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a clan warehouse listener
+	 * @param listener
+	 */
+	public void removeWarehouseListener(ClanWarehouseListener listener)
+	{
+		clanWarehouseListeners.remove(listener);
+	}
+}

+ 130 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Clan.java

@@ -63,6 +63,9 @@ import com.l2jserver.gameserver.network.serverpackets.SkillCoolTime;
 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.listeners.clan.ClanCreationListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.clan.ClanMembershipListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.clan.ClanWarListener;
 import com.l2jserver.gameserver.util.Util;
 
 /**
@@ -74,6 +77,10 @@ public class L2Clan
 {
 	private static final Logger _log = Logger.getLogger(L2Clan.class.getName());
 	
+	private static FastList<ClanCreationListener> clanCreationListeners = new FastList<ClanCreationListener>().shared();
+	private static FastList<ClanMembershipListener> clanMembershipListeners = new FastList<ClanMembershipListener>().shared();
+	private static FastList<ClanWarListener> clanWarListeners = new FastList<ClanWarListener>().shared();
+	
 	private String _name;
 	private int _clanId;
 	private L2ClanMember _leader;
@@ -199,6 +206,10 @@ public class L2Clan
 		_clanId = clanId;
 		_name = clanName;
 		initializePrivs();
+		for (ClanCreationListener listener : clanCreationListeners)
+		{
+			listener.onClanCreate(this);
+		}
 	}
 	
 	/**
@@ -258,6 +269,16 @@ public class L2Clan
 		}
 		
 		L2PcInstance exLeader = getLeader().getPlayerInstance();
+		L2PcInstance newLeader = member.getPlayerInstance();
+		
+		for (ClanMembershipListener listener : clanMembershipListeners)
+		{
+			if (!listener.onLeaderChange(this, newLeader, exLeader))
+			{
+				return;
+			}
+		}
+		
 		SiegeManager.getInstance().removeSiegeSkills(exLeader);
 		exLeader.setClan(this);
 		exLeader.setClanPrivileges(L2Clan.CP_NOTHING);
@@ -269,7 +290,6 @@ public class L2Clan
 		exLeader.setPledgeClass(exLeader.getClan().getClanMember(exLeader.getObjectId()).calculatePledgeClass(exLeader));
 		exLeader.broadcastUserInfo();
 		exLeader.checkItemRestriction();
-		L2PcInstance newLeader = member.getPlayerInstance();
 		newLeader.setClan(this);
 		newLeader.setPledgeClass(member.calculatePledgeClass(newLeader));
 		newLeader.setClanPrivileges(L2Clan.CP_ALL);
@@ -348,6 +368,14 @@ public class L2Clan
 	 */
 	public void addClanMember(L2PcInstance player)
 	{
+		for (ClanMembershipListener listener : clanMembershipListeners)
+		{
+			if (!listener.onJoin(player, this))
+			{
+				return;
+			}
+		}
+		
 		final L2ClanMember member = new L2ClanMember(this, player);
 		// store in memory
 		addClanMember(member);
@@ -405,6 +433,14 @@ public class L2Clan
 	 */
 	public void removeClanMember(int objectId, long clanJoinExpiryTime)
 	{
+		for (ClanMembershipListener listener : clanMembershipListeners)
+		{
+			if (!listener.onLeave(objectId, this))
+			{
+				return;
+			}
+		}
+		
 		final L2ClanMember exMember = _members.remove(objectId);
 		if (exMember == null)
 		{
@@ -1460,12 +1496,26 @@ public class L2Clan
 	
 	public void setEnemyClan(L2Clan clan)
 	{
+		for (ClanWarListener listener : clanWarListeners)
+		{
+			if (!listener.onWarStart(this, clan))
+			{
+				return;
+			}
+		}
 		Integer id = clan.getClanId();
 		_atWarWith.add(id);
 	}
 	
 	public void setEnemyClan(Integer clan)
 	{
+		for (ClanWarListener listener : clanWarListeners)
+		{
+			if (!listener.onWarStart(this, ClanTable.getInstance().getClan(clan)))
+			{
+				return;
+			}
+		}
 		_atWarWith.add(clan);
 	}
 	
@@ -1482,6 +1532,13 @@ public class L2Clan
 	
 	public void deleteEnemyClan(L2Clan clan)
 	{
+		for (ClanWarListener listener : clanWarListeners)
+		{
+			if (!listener.onWarEnd(this, clan))
+			{
+				return;
+			}
+		}
 		Integer id = clan.getClanId();
 		_atWarWith.remove(id);
 	}
@@ -2393,6 +2450,14 @@ public class L2Clan
 		
 		boolean increaseClanLevel = false;
 		
+		for (ClanCreationListener listener : clanCreationListeners)
+		{
+			if (!listener.onClanLevelUp(this, getLevel()))
+			{
+				return false;
+			}
+		}
+		
 		switch (getLevel())
 		{
 			case 0:
@@ -2865,4 +2930,68 @@ public class L2Clan
 		FastList.recycle(list);
 		return result;
 	}
+	
+	// Listeners
+	/**
+	 * 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);
+	}
+	
+	/**
+	 * 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);
+	}
 }

+ 207 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java

@@ -59,6 +59,7 @@ import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.L2WorldRegion;
 import com.l2jserver.gameserver.model.Location;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2NpcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2NpcWalkerInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance.SkillDat;
@@ -114,6 +115,9 @@ import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 import com.l2jserver.gameserver.network.serverpackets.TeleportToLocation;
 import com.l2jserver.gameserver.pathfinding.AbstractNodeLoc;
 import com.l2jserver.gameserver.pathfinding.PathFinding;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.character.AttackListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.character.DeathListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.character.SkillUseListener;
 import com.l2jserver.gameserver.taskmanager.AttackStanceTaskManager;
 import com.l2jserver.gameserver.util.L2TIntObjectHashMap;
 import com.l2jserver.gameserver.util.Point3D;
@@ -144,6 +148,12 @@ public abstract class L2Character extends L2Object
 {
 	public static final Logger _log = Logger.getLogger(L2Character.class.getName());
 	
+	private FastList<AttackListener> attackListeners = new FastList<AttackListener>().shared();
+	private FastList<DeathListener> deathListeners = new FastList<DeathListener>().shared();
+	private static FastList<DeathListener> globalDeathListeners = new FastList<DeathListener>().shared();
+	private static FastList<SkillUseListener> globalSkillUseListeners = new FastList<SkillUseListener>().shared();
+	private FastList<SkillUseListener> skillUseListeners = new FastList<SkillUseListener>().shared();
+	
 	private Set<L2Character> _attackByList;
 	private volatile boolean _isCastingNow = false;
 	private volatile boolean _isCastingSimultaneouslyNow = false;
@@ -756,10 +766,28 @@ public abstract class L2Character extends L2Object
 	 */
 	protected void doAttack(L2Character target)
 	{
+		if (target == null)
+		{
+			return;
+		}
+		for (AttackListener listener : attackListeners)
+		{
+			if (!listener.onAttack(target))
+			{
+				return;
+			}
+		}
+		for (AttackListener listener : target.getAttackListeners())
+		{
+			if (!listener.isAttacked(this))
+			{
+				return;
+			}
+		}
 		if (Config.DEBUG)
 			_log.fine(getName() + " doAttack: target=" + target);
 		
-		if (!isAlikeDead() && target != null)
+		if (!isAlikeDead())
 		{
 			if (this instanceof L2Npc && target.isAlikeDead() || !getKnownList().knowsObject(target))
 			{
@@ -1600,6 +1628,7 @@ public abstract class L2Character extends L2Object
 			}
 			return;
 		}
+
 		// Override casting type
 		if (skill.isSimultaneousCast() && !simultaneously)
 			simultaneously = true;
@@ -1719,7 +1748,32 @@ public abstract class L2Character extends L2Object
 			}
 			return;
 		}
-		
+		for(SkillUseListener listener : skillUseListeners)
+		{
+			int skillId = skill.getId();
+			if(listener.getSkillId() == -1 || skillId == listener.getSkillId())
+			{
+				if(!listener.onSkillUse(skill, this, targets))
+				{
+					return;
+				}
+			}
+		}
+		for(SkillUseListener listener : globalSkillUseListeners)
+		{
+			int npcId = listener.getNpcId();
+			int skillId = listener.getSkillId();
+			boolean skillOk = skillId == -1 || skillId == skill.getId();
+			boolean charOk = (npcId == -1 && this instanceof L2NpcInstance) || (npcId == -2 && this instanceof L2PcInstance) || 
+				npcId == -3 || (this instanceof L2NpcInstance && ((L2NpcInstance)this).getNpcId() == npcId);
+			if(skillOk && charOk)
+			{
+				if(!listener.onSkillUse(skill, this, targets))
+				{
+					return;
+				}
+			}
+		}
 		if (skill.getSkillType() == L2SkillType.RESURRECT)
 		{
 			if (isResurrectionBlocked() || target.isResurrectionBlocked())
@@ -2241,6 +2295,32 @@ public abstract class L2Character extends L2Object
 			setIsDead(true);
 		}
 		
+		for (DeathListener listener : deathListeners)
+		{
+			if (!listener.onDeath(this, killer))
+			{
+				return false;
+			}
+		}
+		for (DeathListener listener : killer.getDeathListeners())
+		{
+			if (!listener.onKill(this, killer))
+			{
+				return false;
+			}
+		}
+		for (DeathListener listener : globalDeathListeners)
+		{
+			if (killer instanceof L2PcInstance || this instanceof L2PcInstance)
+			{
+				if (!listener.onDeath(this, killer))
+				{
+					return false;
+				}
+				
+			}
+		}
+		
 		// Set target to null and cancel Attack or Cast
 		setTarget(null);
 		
@@ -7532,4 +7612,129 @@ public abstract class L2Character extends L2Object
 			_team = id;
 		}
 	}
+	
+	// LISTENERS
+	/**
+	 * Adds an attack listener
+	 * @param listener
+	 */
+	public void addAttackListener(AttackListener listener)
+	{
+		if (!attackListeners.contains(listener))
+		{
+			attackListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes an attack listener
+	 * @param listener
+	 */
+	public void removeAttackListener(AttackListener listener)
+	{
+		attackListeners.remove(listener);
+	}
+	
+	/**
+	 * Returns the attack listeners
+	 * @return
+	 */
+	public List<AttackListener> getAttackListeners()
+	{
+		return attackListeners;
+	}
+	
+	/**
+	 * Adds a death listener.<br>
+	 * Triggered when this char kills another char, and when this char gets killed by another char.
+	 * @param listener
+	 */
+	public void addDeathListener(DeathListener listener)
+	{
+		if (!deathListeners.contains(listener))
+		{
+			deathListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * removes a death listener
+	 * @param listener
+	 */
+	public void removeDeathListener(DeathListener listener)
+	{
+		deathListeners.remove(listener);
+	}
+	
+	/**
+	 * Returns the death listeners
+	 * @return
+	 */
+	public List<DeathListener> getDeathListeners()
+	{
+		return deathListeners;
+	}
+	
+	/**
+	 * Adds a global death listener
+	 * @param listener
+	 */
+	public static void addGlobalDeathListener(DeathListener listener)
+	{
+		if (!globalDeathListeners.contains(listener))
+		{
+			globalDeathListeners.remove(listener);
+		}
+	}
+	
+	/**
+	 * Removes a global death listener
+	 * @param listener
+	 */
+	public static void removeGlobalDeathListener(DeathListener listener)
+	{
+		globalDeathListeners.remove(listener);
+	}
+	
+	/**
+	 * Adds a skill use listener
+	 * @param listener
+	 */
+	public void addSkillUseListener(SkillUseListener listener)
+	{
+		if (!skillUseListeners.contains(listener))
+		{
+			skillUseListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a skill use listener
+	 * @param listener
+	 */
+	public void removeSkillUseListener(SkillUseListener listener)
+	{
+		skillUseListeners.remove(listener);
+	}
+	
+	/**
+	 * Adds a global skill use listener
+	 * @param listener
+	 */
+	public static void addGlobalSkillUseListener(SkillUseListener listener)
+	{
+		if (!globalSkillUseListeners.contains(listener))
+		{
+			globalSkillUseListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a global skill use listener
+	 * @param listener
+	 */
+	public static void removeGlobalSkillUseListener(SkillUseListener listener)
+	{
+		globalSkillUseListeners.remove(listener);
+	}
 }

+ 230 - 12
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -271,6 +271,11 @@ import com.l2jserver.gameserver.network.serverpackets.TradeDone;
 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.scripting.scriptengine.listeners.player.EquipmentListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.HennaListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.PlayerDespawnListener;
+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.FloodProtectors;
 import com.l2jserver.gameserver.util.L2TIntObjectHashMap;
@@ -347,6 +352,15 @@ public final class L2PcInstance extends L2Playable
 	public static final int STORE_PRIVATE_MANUFACTURE = 5;
 	public static final int STORE_PRIVATE_PACKAGE_SELL = 8;
 	
+	public static FastList<PlayerDespawnListener> despawnListeners = new FastList<PlayerDespawnListener>().shared();
+	public static FastList<HennaListener> hennaListeners = new FastList<HennaListener>().shared();
+	public FastList<EquipmentListener> equipmentListeners = new FastList<EquipmentListener>().shared();
+	public static FastList<EquipmentListener> globalEquipmentListeners = new FastList<EquipmentListener>().shared();
+	public FastList<TransformListener> transformListeners = new FastList<TransformListener>().shared();
+	public FastList<ProfessionChangeListener> professionChangeListeners = new FastList<ProfessionChangeListener>().shared();
+	public static FastList<ProfessionChangeListener> globalProfessionChangeListeners = new FastList<ProfessionChangeListener>().shared();
+
+	
 	public class AIAccessor extends L2Character.AIAccessor
 	{
 		protected AIAccessor()
@@ -1425,6 +1439,10 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public void logout()
 	{
+		for(PlayerDespawnListener listener : despawnListeners)
+		{
+			listener.onDespawn(this);
+		}
 		logout(true);
 	}
 	
@@ -2484,6 +2502,16 @@ public final class L2PcInstance extends L2Playable
 		
 		if (isEquiped)
 		{
+			for(EquipmentListener listener : equipmentListeners)
+			{
+				if(!listener.onEquip(item, false))
+					return;
+			}
+			for(EquipmentListener listener : globalEquipmentListeners)
+			{
+				if(!listener.onEquip(item, false))
+					return;
+			}
 			if (item.getEnchantLevel() > 0)
 			{
 				sm = SystemMessage.getSystemMessage(SystemMessageId.EQUIPMENT_S1_S2_REMOVED);
@@ -2506,6 +2534,16 @@ public final class L2PcInstance extends L2Playable
 		}
 		else
 		{
+			for(EquipmentListener listener : equipmentListeners)
+			{
+				if(!listener.onEquip(item, true))
+					return;
+			}
+			for(EquipmentListener listener : globalEquipmentListeners)
+			{
+				if(!listener.onEquip(item, true))
+					return;
+			}
 			items = getInventory().equipItemAndRecord(item);
 			
 			if (item.isEquipped())
@@ -4098,8 +4136,9 @@ public final class L2PcInstance extends L2Playable
 			if ( (item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM) || !item.isEquipable())
 				ItemsAutoDestroy.getInstance().addItem(item);
 		}
-		if (Config.DESTROY_DROPPED_PLAYER_ITEM){
-			if (!item.isEquipable() || (item.isEquipable()  && Config.DESTROY_EQUIPABLE_PLAYER_ITEM ))
+		if (Config.DESTROY_DROPPED_PLAYER_ITEM)
+		{
+			if (!item.isEquipable() || (item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM))
 				item.setProtected(false);
 			else
 				item.setProtected(true);
@@ -5038,6 +5077,11 @@ public final class L2PcInstance extends L2Playable
 			sendPacket(msg);
 			return;
 		}
+		for(TransformListener listener : transformListeners)
+		{
+			if(!listener.onTransform(transformation))
+				return;
+		}
 		setQueuedSkill(null, false, false);
 		if(isMounted())
 		{
@@ -5059,6 +5103,11 @@ public final class L2PcInstance extends L2Playable
 	{
 		if (_transformation != null)
 		{
+			for(TransformListener listener : transformListeners)
+			{
+				if(!listener.onUntransform(_transformation))
+					return;
+			}
 			setQueuedSkill(null, false, false);
 			setTransformAllowedSkills(new int[]{});
 			_transformation.onUntransform();
@@ -8567,6 +8616,11 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public boolean removeHenna(int slot)
 	{
+		for(HennaListener listener : hennaListeners)
+		{
+			if(!listener.onRemoveHenna(this, getHenna(slot+1)))
+				return false;
+		}
 		if (slot < 1 || slot > 3)
 			return false;
 		
@@ -8632,6 +8686,11 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public boolean addHenna(L2HennaInstance henna)
 	{
+		for(HennaListener listener : hennaListeners)
+		{
+			if(!listener.onAddHenna(this, henna))
+				return false;
+		}
 		for (int i = 0; i < 3; i++)
 		{
 			if (_henna[i] == null)
@@ -9212,7 +9271,8 @@ public final class L2PcInstance extends L2Playable
 				return false;
 			}
 			
-			if (isInOlympiadMode() && !isOlympiadStart()){
+			if (isInOlympiadMode() && !isOlympiadStart())
+			{
 				// if L2PcInstance is in Olympia and the match isn't already start, send a Server->Client packet ActionFailed
 				sendPacket(ActionFailed.STATIC_PACKET);
 				return false;
@@ -10512,7 +10572,8 @@ public final class L2PcInstance extends L2Playable
 		_OlympiadStart = b;
 	}
 	
-	public boolean isOlympiadStart(){
+	public boolean isOlympiadStart()
+	{
 		return _OlympiadStart;
 	}
 	
@@ -10957,9 +11018,17 @@ public final class L2PcInstance extends L2Playable
 			_log.severe("Missing template for classId: "+classId);
 			throw new Error();
 		}
-		
 		// Set the template of the L2PcInstance
 		setTemplate(t);
+		
+		for (ProfessionChangeListener listener : professionChangeListeners)
+		{
+			listener.professionChanged(this, isSubClassActive(), t);
+		}
+		for (ProfessionChangeListener listener : globalProfessionChangeListeners)
+		{
+			listener.professionChanged(this, isSubClassActive(), t);
+		}
 	}
 	
 	/**
@@ -12777,28 +12846,29 @@ public final class L2PcInstance extends L2Playable
 	
 	public void setPunishLevel(int state)
 	{
-		switch (state){
-			case 0 :
+		switch (state)
+		{
+			case 0:
 			{
 				_punishLevel = PunishLevel.NONE;
 				break;
 			}
-			case 1 :
+			case 1:
 			{
 				_punishLevel = PunishLevel.CHAT;
 				break;
 			}
-			case 2 :
+			case 2:
 			{
 				_punishLevel = PunishLevel.JAIL;
 				break;
 			}
-			case 3 :
+			case 3:
 			{
 				_punishLevel = PunishLevel.CHAR;
 				break;
 			}
-			case 4 :
+			case 4:
 			{
 				_punishLevel = PunishLevel.ACC;
 				break;
@@ -15486,4 +15556,152 @@ public final class L2PcInstance extends L2Playable
 	{
 		return true;
 	}
-}
+	
+	// LISTENERS
+	/**
+	 * Adds a despawn listener
+	 * @param listener
+	 */
+	public static void addDespawnListener(PlayerDespawnListener listener)
+	{
+		if (!despawnListeners.contains(listener))
+		{
+			despawnListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a despawn listener
+	 * @param listener
+	 */
+	public static void removeDespawnListener(PlayerDespawnListener listener)
+	{
+		despawnListeners.remove(listener);
+	}
+	
+	/**
+	 * Adds a henna listener
+	 * @param listener
+	 */
+	public static void addHennaListener(HennaListener listener)
+	{
+		if (!hennaListeners.contains(listener))
+		{
+			hennaListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a henna listener
+	 * @param listener
+	 */
+	public static void removeHennaListener(HennaListener listener)
+	{
+		hennaListeners.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 (!globalEquipmentListeners.contains(listener))
+		{
+			globalEquipmentListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes an equipment listener
+	 * @param listener
+	 */
+	public static void removeGlobalEquipmentListener(EquipmentListener listener)
+	{
+		globalEquipmentListeners.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 (!globalProfessionChangeListeners.contains(listener))
+		{
+			globalProfessionChangeListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a global profession change listener
+	 * @param listener
+	 */
+	public static void removeGlobalProfessionChangeListener(ProfessionChangeListener listener)
+	{
+		globalProfessionChangeListeners.remove(listener);
+	}
+}

+ 61 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java

@@ -14,6 +14,8 @@
  */
 package com.l2jserver.gameserver.model.actor.stat;
 
+import javolution.util.FastList;
+
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.datatables.ExperienceTable;
 import com.l2jserver.gameserver.datatables.NpcTable;
@@ -33,11 +35,10 @@ import com.l2jserver.gameserver.network.serverpackets.SocialAction;
 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.listeners.player.PlayerLevelListener;
 
 public class PcStat extends PlayableStat
-{
-	//private static Logger _log = Logger.getLogger(PcStat.class.getName());
-	
+{	
 	private int _oldMaxHp; // stats watch
 	private int _oldMaxMp; // stats watch
 	private int _oldMaxCp; // stats watch
@@ -48,6 +49,9 @@ public class PcStat extends PlayableStat
 	public static final int MAX_VITALITY_POINTS = VITALITY_LEVELS[4];
 	public static final int MIN_VITALITY_POINTS = 1;
 	
+	public FastList<PlayerLevelListener> levelListeners = new FastList<PlayerLevelListener>().shared();
+	public static FastList<PlayerLevelListener> globalLevelListeners = new FastList<PlayerLevelListener>().shared();
+	
 	public PcStat(L2PcInstance activeChar)
 	{
 		super(activeChar);
@@ -212,8 +216,16 @@ public class PcStat extends PlayableStat
 		if (getLevel() + value > ExperienceTable.getInstance().getMaxLevel() - 1)
 			return false;
 		
-		boolean levelIncreased = super.addLevel(value);
+		for (PlayerLevelListener listener : levelListeners)
+		{
+			listener.levelChanged(getActiveChar(), getLevel(), getLevel() + value);
+		}
+		for (PlayerLevelListener listener : globalLevelListeners)
+		{
+			listener.levelChanged(getActiveChar(), getLevel(), getLevel() + value);
+		}
 		
+		boolean levelIncreased = super.addLevel(value);
 		if (levelIncreased)
 		{
 			if (!Config.DISABLE_TUTORIAL)
@@ -702,4 +714,49 @@ public class PcStat extends PlayableStat
 		
 		return bonus;
 	}
+	
+	/**
+	 * Listeners
+	 */
+	/**
+	 * Adds a global player level listener
+	 * @param listener
+	 */
+	public static void addGlobalLevelListener(PlayerLevelListener listener)
+	{
+		if (!globalLevelListeners.contains(listener))
+		{
+			globalLevelListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a global player level listener
+	 * @param listener
+	 */
+	public static void removeGlobalLevelListener(PlayerLevelListener listener)
+	{
+		globalLevelListeners.remove(listener);
+	}
+	
+	/**
+	 * Adds a player level listener
+	 * @param listener
+	 */
+	public void addLevelListener(PlayerLevelListener listener)
+	{
+		if (!levelListeners.contains(listener))
+		{
+			levelListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a player level listener
+	 * @param listener
+	 */
+	public void removeLevelListener(PlayerLevelListener listener)
+	{
+		levelListeners.remove(listener);
+	}
 }

+ 36 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/FortSiege.java

@@ -50,11 +50,14 @@ import com.l2jserver.gameserver.network.NpcStringId;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.NpcSay;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+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();
+
 	public static enum TeleportWhoType
 	{
 		All, Attacker, Owner,
@@ -276,6 +279,10 @@ public class FortSiege implements Siegable
 				getFort().setVisibleFlag(true);
 			
 			_log.info("Siege of " + getFort().getName() + " fort finished.");
+			for (FortSiegeListener listener : fortSiegeListeners)
+			{
+				listener.onEnd(this);
+			}
 		}
 	}
 	
@@ -287,6 +294,13 @@ public class FortSiege implements Siegable
 	{
 		if (!getIsInProgress())
 		{
+			for (FortSiegeListener listener : fortSiegeListeners)
+			{
+				if (!listener.onStart(this))
+				{
+					return;
+				}
+			}
 			if (_siegeStartTask != null) // used admin command "admin_startfortsiege"
 			{
 				_siegeStartTask.cancel(true);
@@ -1236,4 +1250,26 @@ public class FortSiege implements Siegable
 	
 	@Override
 	public void updateSiege() { }
+	
+	// Listeners
+	/**
+	 * 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);
+	}
 }

+ 40 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Siege.java

@@ -55,11 +55,14 @@ 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.listeners.events.SiegeListener;
 
 public class Siege implements Siegable
 {
 	protected static final Logger _log = Logger.getLogger(Siege.class.getName());
 	
+	private static FastList<SiegeListener> siegeListeners = new FastList<SiegeListener>().shared();
+	
 	// typeId's
 	public static final byte OWNER = -1;
 	public static final byte DEFENDER = 0;
@@ -302,6 +305,10 @@ public class Siege implements Siegable
 			getCastle().getZone().setIsActive(false);
 			getCastle().getZone().updateZoneStatusForCharactersInside();
 			getCastle().getZone().setSiegeInstance(null);
+			for(SiegeListener listener : siegeListeners)
+			{
+				listener.onEnd(this);
+			}
 		}
 	}
 	
@@ -420,6 +427,10 @@ public class Siege implements Siegable
 				spawnControlTower(getCastle().getCastleId());
 				spawnFlameTower(getCastle().getCastleId());
 				updatePlayerSiegeStateFlags(false);
+				for(SiegeListener listener : siegeListeners)
+				{
+					listener.onControlChange(this);
+				}
 			}
 		}
 	}
@@ -432,6 +443,13 @@ public class Siege implements Siegable
 	{
 		if (!getIsInProgress())
 		{
+			for(SiegeListener listener : siegeListeners)
+			{
+				if(!listener.onStart(this))
+				{
+					return;
+				}
+			}
 			_firstOwnerClanId = getCastle().getOwnerId();
 			
 			if (getAttackerClans().isEmpty())
@@ -1665,4 +1683,26 @@ public class Siege implements Siegable
 	
 	@Override
 	public void updateSiege() { }
+	
+	// Listeners
+	/**
+	 * 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);
+	}
 }

+ 54 - 9
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/TvTEvent.java

@@ -20,6 +20,7 @@ import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javolution.util.FastList;
 import javolution.util.FastMap;
 
 import com.l2jserver.Config;
@@ -50,6 +51,7 @@ 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.listeners.events.TvTListener;
 import com.l2jserver.util.Rnd;
 import com.l2jserver.util.StringUtil;
 
@@ -82,6 +84,8 @@ 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>
 	 */
@@ -144,6 +148,10 @@ public class TvTEvent
 		}
 		
 		setState(EventState.PARTICIPATING);
+		for(TvTListener listener : tvtListeners)
+		{
+			listener.onRegistrationStart();
+		}
 		return true;
 	}
 	
@@ -289,6 +297,10 @@ public class TvTEvent
 				}
 			}
 		}
+		for(TvTListener listener : tvtListeners)
+		{
+			listener.onBegin();
+		}
 		
 		return true;
 	}
@@ -333,6 +345,10 @@ public class TvTEvent
 		// Get team which has more points
 		TvTEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1];
 		rewardTeam(team);
+		for(TvTListener listener : tvtListeners)
+		{
+			listener.onEnd();
+		}
 		return "TvT Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills.";
 	}
 	
@@ -897,6 +913,10 @@ public class TvTEvent
 					playerInstance.sendPacket(cs);
 				}
 			}
+			for(TvTListener listener : tvtListeners)
+			{
+				listener.onKill(killedPlayerInstance, killerPlayerInstance, killerTeam);
+			}
 		}
 	}
 	
@@ -1159,9 +1179,10 @@ public class TvTEvent
 	public static String[] getTeamNames()
 	{
 		return new String[]
-		                  {
-				_teams[0].getName(), _teams[1].getName()
-		                  };
+		{
+			_teams[0].getName(),
+			_teams[1].getName()
+		};
 	}
 	
 	/**
@@ -1172,9 +1193,10 @@ public class TvTEvent
 	public static int[] getTeamsPlayerCounts()
 	{
 		return new int[]
-		               {
-				_teams[0].getParticipatedPlayerCount(), _teams[1].getParticipatedPlayerCount()
-		               };
+		{
+			_teams[0].getParticipatedPlayerCount(),
+			_teams[1].getParticipatedPlayerCount()
+		};
 	}
 	
 	/**
@@ -1185,13 +1207,36 @@ public class TvTEvent
 	public static int[] getTeamsPoints()
 	{
 		return new int[]
-		               {
-				_teams[0].getPoints(), _teams[1].getPoints()
-		               };
+		{
+			_teams[0].getPoints(), 
+			_teams[1].getPoints()
+		};
 	}
 	
 	public static int getTvTEventInstance()
 	{
 		return _TvTEventInstance;
 	}
+	
+	// Listeners
+	/**
+	 * 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);
+	}
 }

+ 70 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemcontainer/PcInventory.java

@@ -36,6 +36,7 @@ import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
 import com.l2jserver.gameserver.network.serverpackets.ItemList;
 import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.ItemTracker;
 import com.l2jserver.gameserver.util.Util;
 
 public class PcInventory extends Inventory
@@ -65,6 +66,8 @@ public class PcInventory extends Inventory
 	 */
 	private int _blockMode = -1;
 	
+	private static FastList<ItemTracker> itemTrackers = new FastList<ItemTracker>().shared();
+	
 	public PcInventory(L2PcInstance owner)
 	{
 		_owner = owner;
@@ -463,6 +466,13 @@ public class PcInventory extends Inventory
 		if (item != null && item.getItemId() == ANCIENT_ADENA_ID && !item.equals(_ancientAdena))
 			_ancientAdena = item;
 		
+		for (ItemTracker tracker : itemTrackers)
+		{
+			if (tracker.containsItemId(item.getItemId()))
+			{
+				tracker.onAddToInventory(item, actor);
+			}
+		}
 		return item;
 	}
 	
@@ -501,8 +511,17 @@ public class PcInventory extends Inventory
 			StatusUpdate su = new StatusUpdate(actor);
 			su.addAttribute(StatusUpdate.CUR_LOAD, actor.getCurrentLoad());
 			actor.sendPacket(su);
+			
+			for (ItemTracker tracker : itemTrackers)
+			{
+				if (tracker.containsItemId(item.getItemId()))
+				{
+					tracker.onAddToInventory(item, actor);
+				}
+			}
 		}
 		
+		
 		return item;
 	}
 	
@@ -527,6 +546,13 @@ public class PcInventory extends Inventory
 		if (_ancientAdena != null && (_ancientAdena.getCount() <= 0 || _ancientAdena.getOwnerId() != getOwnerId()))
 			_ancientAdena = null;
 		
+		for (ItemTracker tracker : itemTrackers)
+		{
+			if (tracker.containsItemId(item.getItemId()))
+			{
+				tracker.onTransfer(item, actor, target);
+			}
+		}
 		return item;
 	}
 	
@@ -563,6 +589,14 @@ public class PcInventory extends Inventory
 		if (_ancientAdena != null && _ancientAdena.getCount() <= 0)
 			_ancientAdena = null;
 		
+		for (ItemTracker tracker : itemTrackers)
+		{
+			if (tracker.containsItemId(item.getItemId()))
+			{
+				tracker.onDestroy(item, actor);
+			}
+		}
+
 		return item;
 	}
 	
@@ -625,6 +659,13 @@ public class PcInventory extends Inventory
 		if (_ancientAdena != null && (_ancientAdena.getCount() <= 0 || _ancientAdena.getOwnerId() != getOwnerId()))
 			_ancientAdena = null;
 		
+		for (ItemTracker tracker : itemTrackers)
+		{
+			if (tracker.containsItemId(item.getItemId()))
+			{
+				tracker.onDrop(item, actor);
+			}
+		}
 		return item;
 	}
 	
@@ -648,6 +689,13 @@ public class PcInventory extends Inventory
 		if (_ancientAdena != null && (_ancientAdena.getCount() <= 0 || _ancientAdena.getOwnerId() != getOwnerId()))
 			_ancientAdena = null;
 		
+		for (ItemTracker tracker : itemTrackers)
+		{
+			if (tracker.containsItemId(item.getItemId()))
+			{
+				tracker.onDrop(item, actor);
+			}
+		}
 		return item;
 	}
 	
@@ -947,4 +995,26 @@ public class PcInventory extends Inventory
 			item.giveSkillsToOwner();
 		}
 	}
+	
+	// LISTENERS
+	/**
+	 * Adds an item tracker
+	 * @param tracker
+	 */
+	public static void addItemTracker(ItemTracker tracker)
+	{
+		if (!itemTrackers.contains(itemTrackers))
+		{
+			itemTrackers.add(tracker);
+		}
+	}
+	
+	/**
+	 * Removes an item tracker
+	 * @param tracker
+	 */
+	public static void removeItemTracker(ItemTracker tracker)
+	{
+		itemTrackers.remove(tracker);
+	}
 }

+ 73 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/instance/L2ItemInstance.java

@@ -27,6 +27,8 @@ import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
 
+import javolution.util.FastList;
+
 import com.l2jserver.Config;
 import com.l2jserver.L2DatabaseFactory;
 import com.l2jserver.gameserver.GeoData;
@@ -61,6 +63,8 @@ import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
 import com.l2jserver.gameserver.network.serverpackets.SpawnItem;
 import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.AugmentListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.DropListener;
 import com.l2jserver.gameserver.util.GMAudit;
 
 /**
@@ -72,6 +76,9 @@ public final class L2ItemInstance extends L2Object
 	protected static final Logger _log = Logger.getLogger(L2ItemInstance.class.getName());
 	private static final Logger _logItems = Logger.getLogger("item");
 	
+	private static FastList<AugmentListener> augmentListeners = new FastList<AugmentListener>().shared();
+	private static FastList<DropListener> dropListeners = new FastList<DropListener>().shared();
+	
 	/** Enumeration of locations for item */
 	public static enum ItemLocation
 	{
@@ -241,6 +248,11 @@ public final class L2ItemInstance extends L2Object
 	 */
 	public final void pickupMe(L2Character player)
 	{
+		for (DropListener listener : dropListeners)
+		{
+			if (!listener.onPickup(this, (L2PcInstance) player, getPosition().getX(), getPosition().getY(), getPosition().getZ()))
+				return;
+		}
 		assert getPosition().getWorldRegion() != null;
 		
 		L2WorldRegion oldregion = getPosition().getWorldRegion();
@@ -878,6 +890,11 @@ public final class L2ItemInstance extends L2Object
 		// there shall be no previous augmentation..
 		if (_augmentation != null)
 			return false;
+		for (AugmentListener listener : augmentListeners)
+		{
+			if (!listener.onAugment(this, _augmentation))
+				return false;
+		}
 		_augmentation = augmentation;
 		updateItemAttributes(null);
 		return true;
@@ -890,6 +907,11 @@ public final class L2ItemInstance extends L2Object
 	{
 		if (_augmentation == null)
 			return;
+		for (AugmentListener listener : augmentListeners)
+		{
+			if (!listener.onRemoveAugment(this, _augmentation))
+				return;
+		}
 		_augmentation = null;
 		
 		Connection con = null;
@@ -1600,6 +1622,14 @@ public final class L2ItemInstance extends L2Object
 	
 	public final void dropMe(L2Character dropper, int x, int y, int z)
 	{
+		if(dropper.isPlayer())
+		{
+			for (DropListener listener : dropListeners)
+			{
+				if (!listener.onDrop(this, dropper.getActingPlayer(), x, y, z))
+					return;
+			}
+		}		
 		ThreadPoolManager.getInstance().executeTask(new ItemDropTask(this, dropper, x, y, z));
 	}
 	
@@ -2033,4 +2063,47 @@ public final class L2ItemInstance extends L2Object
 	{
 		return true;
 	}
+	
+	// LISTENERS
+	/**
+	 * Adds an augmentation listener
+	 * @param listener
+	 */
+	public static void addAugmentListener(AugmentListener listener)
+	{
+		if (!augmentListeners.contains(listener))
+		{
+			augmentListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes an augmentation listener
+	 * @param listener
+	 */
+	public static void removeAugmentListener(AugmentListener listener)
+	{
+		augmentListeners.remove(listener);
+	}
+	
+	/**
+	 * Adds a drop / pickup listener
+	 * @param listener
+	 */
+	public static void addDropListener(DropListener listener)
+	{
+		if (!dropListeners.contains(listener))
+		{
+			dropListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a drop / pickup listener
+	 * @param listener
+	 */
+	public static void removeDropListener(DropListener listener)
+	{
+		dropListeners.remove(listener);
+	}
 }

+ 32 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java

@@ -17,6 +17,8 @@ package com.l2jserver.gameserver.network.clientpackets;
 import java.io.UnsupportedEncodingException;
 import java.util.logging.Logger;
 
+import javolution.util.FastList;
+
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.Announcements;
 import com.l2jserver.gameserver.GmListTable;
@@ -87,6 +89,7 @@ import com.l2jserver.gameserver.network.serverpackets.QuestList;
 import com.l2jserver.gameserver.network.serverpackets.ShortCutInit;
 import com.l2jserver.gameserver.network.serverpackets.SkillCoolTime;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.PlayerSpawnListener;
 import com.l2jserver.util.Base64;
 
 /**
@@ -102,6 +105,8 @@ public class EnterWorld extends L2GameClientPacket
 	
 	private static Logger _log = Logger.getLogger(EnterWorld.class.getName());
 	
+	private static FastList<PlayerSpawnListener> listeners = new FastList<PlayerSpawnListener>().shared();
+	
 	private final int[][] tracert = new int[5][4];
 	
 	public TaskPriority getPriority()
@@ -512,6 +517,11 @@ public class EnterWorld extends L2GameClientPacket
 		
 		if(!activeChar.getPremiumItemList().isEmpty())
 			activeChar.sendPacket(new ExNotifyPremiumItem());
+		
+		for(PlayerSpawnListener listener: listeners)
+		{
+			listener.onSpawn(activeChar);
+		}
 	}
 	
 	/**
@@ -649,4 +659,26 @@ public class EnterWorld extends L2GameClientPacket
 	{
 		return false;
 	}
+	
+	// Player spawn listeners
+	/**
+	 * Adds a spawn listener
+	 * @param listener
+	 */
+	public static void addSpawnListener(PlayerSpawnListener listener)
+	{
+		if (!listeners.contains(listener))
+		{
+			listeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a spawn listener
+	 * @param listener
+	 */
+	public static void removeSpawnListener(PlayerSpawnListener listener)
+	{
+		listeners.remove(listener);
+	}
 }

+ 99 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/Say2.java

@@ -18,6 +18,8 @@ import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
 
+import javolution.util.FastList;
+
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.handler.ChatHandler;
 import com.l2jserver.gameserver.handler.IChatHandler;
@@ -27,6 +29,8 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.talk.ChatFilterListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.talk.ChatListener;
 import com.l2jserver.gameserver.util.Util;
 
 
@@ -41,6 +45,9 @@ public final class Say2 extends L2GameClientPacket
 	private static Logger _log = Logger.getLogger(Say2.class.getName());
 	private static Logger _logChat = Logger.getLogger("chat");
 	
+	private static FastList<ChatListener> chatListeners = new FastList<ChatListener>().shared();
+	private static FastList<ChatFilterListener> chatFilterListeners = new FastList<ChatFilterListener>().shared();
+	
 	public final static int ALL = 0;
 	public final static int SHOUT = 1; //!
 	public final static int TELL = 2;
@@ -90,9 +97,44 @@ public final class Say2 extends L2GameClientPacket
 		"MPCC_ROOM"
 	};
 	
-	private static final String[] WALKER_COMMAND_LIST = { "USESKILL", "USEITEM", "BUYITEM", "SELLITEM", "SAVEITEM", "LOADITEM", "MSG", "DELAY", "LABEL", "JMP", "CALL",
-		"RETURN", "MOVETO", "NPCSEL", "NPCDLG", "DLGSEL", "CHARSTATUS", "POSOUTRANGE", "POSINRANGE", "GOHOME", "SAY", "EXIT", "PAUSE", "STRINDLG", "STRNOTINDLG", "CHANGEWAITTYPE",
-		"FORCEATTACK", "ISMEMBER", "REQUESTJOINPARTY", "REQUESTOUTPARTY", "QUITPARTY", "MEMBERSTATUS", "CHARBUFFS", "ITEMCOUNT", "FOLLOWTELEPORT" };
+	private static final String[] WALKER_COMMAND_LIST =
+	{
+		"USESKILL",
+		"USEITEM",
+		"BUYITEM",
+		"SELLITEM",
+		"SAVEITEM",
+		"LOADITEM",
+		"MSG",
+		"DELAY",
+		"LABEL",
+		"JMP",
+		"CALL",
+		"RETURN",
+		"MOVETO",
+		"NPCSEL",
+		"NPCDLG",
+		"DLGSEL",
+		"CHARSTATUS",
+		"POSOUTRANGE",
+		"POSINRANGE",
+		"GOHOME",
+		"SAY",
+		"EXIT",
+		"PAUSE",
+		"STRINDLG",
+		"STRNOTINDLG",
+		"CHANGEWAITTYPE",
+		"FORCEATTACK",
+		"ISMEMBER",
+		"REQUESTJOINPARTY",
+		"REQUESTOUTPARTY",
+		"QUITPARTY",
+		"MEMBERSTATUS",
+		"CHARBUFFS",
+		"ITEMCOUNT",
+		"FOLLOWTELEPORT"
+	};
 	
 	private String _text;
 	private int _type;
@@ -195,10 +237,21 @@ public final class Say2 extends L2GameClientPacket
 			if (!parseAndPublishItem(activeChar))
 				return;
 		
+		for (ChatListener listener : chatListeners)
+		{
+			listener.onTalk(_text, activeChar, _target, ChatListener.getTargetType(CHAT_NAMES[_type]));
+		}
+		
 		// Say Filter implementation
 		if (Config.USE_SAY_FILTER)
 			checkText();
 		
+		// Custom chat filter
+		for (ChatFilterListener listener : chatFilterListeners)
+		{
+			_text = listener.onTalk(_text, activeChar, ChatListener.getTargetType(CHAT_NAMES[_type]));
+		}
+		
 		IChatHandler handler = ChatHandler.getInstance().getHandler(_type);
 		if (handler != null)
 			handler.handleChat(_type, activeChar, _target, _text);
@@ -273,4 +326,47 @@ public final class Say2 extends L2GameClientPacket
 	{
 		return false;
 	}
+	
+	// Listeners
+	/**
+	 * Adds a chat listener
+	 * @param listener
+	 */
+	public static void addChatListener(ChatListener listener)
+	{
+		if (!chatListeners.contains(listener))
+		{
+			chatListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes the given listener
+	 * @param listener
+	 */
+	public static void removeChatListener(ChatListener listener)
+	{
+		chatListeners.remove(listener);
+	}
+	
+	/**
+	 * Adds a chat listener
+	 * @param listener
+	 */
+	public static void addChatFilterListener(ChatFilterListener listener)
+	{
+		if (!chatFilterListeners.contains(listener))
+		{
+			chatFilterListeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes the given listener
+	 * @param listener
+	 */
+	public static void removeChatFilterListener(ChatFilterListener listener)
+	{
+		chatFilterListeners.remove(listener);
+	}
 }

+ 53 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/impl/L2JListener.java

@@ -0,0 +1,53 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.impl;
+
+import java.util.logging.Logger;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * Convenience superclass for all the L2J listeners.<br>
+ * Forces having the register() and unregister() methods in all its children.<br>
+ * The register() method is called automatically when the listener is instanciated.<br>
+ * These are 2 convenience methods to avoid having to register the listeners ourselves. This is particularly useful for our less advanced coders.
+ * @author TheOne
+ */
+public abstract class L2JListener
+{
+	public static Logger log = Logger.getLogger(L2JListener.class.getName());
+	
+	public L2PcInstance player = null;
+	
+	/**
+	 * Convenience method to add this listener in its proper place.<br>
+	 * Called automatically by the superconstructor when the class is instanciated.
+	 */
+	public abstract void register();
+	
+	/**
+	 * Convenience method to remove this listener
+	 */
+	public abstract void unregister();
+	
+	/**
+	 * Returns the player attached to this listener
+	 * @return
+	 */
+	public L2PcInstance getPlayer()
+	{
+		return player;
+	}
+}

+ 1496 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/impl/L2Script.java

@@ -0,0 +1,1496 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javolution.util.FastList;
+
+import com.l2jserver.gameserver.model.L2Augmentation;
+import com.l2jserver.gameserver.model.L2Clan;
+import com.l2jserver.gameserver.model.L2Object;
+import com.l2jserver.gameserver.model.L2Transformation;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.templates.L2PcTemplate;
+import com.l2jserver.gameserver.model.entity.FortSiege;
+import com.l2jserver.gameserver.model.entity.Siege;
+import com.l2jserver.gameserver.model.entity.TvTEventTeam;
+import com.l2jserver.gameserver.model.itemcontainer.ItemContainer;
+import com.l2jserver.gameserver.model.items.instance.L2HennaInstance;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.model.skills.L2Skill;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.character.AttackListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.character.DeathListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.character.SkillUseListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.clan.ClanCreationListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.clan.ClanMembershipListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.clan.ClanWarListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.clan.ClanWarehouseListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.FortSiegeListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.SiegeListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.TvTListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.AugmentListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.DropListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.EquipmentListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.HennaListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.ItemTracker;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.NewItemListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.PlayerDespawnListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.PlayerLevelListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.PlayerSpawnListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.ProfessionChangeListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.player.TransformListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.talk.ChatFilterListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.talk.ChatListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.talk.ChatListener.ChatTargetType;
+
+/**
+ * L2Script is an extension of Quest.java which makes use of the L2J listeners.<br>
+ * It is much more in-depth than its predecessor,<br>
+ * It is strongly recommended for the more advanced developers.<br>
+ * Methods with boolean return values can be used as code blockers. This means that if the return is false, the action for which the listener was fired does not happen.<br>
+ * @author TheOne
+ */
+public abstract class L2Script extends Quest
+{
+	private FastList<L2JListener> _listeners = new FastList<L2JListener>();
+	
+	/**
+	 * constructor
+	 * @param name
+	 * @param descr
+	 */
+	public L2Script(String name, String descr)
+	{
+		super(-1, name, descr);
+		init();
+	}
+	
+	/**
+	 * constructor
+	 * @param questId
+	 * @param name
+	 * @param descr
+	 */
+	public L2Script(int questId, String name, String descr)
+	{
+		super(questId, name, descr);
+		init();
+	}
+	
+	// New in this version: profession change + player level change
+	// TODO: pet item use listeners
+	// TODO: player subclass listeners ?? (needed?)
+	
+	/**
+	 * Initialize the variables and listeners/notifiers here This method is called automatically! No need to call it again ;)
+	 */
+	public abstract void init();
+	
+	/**
+	 * Unloads the script
+	 */
+	@Override
+	public boolean unload()
+	{
+		for (L2JListener listener : _listeners)
+		{
+			listener.unregister();
+		}
+		_listeners.clear();
+		return super.unload();
+	}
+	
+	/**
+	 * Unregisters the listeners and removes them from the listeners list
+	 * @param removeList
+	 */
+	private void removeListeners(List<L2JListener> removeList)
+	{
+		for (L2JListener listener : removeList)
+		{
+			listener.unregister();
+			_listeners.remove(listener);
+		}
+	}
+	
+	/**
+	 * Used locally to call onDeath()
+	 * @param killer
+	 * @param victim
+	 * @return
+	 */
+	private boolean notifyDeath(L2Character killer, L2Character victim)
+	{
+		return onDeath(killer, victim);
+	}
+	
+	/**
+	 * Used locally to call onAttack(L2Character,L2Character)
+	 * @param target
+	 * @param attacker
+	 * @return
+	 */
+	private boolean notifyAttack(L2Character target, L2Character attacker)
+	{
+		return onAttack(target, attacker);
+	}
+	
+	// Register for event notification
+	/**
+	 * Will notify the script when this L2Character is killed<br>
+	 * Can be used for Npc or Player<br>
+	 * When the L2Character is killed, the onDeath(L2Character,L2Character) method will be fired<br>
+	 * To set a global notifier (for all L2Character) set character to null!
+	 * @param character
+	 */
+	public void addDeathNodify(final L2Character character)
+	{
+		DeathListener listener = new DeathListener(character)
+		{
+			@Override
+			public boolean onKill(L2Character target, L2Character killer)
+			{
+				return notifyDeath(killer, target);
+			}
+			
+			@Override
+			public boolean onDeath(L2Character target, L2Character killer)
+			{
+				return notifyDeath(killer, target);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the death listener from this L2Character
+	 * @param character
+	 */
+	public void removeDeathNotify(L2Character character)
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof DeathListener)
+			{
+				if (((DeathListener) listener).getCharacter() == character)
+				{
+					removeList.add(listener);
+				}
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * When a player logs in it will call the onPlayerLogin(L2PcInstance player) method<br>
+	 * When a player logs out it will call the onPlayerLogout(L2PcInstance player) method<br>
+	 */
+	public void addLoginLogoutNotify()
+	{
+		PlayerSpawnListener spawn = new PlayerSpawnListener()
+		{
+			@Override
+			public void onSpawn(L2PcInstance player)
+			{
+				onPlayerLogin(player);
+			}
+		};
+		PlayerDespawnListener despawn = new PlayerDespawnListener()
+		{
+			@Override
+			public void onDespawn(L2PcInstance player)
+			{
+				onPlayerLogout(player);
+			}
+		};
+		_listeners.add(spawn);
+		_listeners.add(despawn);
+	}
+	
+	/**
+	 * Removes the login and logout notifications
+	 */
+	public void removeLoginLogoutNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof PlayerSpawnListener || listener instanceof PlayerDespawnListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds an L2Character-specific attack listener Fires onAttack(L2Character target, L2Character attacker) when this character is attacked AND when it gets attacked
+	 * @param character
+	 */
+	public void addAttackNotify(final L2Character character)
+	{
+		if (character != null)
+		{
+			AttackListener listener = new AttackListener(character)
+			{
+				@Override
+				public boolean onAttack(L2Character target)
+				{
+					return notifyAttack(target, character);
+				}
+				
+				@Override
+				public boolean isAttacked(L2Character attacker)
+				{
+					return notifyAttack(character, attacker);
+				}
+			};
+			_listeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes the notifications for attacks from/on this L2Character
+	 * @param character
+	 */
+	public void removeAttackNotify(L2Character character)
+	{
+		if (character != null)
+		{
+			List<L2JListener> removeList = new ArrayList<L2JListener>();
+			for (L2JListener listener : _listeners)
+			{
+				if (listener instanceof AttackListener && ((AttackListener) listener).getCharacter() == character)
+				{
+					removeList.add(listener);
+				}
+			}
+			removeListeners(removeList);
+		}
+	}
+	
+	/**
+	 * NPC specific, will only be triggered when npc with the given ID uses the correct skill Use skillId = -1 to be notified of all skills used Use npcId = -1 to be notified for all NPCs use npcId = -2 to be notified for all players use npcId = -3 to be notified for all L2Characters
+	 * @param npcId
+	 * @param skillId
+	 */
+	public void addSkillUseNotify(int npcId, int skillId)
+	{
+		SkillUseListener listener = new SkillUseListener(npcId, skillId)
+		{
+			@Override
+			public boolean onSkillUse(L2Skill skill, L2Character character, L2Object[] targets)
+			{
+				return onUseSkill(skill, character, targets);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * L2Character specific, will only be fired when this L2Character uses the specified skill Use skillId = -1 to be notified of all skills used
+	 * @param character
+	 * @param skillId
+	 */
+	public void addSkillUseNotify(L2Character character, int skillId)
+	{
+		if (character != null)
+		{
+			SkillUseListener listener = new SkillUseListener(character, skillId)
+			{
+				@Override
+				public boolean onSkillUse(L2Skill skill, L2Character character, L2Object[] targets)
+				{
+					return onUseSkill(skill, character, targets);
+				}
+			};
+			_listeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a skill use listener
+	 * @param character
+	 */
+	public void removeSkillUseNotify(L2Character character)
+	{
+		if (character != null)
+		{
+			List<L2JListener> removeList = new ArrayList<L2JListener>();
+			for (L2JListener listener : _listeners)
+			{
+				if (listener instanceof SkillUseListener && ((SkillUseListener) listener).getCharacter() == character)
+				{
+					removeList.add(listener);
+				}
+			}
+			removeListeners(removeList);
+		}
+	}
+	
+	/**
+	 * Removes a skill use listener
+	 * @param npcId
+	 */
+	public void removeSkillUseNotify(int npcId)
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof SkillUseListener && ((SkillUseListener) listener).getNpcId() == npcId)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a notification for when a clan is created or levels up
+	 */
+	public void addClanCreationLevelUpNotify()
+	{
+		ClanCreationListener listener = new ClanCreationListener()
+		{
+			@Override
+			public void onClanCreate(L2Clan clan)
+			{
+				onClanCreated(clan);
+			}
+			
+			@Override
+			public boolean onClanLevelUp(L2Clan clan, int oldLevel)
+			{
+				return onClanLeveledUp(clan, oldLevel);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the clan creation and level up notifications
+	 */
+	public void removeClanCreationLevelUpNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof ClanCreationListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a notification for players joining and leaving a clan as well as clan leadership changes
+	 */
+	public void addClanJoinLeaveNotify()
+	{
+		ClanMembershipListener listener = new ClanMembershipListener()
+		{
+			@Override
+			public boolean onJoin(L2PcInstance player, L2Clan clan)
+			{
+				return onClanJoin(player, clan);
+			}
+			
+			@Override
+			public boolean onLeaderChange(L2Clan clan, L2PcInstance newLeader, L2PcInstance oldLeader)
+			{
+				return onClanLeaderChange(player, clan);
+			}
+			
+			@Override
+			public boolean onLeave(int playerObjId, L2Clan clan)
+			{
+				return onClanLeave(playerObjId, clan);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the notification for players joining and leaving a clan as well as clan leadership changes
+	 */
+	public void removeClanJoinLeaveNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof ClanMembershipListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a notification for when an item from a clanwarehouse is added, deleted or transfered
+	 * @param clan
+	 */
+	public void addClanWarehouseNotify(L2Clan clan)
+	{
+		if (clan != null)
+		{
+			ClanWarehouseListener listener = new ClanWarehouseListener(clan)
+			{
+				@Override
+				public boolean onAddItem(String process, L2ItemInstance item, L2PcInstance actor)
+				{
+					return onClanWarehouseAddItem(process, item, actor);
+				}
+				
+				@Override
+				public boolean onDeleteItem(String process, L2ItemInstance item, long count, L2PcInstance actor)
+				{
+					return onClanWarehouseDeleteItem(process, item, count, actor);
+				}
+				
+				@Override
+				public boolean onTransferItem(String process, L2ItemInstance item, long count, ItemContainer target, L2PcInstance actor)
+				{
+					return onClanWarehouseTransferItem(process, item, count, target, actor);
+				}
+			};
+			_listeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a clan warehouse notifier
+	 * @param clan
+	 */
+	public void removeClanWarehouseNotify(L2Clan clan)
+	{
+		if (clan != null)
+		{
+			List<L2JListener> removeList = new ArrayList<L2JListener>();
+			for (L2JListener listener : _listeners)
+			{
+				if (listener instanceof ClanWarehouseListener && ((ClanWarehouseListener) listener).getWarehouse() == clan.getWarehouse())
+				{
+					removeList.add(listener);
+				}
+			}
+			removeListeners(removeList);
+		}
+	}
+	
+	/**
+	 * Adds a notifier for when clan wars start and end
+	 */
+	public void addClanWarNotify()
+	{
+		ClanWarListener listener = new ClanWarListener()
+		{
+			@Override
+			public boolean onWarStart(L2Clan clan1, L2Clan clan2)
+			{
+				return onClanWarEvent(clan1, clan2, EventStage.start);
+			}
+			
+			@Override
+			public boolean onWarEnd(L2Clan clan1, L2Clan clan2)
+			{
+				return onClanWarEvent(clan1, clan2, EventStage.end);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the notification for start/end of clan wars
+	 */
+	public void removeClanWarNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof ClanWarListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Notifies when fort sieges start and end
+	 */
+	public void addFortSiegeNotify()
+	{
+		FortSiegeListener listener = new FortSiegeListener()
+		{
+			@Override
+			public boolean onStart(FortSiege fortSiege)
+			{
+				return onFortSiegeEvent(fortSiege, EventStage.start);
+			}
+			
+			@Override
+			public void onEnd(FortSiege fortSiege)
+			{
+				onFortSiegeEvent(fortSiege, EventStage.end);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the notification for fort sieges
+	 */
+	public void removeFortSiegeNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof FortSiegeListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a notifier for when castle sieges start and end
+	 */
+	public void addSiegeNotify()
+	{
+		SiegeListener listener = new SiegeListener()
+		{
+			@Override
+			public boolean onStart(Siege siege)
+			{
+				return onSiegeEvent(siege, EventStage.start);
+			}
+			
+			@Override
+			public void onEnd(Siege siege)
+			{
+				onSiegeEvent(siege, EventStage.end);
+			}
+			
+			@Override
+			public void onControlChange(Siege siege)
+			{
+				onCastleControlChange(siege);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes notification for castle sieges
+	 */
+	public void removeSiegeNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof SiegeListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Notifies of events on TvT:<br>
+	 * start<br>
+	 * end<br>
+	 * registion begin<br>
+	 * event stopped<br>
+	 * player killed<br>
+	 */
+	public void addTvTNotify()
+	{
+		TvTListener listener = new TvTListener()
+		{
+			@Override
+			public void onBegin()
+			{
+				onTvtEvent(EventStage.start);
+			}
+			
+			@Override
+			public void onKill(L2PcInstance killed, L2PcInstance killer, TvTEventTeam killerTeam)
+			{
+				onTvtKill(killed, killer, killerTeam);
+			}
+			
+			@Override
+			public void onEnd()
+			{
+				onTvtEvent(EventStage.end);
+			}
+			
+			@Override
+			public void onRegistrationStart()
+			{
+				onTvtEvent(EventStage.registration_begin);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the TvT notifications
+	 */
+	public void removeTvtNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof TvTListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a notifier for when items get augmented
+	 */
+	public void addItemAugmentNotify()
+	{
+		AugmentListener listener = new AugmentListener()
+		{
+			@Override
+			public boolean onAugment(L2ItemInstance item, L2Augmentation augmentation)
+			{
+				return onItemAugment(item, augmentation, true);
+			}
+			
+			@Override
+			public boolean onRemoveAugment(L2ItemInstance item, L2Augmentation augmentation)
+			{
+				return onItemAugment(item, augmentation, false);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the item augmentation listener
+	 */
+	public void removeItemAugmentNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof AugmentListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a listener for items dropped and picked up by players
+	 */
+	public void addItemDropPickupNotify()
+	{
+		DropListener listener = new DropListener()
+		{
+			
+			@Override
+			public boolean onDrop(L2ItemInstance item, L2PcInstance dropper, int x, int y, int z)
+			{
+				return onItemDrop(item, dropper, x, y, z);
+			}
+			
+			@Override
+			public boolean onPickup(L2ItemInstance item, L2PcInstance picker, int x, int y, int z)
+			{
+				return onItemPickup(item, picker, x, y, z);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the item drop and pickup listeners
+	 */
+	public void removeItemDropPickupNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof DropListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a player level change listener<br>
+	 * Set player to null if you wish to be notified for all the players on the server.
+	 * @param player
+	 */
+	public void addPlayerLevelNotify(L2PcInstance player)
+	{
+		PlayerLevelListener listener = new PlayerLevelListener(player)
+		{
+			@Override
+			public void levelChanged(L2PcInstance player, int oldLevel, int newLevel)
+			{
+				onPlayerLevelChange(player, oldLevel, newLevel);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the player level notification for the given player<br>
+	 * Removes all global notifications if player = null
+	 * @param player
+	 */
+	public void removePlayerLevelNotify(L2PcInstance player)
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof PlayerLevelListener && listener.getPlayer() == player)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a player profession change listener.<br>
+	 * Set player to null if you wish to be notified for all the players on the server.
+	 * @param player
+	 */
+	public void addProfessionChangeNotify(L2PcInstance player)
+	{
+		ProfessionChangeListener listener = new ProfessionChangeListener(player)
+		{
+			@Override
+			public void professionChanged(L2PcInstance player, boolean isSubClass, L2PcTemplate template)
+			{
+				onProfessionChange(player, isSubClass, template);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the profession change notification for the given player<br>
+	 * Removes all global notifications if player = null
+	 * @param player
+	 */
+	public void removeProfessionChangeNotify(L2PcInstance player)
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof ProfessionChangeListener && listener.getPlayer() == player)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds an item equip/unequip listener.<br>
+	 * Set player to null if you wish to be notified for all the players on server
+	 * @param player
+	 */
+	public void addEquipmentNotify(L2PcInstance player)
+	{
+		EquipmentListener listener = new EquipmentListener(player)
+		{
+			@Override
+			public boolean onEquip(L2ItemInstance item, boolean isEquipped)
+			{
+				return onItemEquip(player, item, isEquipped);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes an equip/unequip listener<br>
+	 * Set player to null if you wish to remove a global listener
+	 * @param player
+	 */
+	public void removeEquipmentNotify(L2PcInstance player)
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof EquipmentListener && ((EquipmentListener) listener).getPlayer() == player)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a Henna add/remove notifier
+	 */
+	public void addHennaNotify()
+	{
+		HennaListener listener = new HennaListener()
+		{
+			@Override
+			public boolean onAddHenna(L2PcInstance player, L2HennaInstance henna)
+			{
+				return onHennaModify(player, henna, true);
+			}
+			
+			@Override
+			public boolean onRemoveHenna(L2PcInstance player, L2HennaInstance henna)
+			{
+				return onHennaModify(player, henna, false);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes the henna add/remove notifier
+	 */
+	public void removeHennaNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof HennaListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds an item tracker notifier.<br>
+	 * It will keep track of all movements for the items with the given IDs
+	 * @param itemIds
+	 */
+	public void addItemTracker(final List<Integer> itemIds)
+	{
+		if (itemIds != null)
+		{
+			ItemTracker listener = new ItemTracker(itemIds)
+			{
+				@Override
+				public void onDrop(L2ItemInstance item, L2PcInstance player)
+				{
+					onItemTrackerEvent(item, player, null, ItemTrackerEvent.drop);
+				}
+				
+				@Override
+				public void onAddToInventory(L2ItemInstance item, L2PcInstance player)
+				{
+					onItemTrackerEvent(item, player, null, ItemTrackerEvent.add_to_inventory);
+				}
+				
+				@Override
+				public void onDestroy(L2ItemInstance item, L2PcInstance player)
+				{
+					onItemTrackerEvent(item, player, null, ItemTrackerEvent.destroy);
+				}
+				
+				@Override
+				public void onTransfer(L2ItemInstance item, L2PcInstance player, ItemContainer target)
+				{
+					onItemTrackerEvent(item, player, target, ItemTrackerEvent.transfer);
+				}
+			};
+			_listeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes all the item trackers
+	 */
+	public void removeItemTrackers()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof ItemTracker)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds an item creation notifier
+	 * @param itemIds
+	 */
+	public void addNewItemNotify(List<Integer> itemIds)
+	{
+		if (itemIds != null)
+		{
+			NewItemListener listener = new NewItemListener(itemIds)
+			{
+				
+				@Override
+				public boolean onCreate(int itemId, L2PcInstance player)
+				{
+					return onItemCreate(itemId, player);
+				}
+			};
+			_listeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes all new items notifiers
+	 */
+	public void removeNewItemNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof NewItemListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a player transformation notifier
+	 * @param player
+	 */
+	public void addTransformNotify(final L2PcInstance player)
+	{
+		if (player != null)
+		{
+			TransformListener listener = new TransformListener(player)
+			{
+				@Override
+				public boolean onTransform(L2Transformation transformation)
+				{
+					return onPlayerTransform(player, transformation, true);
+				}
+				
+				@Override
+				public boolean onUntransform(L2Transformation transformation)
+				{
+					return onPlayerTransform(player, transformation, false);
+				}
+			};
+			_listeners.add(listener);
+		}
+	}
+	
+	/**
+	 * Removes a player transform notifier
+	 * @param player
+	 */
+	public void removeTransformNotify(L2PcInstance player)
+	{
+		if (player != null)
+		{
+			List<L2JListener> removeList = new ArrayList<L2JListener>();
+			for (L2JListener listener : _listeners)
+			{
+				if (listener instanceof TransformListener && listener.getPlayer() == player)
+				{
+					removeList.add(listener);
+				}
+			}
+			removeListeners(removeList);
+		}
+	}
+	
+	/**
+	 * Adds a chat filter
+	 */
+	public void addPlayerChatFilter()
+	{
+		ChatFilterListener listener = new ChatFilterListener()
+		{
+			@Override
+			public String onTalk(String text, L2PcInstance origin, ChatTargetType targetType)
+			{
+				return filterChat(text, origin, targetType);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes a chat filter
+	 */
+	public void removePlayerChatFilter()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof ChatFilterListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	/**
+	 * Adds a player chat notifier
+	 */
+	public void addPlayerTalkNotify()
+	{
+		ChatListener listener = new ChatListener()
+		{
+			@Override
+			public void onTalk(String text, L2PcInstance origin, String target, ChatTargetType targetType)
+			{
+				onPlayerTalk(text, origin, target, targetType);
+			}
+		};
+		_listeners.add(listener);
+	}
+	
+	/**
+	 * Removes all player chat notifiers
+	 */
+	public void removePlayerTalkNotify()
+	{
+		List<L2JListener> removeList = new ArrayList<L2JListener>();
+		for (L2JListener listener : _listeners)
+		{
+			if (listener instanceof ChatListener)
+			{
+				removeList.add(listener);
+			}
+		}
+		removeListeners(removeList);
+	}
+	
+	// Script notifications
+	/**
+	 * Fired when a player logs in
+	 * @param player
+	 */
+	public void onPlayerLogin(L2PcInstance player)
+	{
+		
+	}
+	
+	/**
+	 * Fired when a player logs out
+	 * @param player
+	 */
+	public void onPlayerLogout(L2PcInstance player)
+	{
+		
+	}
+	
+	/**
+	 * Fired when a L2Character registered with addAttackNotify is either attacked or attacks another L2Character
+	 * @param target
+	 * @param attacker
+	 * @return
+	 */
+	public boolean onAttack(L2Character target, L2Character attacker)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a L2Character registered with addNotifyDeath is either killed or kills another L2Character
+	 * @param killer
+	 * @param victim
+	 * @return
+	 */
+	public boolean onDeath(L2Character killer, L2Character victim)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a SKillUseListener gets triggered.<br>
+	 * Register using addSkillUseNotify()
+	 * @param skill
+	 * @param caster
+	 * @param targets
+	 * @return
+	 */
+	public boolean onUseSkill(L2Skill skill, L2Character caster, L2Object[] targets)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a clan is created Register the listener using addClanCreationLevelUpNotify()
+	 * @param clan
+	 */
+	public void onClanCreated(L2Clan clan)
+	{
+		
+	}
+	
+	/**
+	 * Fired when a clan levels up<br>
+	 * Register the listener using addClanCreationLevelUpListener()
+	 * @param clan
+	 * @param oldLevel
+	 * @return
+	 */
+	public boolean onClanLeveledUp(L2Clan clan, int oldLevel)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a player joins a clan<br>
+	 * Register the listener with addClanJoinLeaveNotify()<br>
+	 * @param player
+	 * @param clan
+	 * @return
+	 */
+	public boolean onClanJoin(L2PcInstance player, L2Clan clan)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a player leaves a clan<br>
+	 * Register the listener with addClanJoinLeaveNotify()<br>
+	 * @param playerObjId
+	 * @param clan
+	 * @return
+	 */
+	public boolean onClanLeave(int playerObjId, L2Clan clan)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a clan leader is changed for another<br>
+	 * Register the listener with addClanJoinLeaveNotify()<br>
+	 * @param player
+	 * @param clan
+	 * @return
+	 */
+	public boolean onClanLeaderChange(L2PcInstance player, L2Clan clan)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when an item is added to a clan warehouse<br>
+	 * Register the listener with addClanWarehouseNotify(L2Clan)
+	 * @param process
+	 * @param item
+	 * @param actor
+	 * @return
+	 */
+	public boolean onClanWarehouseAddItem(String process, L2ItemInstance item, L2PcInstance actor)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when an item is deleted from a clan warehouse<br>
+	 * Register the listener with addClanWarehouseNotify(L2Clan)
+	 * @param process
+	 * @param item
+	 * @param count
+	 * @param actor
+	 * @return
+	 */
+	public boolean onClanWarehouseDeleteItem(String process, L2ItemInstance item, long count, L2PcInstance actor)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when an item is transfered from/to a clan warehouse<br>
+	 * Register the listener with addClanWarehouseNotify(L2Clan)
+	 * @param process
+	 * @param item
+	 * @param count
+	 * @param target
+	 * @param actor
+	 * @return
+	 */
+	public boolean onClanWarehouseTransferItem(String process, L2ItemInstance item, long count, ItemContainer target, L2PcInstance actor)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a clan war starts or ends<br>
+	 * Register the listener witn addClanWarNotify()
+	 * @param clan1
+	 * @param clan2
+	 * @param stage
+	 * @return
+	 */
+	public boolean onClanWarEvent(L2Clan clan1, L2Clan clan2, EventStage stage)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a fort siege starts or ends<br>
+	 * Register using addFortSiegeNotify()
+	 * @param fortSiege
+	 * @param stage
+	 * @return
+	 */
+	public boolean onFortSiegeEvent(FortSiege fortSiege, EventStage stage)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a castle siege starts or ends<br>
+	 * Register using addSiegeNotify()
+	 * @param siege
+	 * @param stage
+	 * @return
+	 */
+	public boolean onSiegeEvent(Siege siege, EventStage stage)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when the control of a castle changes during a siege<br>
+	 * Register using addSiegeNotify()
+	 * @param siege
+	 */
+	public void onCastleControlChange(Siege siege)
+	{
+		
+	}
+	
+	/**
+	 * Notifies of TvT events<br>
+	 * Register using addTvtNotify()
+	 * @param stage
+	 */
+	public void onTvtEvent(EventStage stage)
+	{
+		
+	}
+	
+	/**
+	 * Notifies that a player was killed during TvT<br>
+	 * Register using addTvtNotify()
+	 * @param killed
+	 * @param killer
+	 * @param killerTeam
+	 */
+	public void onTvtKill(L2PcInstance killed, L2PcInstance killer, TvTEventTeam killerTeam)
+	{
+		
+	}
+	
+	/**
+	 * triggered when an item is augmented or when the augmentation is removed<br>
+	 * Register using addItemAugmentNotify()
+	 * @param item
+	 * @param augmentation
+	 * @param augment -> false = remove augment
+	 * @return
+	 */
+	public boolean onItemAugment(L2ItemInstance item, L2Augmentation augmentation, boolean augment)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when an item is dropped by a player<br>
+	 * Register using addItemDropPickupNotify()
+	 * @param item
+	 * @param dropper
+	 * @param x
+	 * @param y
+	 * @param z
+	 * @return
+	 */
+	public boolean onItemDrop(L2ItemInstance item, L2PcInstance dropper, int x, int y, int z)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when an item is picked up by a player<br>
+	 * Register using addItemDropPickupNotify()
+	 * @param item
+	 * @param dropper
+	 * @param x
+	 * @param y
+	 * @param z
+	 * @return
+	 */
+	public boolean onItemPickup(L2ItemInstance item, L2PcInstance dropper, int x, int y, int z)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when an item is equipped or unequipped<br>
+	 * Register using addEquipmentNotify()
+	 * @param player
+	 * @param item
+	 * @param isEquipped
+	 * @return
+	 */
+	public boolean onItemEquip(L2PcInstance player, L2ItemInstance item, boolean isEquipped)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a player's level changes<br>
+	 * Register using addPlayerLevelNotify(player)
+	 * @param player
+	 * @param oldLevel
+	 * @param newLevel
+	 */
+	public void onPlayerLevelChange(L2PcInstance player, int oldLevel, int newLevel)
+	{
+		
+	}
+	
+	/**
+	 * Fired when a player changes profession<br>
+	 * Register using addProfessionChangeNotify(player)
+	 * @param player
+	 * @param isSubClass
+	 * @param template
+	 */
+	public void onProfessionChange(L2PcInstance player, boolean isSubClass, L2PcTemplate template)
+	{
+		
+	}
+	
+	/**
+	 * Fired when a player's henna changes (add/remove)<br>
+	 * Register using addHennaNotify()
+	 * @param player
+	 * @param henna
+	 * @param add -> false = remove
+	 * @return
+	 */
+	public boolean onHennaModify(L2PcInstance player, L2HennaInstance henna, boolean add)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when an item on the item tracker list has an event<br>
+	 * Register using addItemTracker(itemIds)
+	 * @param item
+	 * @param player
+	 * @param target
+	 * @param event
+	 */
+	public void onItemTrackerEvent(L2ItemInstance item, L2PcInstance player, ItemContainer target, ItemTrackerEvent event)
+	{
+		
+	}
+	
+	/**
+	 * Fired when an item is created<br>
+	 * Register using addNewItemNotify(itemIds)
+	 * @param itemId
+	 * @param player
+	 * @return
+	 */
+	public boolean onItemCreate(int itemId, L2PcInstance player)
+	{
+		return true;
+	}
+	
+	/**
+	 * Fired when a player transforms/untransforms<br>
+	 * Register using addTransformNotify(player)
+	 * @param player
+	 * @param transformation
+	 * @param isTransforming -> false = untransform
+	 * @return
+	 */
+	public boolean onPlayerTransform(L2PcInstance player, L2Transformation transformation, boolean isTransforming)
+	{
+		return true;
+	}
+	
+	/**
+	 * Allows for custom chat filtering<br>
+	 * Fired each time a player writes something in any form of chat<br>
+	 * Register using addPlayerChatFilter()
+	 * @param text
+	 * @param origin
+	 * @param targetType
+	 * @return
+	 */
+	public String filterChat(String text, L2PcInstance origin, ChatTargetType targetType)
+	{
+		return "";
+	}
+	
+	/**
+	 * Fired when a player writes some text in chat<br>
+	 * Register using addPlayerTalkNotify()
+	 * @param text
+	 * @param origin
+	 * @param target
+	 * @param targetType
+	 */
+	public void onPlayerTalk(String text, L2PcInstance origin, String target, ChatTargetType targetType)
+	{
+		
+	}
+	
+	// Enums
+	
+	public enum EventStage
+	{
+		start,
+		end,
+		event_stopped,
+		registration_begin
+	}
+	
+	public enum ItemTrackerEvent
+	{
+		drop,
+		add_to_inventory,
+		destroy,
+		transfer
+	}
+}

+ 73 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/character/AttackListener.java

@@ -0,0 +1,73 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.character;
+
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * @author TheOne
+ */
+public abstract class AttackListener extends L2JListener
+{
+	private L2Character _character = null;
+	
+	/**
+	 * Constructor.<br>
+	 * AttackListener is not a static listener, it needs to be registered for each L2Character you wish to use it for.<br>
+	 * It will work for both NPCs and Players
+	 * @param character
+	 */
+	public AttackListener(L2Character character)
+	{
+		_character = character;
+		register();
+	}
+	
+	/**
+	 * The player just attacked another character
+	 * @param target
+	 * @return
+	 */
+	public abstract boolean onAttack(L2Character target);
+	
+	/**
+	 * The player was just attacked by another character
+	 * @param attacker
+	 * @return
+	 */
+	public abstract boolean isAttacked(L2Character attacker);
+	
+	@Override
+	public void register()
+	{
+		_character.addAttackListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		_character.removeAttackListener(this);
+	}
+	
+	/**
+	 * returns the L2Character this listener is attached to
+	 * @return
+	 */
+	public L2Character getCharacter()
+	{
+		return _character;
+	}
+}

+ 96 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/character/DeathListener.java

@@ -0,0 +1,96 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.character;
+
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Death/Kill listener<br>
+ * Works for NPCs and Players
+ * @author TheOne
+ */
+public abstract class DeathListener extends L2JListener
+{
+	private L2Character _character = null;
+	private boolean _isGlobal = false;
+	
+	/**
+	 * constructor To have a global listener, set character to null
+	 * @param character
+	 */
+	public DeathListener(L2Character character)
+	{
+		if (character == null)
+		{
+			_isGlobal = true;
+		}
+		_character = character;
+		register();
+	}
+	
+	/**
+	 * The character just killed the target<br>
+	 * If you use this listener as global, use: onDeathGlobal()
+	 * @param target
+	 * @param killer
+	 * @return
+	 */
+	public abstract boolean onKill(L2Character target, L2Character killer);
+	
+	/**
+	 * The character was just killed by the target<br>
+	 * If you use this listener as global, use: onDeathGlobal()
+	 * @param target
+	 * @param killer
+	 * @return
+	 */
+	public abstract boolean onDeath(L2Character target, L2Character killer);
+	
+	/**
+	 * Returns the character
+	 * @return
+	 */
+	public L2Character getCharacter()
+	{
+		return _character;
+	}
+	
+	@Override
+	public void register()
+	{
+		if (_isGlobal)
+		{
+			L2Character.addGlobalDeathListener(this);
+		}
+		else
+		{
+			_character.addDeathListener(this);
+		}
+	}
+	
+	@Override
+	public void unregister()
+	{
+		if (_isGlobal)
+		{
+			L2Character.removeGlobalDeathListener(this);
+		}
+		else
+		{
+			_character.removeDeathListener(this);
+		}
+	}
+}

+ 118 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/character/SkillUseListener.java

@@ -0,0 +1,118 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.character;
+
+import com.l2jserver.gameserver.model.L2Object;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.skills.L2Skill;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * @author TheOne
+ */
+public abstract class SkillUseListener extends L2JListener
+{
+	private L2Character _character = null;
+	private int _skillId = -1;
+	private int _npcId = -1;
+	private boolean _characterSpecific = false;
+	
+	/**
+	 * constructor L2Character specific, will only be fired when this L2Character uses the specified skill Use skillId = -1 to be notified of all skills used
+	 * @param character
+	 * @param skillId
+	 */
+	public SkillUseListener(L2Character character, int skillId)
+	{
+		_skillId = skillId;
+		_character = character;
+		_characterSpecific = true;
+		register();
+	}
+	
+	/**
+	 * constructor NPC specific, will only be triggered when npc with the given ID uses the correct skill Use skillId = -1 to be notified of all skills used Use npcId = -1 to be notified for all NPCs use npcId = -2 to be notified for all players use npcId = -3 to be notified for all L2Characters
+	 * @param npcId
+	 * @param skillId
+	 */
+	public SkillUseListener(int npcId, int skillId)
+	{
+		_skillId = skillId;
+		_npcId = npcId;
+		register();
+	}
+	
+	/**
+	 * A L2Character just cast a skill
+	 * @param skill
+	 * @param character
+	 * @param targets
+	 * @return
+	 */
+	public abstract boolean onSkillUse(L2Skill skill, L2Character character, L2Object[] targets);
+	
+	@Override
+	public void register()
+	{
+		if (!_characterSpecific)
+		{
+			L2Character.addGlobalSkillUseListener(this);
+		}
+		else
+		{
+			_character.addSkillUseListener(this);
+		}
+	}
+	
+	@Override
+	public void unregister()
+	{
+		if (!_characterSpecific)
+		{
+			L2Character.removeGlobalSkillUseListener(this);
+		}
+		else
+		{
+			_character.removeSkillUseListener(this);
+		}
+	}
+	
+	/**
+	 * Returns the npcId this listener will be triggered for
+	 * @return
+	 */
+	public int getNpcId()
+	{
+		return _npcId;
+	}
+	
+	/**
+	 * Returns the skillId this listener will be triggered for
+	 * @return
+	 */
+	public int getSkillId()
+	{
+		return _skillId;
+	}
+	
+	/**
+	 * Returns the L2Character this listener is attached to
+	 * @return
+	 */
+	public L2Character getCharacter()
+	{
+		return _character;
+	}
+}

+ 56 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/clan/ClanCreationListener.java

@@ -0,0 +1,56 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.clan;
+
+import com.l2jserver.gameserver.model.L2Clan;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * This class notifies of clan creation and
+ * @author TheOne
+ */
+public abstract class ClanCreationListener extends L2JListener
+{
+	public ClanCreationListener()
+	{
+		register();
+	}
+	
+	/**
+	 * Fired when a clan is created
+	 * @param clan
+	 */
+	public abstract void onClanCreate(L2Clan clan);
+	
+	/**
+	 * Fired when a clan levels up
+	 * @param clan
+	 * @param oldLevel
+	 * @return
+	 */
+	public abstract boolean onClanLevelUp(L2Clan clan, int oldLevel);
+	
+	@Override
+	public void register()
+	{
+		L2Clan.addClanCreationListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		L2Clan.removeClanCreationListener(this);
+	}
+}

+ 68 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/clan/ClanMembershipListener.java

@@ -0,0 +1,68 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.clan;
+
+import com.l2jserver.gameserver.model.L2Clan;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Clan join and leave notifiers
+ * @author TheOne
+ */
+public abstract class ClanMembershipListener extends L2JListener
+{
+	public ClanMembershipListener()
+	{
+		register();
+	}
+	
+	/**
+	 * A player just joined the clan
+	 * @param player
+	 * @param clan
+	 * @return
+	 */
+	public abstract boolean onJoin(L2PcInstance player, L2Clan clan);
+	
+	/**
+	 * A player just left the clan
+	 * @param playerObjId
+	 * @param clan
+	 * @return
+	 */
+	public abstract boolean onLeave(int playerObjId, L2Clan clan);
+	
+	/**
+	 * Fired when the clan leader changes
+	 * @param clan
+	 * @param newLeader
+	 * @param oldLeader
+	 * @return
+	 */
+	public abstract boolean onLeaderChange(L2Clan clan, L2PcInstance newLeader, L2PcInstance oldLeader);
+	
+	@Override
+	public void register()
+	{
+		L2Clan.addClanMembershipListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		L2Clan.removeClanMembershipListener(this);
+	}
+}

+ 58 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/clan/ClanWarListener.java

@@ -0,0 +1,58 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.clan;
+
+import com.l2jserver.gameserver.model.L2Clan;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Notifies when a clan war starts or ends
+ * @author TheOne
+ */
+public abstract class ClanWarListener extends L2JListener
+{
+	public ClanWarListener()
+	{
+		register();
+	}
+	
+	/**
+	 * Clan war just started
+	 * @param clan1
+	 * @param clan2
+	 * @return
+	 */
+	public abstract boolean onWarStart(L2Clan clan1, L2Clan clan2);
+	
+	/**
+	 * Clan war just ended
+	 * @param clan1
+	 * @param clan2
+	 * @return
+	 */
+	public abstract boolean onWarEnd(L2Clan clan1, L2Clan clan2);
+	
+	@Override
+	public void register()
+	{
+		L2Clan.addClanWarListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		L2Clan.removeClanWarListener(this);
+	}
+}

+ 87 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/clan/ClanWarehouseListener.java

@@ -0,0 +1,87 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.clan;
+
+import com.l2jserver.gameserver.model.ClanWarehouse;
+import com.l2jserver.gameserver.model.L2Clan;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.itemcontainer.ItemContainer;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * @author TheOne
+ */
+public abstract class ClanWarehouseListener extends L2JListener
+{
+	private ClanWarehouse _clanWarehouse;
+	
+	public ClanWarehouseListener(L2Clan clan)
+	{
+		_clanWarehouse = (ClanWarehouse) clan.getWarehouse();
+		register();
+	}
+	
+	/**
+	 * An item was just added
+	 * @param process
+	 * @param item
+	 * @param actor
+	 * @return
+	 */
+	public abstract boolean onAddItem(String process, L2ItemInstance item, L2PcInstance actor);
+	
+	/**
+	 * An item was just deleted
+	 * @param process
+	 * @param item
+	 * @param count
+	 * @param actor
+	 * @return
+	 */
+	public abstract boolean onDeleteItem(String process, L2ItemInstance item, long count, L2PcInstance actor);
+	
+	/**
+	 * An item was just transfered
+	 * @param process
+	 * @param item
+	 * @param count
+	 * @param target
+	 * @param actor
+	 * @return
+	 */
+	public abstract boolean onTransferItem(String process, L2ItemInstance item, long count, ItemContainer target, L2PcInstance actor);
+	
+	@Override
+	public void register()
+	{
+		_clanWarehouse.addWarehouseListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		_clanWarehouse.removeWarehouseListener(this);
+	}
+	
+	/**
+	 * Returns the clan warehouse attached to this listener
+	 * @return
+	 */
+	public ClanWarehouse getWarehouse()
+	{
+		return _clanWarehouse;
+	}
+}

+ 54 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/FortSiegeListener.java

@@ -0,0 +1,54 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.events;
+
+import com.l2jserver.gameserver.model.entity.FortSiege;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * @author TheOne
+ */
+public abstract class FortSiegeListener extends L2JListener
+{
+	public FortSiegeListener()
+	{
+		register();
+	}
+	
+	/**
+	 * Fired when a fort siege starts
+	 * @param fortSiege
+	 * @return
+	 */
+	public abstract boolean onStart(FortSiege fortSiege);
+	
+	/**
+	 * Fired when a fort siege ends
+	 * @param fortSiege
+	 */
+	public abstract void onEnd(FortSiege fortSiege);
+	
+	@Override
+	public void register()
+	{
+		FortSiege.addFortSiegeListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		FortSiege.removeFortSiegeListener(this);
+	}
+}

+ 60 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/SiegeListener.java

@@ -0,0 +1,60 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.events;
+
+import com.l2jserver.gameserver.model.entity.Siege;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * @author TheOne
+ */
+public abstract class SiegeListener extends L2JListener
+{
+	public SiegeListener()
+	{
+		register();
+	}
+	
+	/**
+	 * Fired when a siege starts
+	 * @param siege
+	 * @return
+	 */
+	public abstract boolean onStart(Siege siege);
+	
+	/**
+	 * Fired when a siege ends
+	 * @param siege
+	 */
+	public abstract void onEnd(Siege siege);
+	
+	/**
+	 * Fired when the control of the castle change hands during the siege
+	 * @param siege
+	 */
+	public abstract void onControlChange(Siege siege);
+	
+	@Override
+	public void register()
+	{
+		Siege.addSiegeListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		Siege.removeSiegeListener(this);
+	}
+}

+ 67 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/events/TvTListener.java

@@ -0,0 +1,67 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.events;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.TvTEventTeam;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Notifies when a TvT event starts
+ * @author TheOne
+ */
+public abstract class TvTListener extends L2JListener
+{
+	public TvTListener()
+	{
+		register();
+	}
+	
+	/**
+	 * Fired when a TvT event starts
+	 */
+	public abstract void onBegin();
+	
+	/**
+	 * A player has been killed
+	 * @param killed
+	 * @param killer
+	 * @param killerTeam
+	 */
+	public abstract void onKill(L2PcInstance killed, L2PcInstance killer, TvTEventTeam killerTeam);
+	
+	/**
+	 * Fired when a TvT event ends
+	 */
+	public abstract void onEnd();
+	
+	/**
+	 * Fired when TvT registration starts
+	 */
+	public abstract void onRegistrationStart();
+	
+	@Override
+	public void register()
+	{
+		TvTEvent.addTvTListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		TvTEvent.removeTvtListener(this);
+	}
+}

+ 60 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/AugmentListener.java

@@ -0,0 +1,60 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import com.l2jserver.gameserver.model.L2Augmentation;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Global listener for item augmentation
+ * @author TheOne
+ */
+public abstract class AugmentListener extends L2JListener
+{
+	public AugmentListener()
+	{
+		register();
+	}
+	
+	/**
+	 * Triggered when a L2ItemInstance is augmented
+	 * @param item
+	 * @param augmentation
+	 * @return
+	 */
+	public abstract boolean onAugment(L2ItemInstance item, L2Augmentation augmentation);
+	
+	/**
+	 * Triggered when a L2ItemInstance's augmentation is removed
+	 * @param item
+	 * @param augmentation
+	 * @return
+	 */
+	public abstract boolean onRemoveAugment(L2ItemInstance item, L2Augmentation augmentation);
+	
+	@Override
+	public void register()
+	{
+		L2ItemInstance.addAugmentListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		L2ItemInstance.removeAugmentListener(this);
+	}
+	
+}

+ 65 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/DropListener.java

@@ -0,0 +1,65 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Global listener for items dropped by players
+ * @author TheOne
+ */
+public abstract class DropListener extends L2JListener
+{
+	public DropListener()
+	{
+		register();
+	}
+	
+	/**
+	 * The item was dropped
+	 * @param item
+	 * @param dropper
+	 * @param x
+	 * @param y
+	 * @param z
+	 * @return
+	 */
+	public abstract boolean onDrop(L2ItemInstance item, L2PcInstance dropper, int x, int y, int z);
+	
+	/**
+	 * The item was picked up
+	 * @param item
+	 * @param picker
+	 * @param x
+	 * @param y
+	 * @param z
+	 * @return
+	 */
+	public abstract boolean onPickup(L2ItemInstance item, L2PcInstance picker, int x, int y, int z);
+	
+	@Override
+	public void register()
+	{
+		L2ItemInstance.addDropListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		L2ItemInstance.removeDropListener(this);
+	}
+}

+ 79 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/EquipmentListener.java

@@ -0,0 +1,79 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Equip and unequip listener.<br>
+ * This listener can be either global or player-based<br>
+ * Use the boolean in the constructor!
+ * @author TheOne
+ */
+public abstract class EquipmentListener extends L2JListener
+{
+	private boolean isGlobal = false;
+	
+	/**
+	 * Constructor To set a global listener, set the L2PcInstance value to null
+	 * @param character
+	 */
+	public EquipmentListener(L2PcInstance character)
+	{
+		player = character;
+		if (character == null)
+		{
+			isGlobal = true;
+		}
+		register();
+	}
+	
+	/**
+	 * The item has just been equipped or unequipped
+	 * @param item
+	 * @param isEquipped
+	 * @return
+	 */
+	public abstract boolean onEquip(L2ItemInstance item, boolean isEquipped);
+	
+	@Override
+	public void register()
+	{
+		if (isGlobal)
+		{
+			L2PcInstance.addGlobalEquipmentListener(this);
+		}
+		else
+		{
+			player.addEquipmentListener(this);
+		}
+	}
+	
+	@Override
+	public void unregister()
+	{
+		if (isGlobal)
+		{
+			L2PcInstance.removeGlobalEquipmentListener(this);
+		}
+		else
+		{
+			player.removeEquipmentListener(this);
+		}
+	}
+	
+}

+ 58 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/HennaListener.java

@@ -0,0 +1,58 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.items.instance.L2HennaInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * @author TheOne
+ */
+public abstract class HennaListener extends L2JListener
+{
+	public HennaListener()
+	{
+		register();
+	}
+	
+	/**
+	 * The given henna has just been added to the player
+	 * @param player
+	 * @param henna
+	 * @return
+	 */
+	public abstract boolean onAddHenna(L2PcInstance player, L2HennaInstance henna);
+	
+	/**
+	 * The given henna has just been removed from the player
+	 * @param player
+	 * @param henna
+	 * @return
+	 */
+	public abstract boolean onRemoveHenna(L2PcInstance player, L2HennaInstance henna);
+	
+	@Override
+	public void register()
+	{
+		L2PcInstance.addHennaListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		L2PcInstance.removeHennaListener(this);
+	}
+}

+ 91 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/ItemTracker.java

@@ -0,0 +1,91 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import java.util.List;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.itemcontainer.ItemContainer;
+import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * This listener allows you to track items with certain item ids.<br>
+ * This can be very useful if you want to make a script which will track all high value items and will log their movements/creation/drop/etc.<br>
+ * It can be a great tool to catch hackers on your server ;)
+ * @author TheOne
+ */
+public abstract class ItemTracker extends L2JListener
+{
+	private List<Integer> _itemIds;
+	
+	public ItemTracker(List<Integer> itemIds)
+	{
+		_itemIds = itemIds;
+		register();
+	}
+	
+	/**
+	 * The item has been dropped
+	 * @param item
+	 * @param player
+	 */
+	public abstract void onDrop(L2ItemInstance item, L2PcInstance player);
+	
+	/**
+	 * The item has been added to the inventory
+	 * @param item
+	 * @param player
+	 */
+	public abstract void onAddToInventory(L2ItemInstance item, L2PcInstance player);
+	
+	/**
+	 * Notifies when the item is destroyed
+	 * @param item
+	 * @param player
+	 */
+	public abstract void onDestroy(L2ItemInstance item, L2PcInstance player);
+	
+	/**
+	 * Notifies when the item is transfered or traded
+	 * @param item
+	 * @param player
+	 * @param target
+	 */
+	public abstract void onTransfer(L2ItemInstance item, L2PcInstance player, ItemContainer target);
+	
+	@Override
+	public void register()
+	{
+		PcInventory.addItemTracker(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		PcInventory.removeItemTracker(this);
+	}
+	
+	/**
+	 * Checks if this item is tracked
+	 * @param itemId
+	 * @return
+	 */
+	public boolean containsItemId(int itemId)
+	{
+		return _itemIds.contains(itemId);
+	}
+}

+ 61 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/NewItemListener.java

@@ -0,0 +1,61 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import java.util.List;
+
+import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Watches for specific item Ids and triggers the listener when one of these items is created
+ * @author TheOne
+ */
+public abstract class NewItemListener extends L2JListener
+{
+	private List<Integer> _itemIds;
+	
+	public NewItemListener(List<Integer> itemIds)
+	{
+		_itemIds = itemIds;
+		register();
+	}
+	
+	/**
+	 * An item corresponding to the itemIds list was just created
+	 * @param itemId
+	 * @param player
+	 * @return
+	 */
+	public abstract boolean onCreate(int itemId, L2PcInstance player);
+	
+	@Override
+	public void register()
+	{
+		ItemTable.addNewItemListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		ItemTable.removeNewItemListener(this);
+	}
+	
+	public boolean containsItemId(int itemId)
+	{
+		return _itemIds.contains(itemId);
+	}
+}

+ 43 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/PlayerDespawnListener.java

@@ -0,0 +1,43 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * @author TheOne
+ */
+public abstract class PlayerDespawnListener extends L2JListener
+{
+	public PlayerDespawnListener()
+	{
+		register();
+	}
+	
+	public abstract void onDespawn(L2PcInstance player);
+	
+	@Override
+	public void register()
+	{
+		L2PcInstance.addDespawnListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		L2PcInstance.removeDespawnListener(this);
+	}
+}

+ 63 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/PlayerLevelListener.java

@@ -0,0 +1,63 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.stat.PcStat;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Listens for player level changes<br>
+ * If you wish to have a global listener for all the players logged in, set the L2PcInstance to null.<br>
+ * @author TheOne
+ */
+public abstract class PlayerLevelListener extends L2JListener
+{
+	
+	/**
+	 * constructor
+	 * @param player
+	 */
+	public PlayerLevelListener(L2PcInstance player)
+	{
+		super.player = player;
+		register();
+	}
+	
+	public abstract void levelChanged(L2PcInstance player, int oldLevel, int newLevel);
+	
+	@Override
+	public void register()
+	{
+		if (player == null)
+		{
+			PcStat.addGlobalLevelListener(this);
+			return;
+		}
+		player.getStat().addLevelListener(this);
+		
+	}
+	
+	@Override
+	public void unregister()
+	{
+		if (player == null)
+		{
+			PcStat.removeGlobalLevelListener(this);
+			return;
+		}
+		player.getStat().removeLevelListener(this);
+	}
+}

+ 50 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/PlayerSpawnListener.java

@@ -0,0 +1,50 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.clientpackets.EnterWorld;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Gets triggered when a L2PcInstance is spawned in the world
+ * @author TheOne
+ */
+public abstract class PlayerSpawnListener extends L2JListener
+{
+	public PlayerSpawnListener()
+	{
+		register();
+	}
+	
+	/**
+	 * Triggered when a player is spawned
+	 * @param player
+	 */
+	public abstract void onSpawn(L2PcInstance player);
+	
+	@Override
+	public void register()
+	{
+		EnterWorld.addSpawnListener(this);
+		
+	}
+	
+	@Override
+	public void unregister()
+	{
+		EnterWorld.removeSpawnListener(this);
+	}
+}

+ 62 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/ProfessionChangeListener.java

@@ -0,0 +1,62 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.actor.templates.L2PcTemplate;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Listener for player profession change.<br>
+ * Set player to null if you want to set a global listener for all players on server.
+ * @author TheOne
+ */
+public abstract class ProfessionChangeListener extends L2JListener
+{
+	
+	/**
+	 * constructor
+	 * @param player
+	 */
+	public ProfessionChangeListener(L2PcInstance player)
+	{
+		super.player = player;
+		register();
+	}
+	
+	public abstract void professionChanged(L2PcInstance player, boolean isSubClass, L2PcTemplate template);
+	
+	@Override
+	public void register()
+	{
+		if (player != null)
+		{
+			player.addProfessionChangeListener(this);
+			return;
+		}
+		L2PcInstance.addGlobalProfessionChangeListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		if (player != null)
+		{
+			player.removeProfessionChangeListener(this);
+			return;
+		}
+		L2PcInstance.removeGlobalProfessionChangeListener(this);
+	}
+}

+ 63 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/player/TransformListener.java

@@ -0,0 +1,63 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.player;
+
+import com.l2jserver.gameserver.model.L2Transformation;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * @author TheOne
+ */
+public abstract class TransformListener extends L2JListener
+{
+	
+	/**
+	 * constructor
+	 * @param player
+	 */
+	public TransformListener(L2PcInstance player)
+	{
+		this.player = player;
+		register();
+	}
+	
+	/**
+	 * The player just transformed
+	 * @param transformation
+	 * @return
+	 */
+	public abstract boolean onTransform(L2Transformation transformation);
+	
+	/**
+	 * The player just untransformed
+	 * @param transformation
+	 * @return
+	 */
+	public abstract boolean onUntransform(L2Transformation transformation);
+	
+	@Override
+	public void register()
+	{
+		player.addTransformListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		player.removeTransformListener(this);
+	}
+	
+}

+ 55 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/talk/ChatFilterListener.java

@@ -0,0 +1,55 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.talk;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+import com.l2jserver.gameserver.scripting.scriptengine.listeners.talk.ChatListener.ChatTargetType;
+
+/**
+ * Listener to intercept player chat.<br>
+ * Could be useful to improve or customize the integrated chat filters (i.e.: make it dependent on who's sending the message and the chat type... for example GMs could be unfiltered?).<br>
+ * See Say2.java
+ * @author TheOne
+ */
+public abstract class ChatFilterListener extends L2JListener
+{
+	public ChatFilterListener()
+	{
+		register();
+	}
+	
+	/**
+	 * Allows for filtering the text
+	 * @param text
+	 * @param origin
+	 * @param targetType
+	 * @return
+	 */
+	public abstract String onTalk(String text, L2PcInstance origin, ChatTargetType targetType);
+	
+	@Override
+	public void register()
+	{
+		Say2.addChatFilterListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		Say2.removeChatFilterListener(this);
+	}
+}

+ 105 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/scripting/scriptengine/listeners/talk/ChatListener.java

@@ -0,0 +1,105 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.scripting.scriptengine.listeners.talk;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.scripting.scriptengine.impl.L2JListener;
+
+/**
+ * Listener to intercept player chat.<br>
+ * Useful to create customized chat log or any other use you can find for it.<br>
+ * See network.Say2.java
+ * @author TheOne
+ */
+public abstract class ChatListener extends L2JListener
+{
+	public ChatListener()
+	{
+		register();
+	}
+	
+	/**
+	 * Notifies that the given text was sent from player1(origin) to a given target.<br>
+	 * @param text
+	 * @param origin
+	 * @param target
+	 * @param targetType
+	 */
+	public abstract void onTalk(String text, L2PcInstance origin, String target, ChatTargetType targetType);
+	
+	@Override
+	public void register()
+	{
+		Say2.addChatListener(this);
+	}
+	
+	@Override
+	public void unregister()
+	{
+		Say2.removeChatListener(this);
+	}
+	
+	/**
+	 * Defines the type of talk/chat taking place
+	 * @author TheOne
+	 */
+	public enum ChatTargetType
+	{
+		ALL,
+		SHOUT,
+		TELL,
+		PARTY,
+		CLAN,
+		GM,
+		PETITION_PLAYER,
+		PETITION_GM,
+		TRADE,
+		ALLIANCE,
+		ANNOUNCEMENT,
+		BOAT,
+		L2FRIEND,
+		MSNCHAT,
+		PARTYMATCH_ROOM,
+		PARTYROOM_COMMANDER,
+		PARTYROOM_ALL,
+		HERO_VOICE,
+		CRITICAL_ANNOUNCE,
+		SCREEN_ANNOUNCE,
+		BATTLEFIELD,
+		MPCC_ROOM
+	}
+	
+	/**
+	 * Returns the ChatTargetType based on the type (String) given.<br>
+	 * Default = ChatTargetType.ALL
+	 * @param type
+	 * @return
+	 */
+	public static ChatTargetType getTargetType(String type)
+	{
+		ChatTargetType targetType = ChatTargetType.ALL;
+		try
+		{
+			targetType = ChatTargetType.valueOf(type);
+		}
+		catch (Exception e)
+		{
+			log.info("Invalid ChatTargetType:" + type);
+			e.getMessage();
+		}
+		return targetType;
+	}
+}