All pastes #38971 Raw Edit

Gnipi

public text v1 · immutable
#38971 ·published 2006-01-29 01:52 UTC
rendered paste body
Index: C:/workspace/L2_GameServer/java/config/altsettings.properties
===================================================================
--- C:/workspace/L2_GameServer/java/config/altsettings.properties	(revision 2218)
+++ C:/workspace/L2_GameServer/java/config/altsettings.properties	(working copy)
@@ -20,6 +20,11 @@
 # - players get EXP/SP for crafting
 AltGameCreation = False
 
+# Alt game creation XP/SP based on mana
+# new XP/SP reward system, calculation based on
+# mana used to craft item
+AltGameCreationByMana = False
+
 # Alternative skill learn rules:
 # - all classes can learn all skills
 # - skills of another class costs x2 SP
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/status/Status.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/status/Status.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/status/Status.java	(working copy)
@@ -43,6 +43,7 @@
                 	if(lst.isAlive())
                 	{
                 		_loginStatus.add(lst);
+                        lst.setPriority(lst.getPriority()+1); // raise priority a bit
                 	}
                 }
                 if (this.isInterrupted())
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/status/GameStatusThread.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/status/GameStatusThread.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/status/GameStatusThread.java	(working copy)
@@ -245,6 +246,12 @@
                     {
                         _print.println(line);
                     }
+                    _print.println();
+                    // maxMemory is the upper limit the jvm can use, totalMemory the size of the current allocation pool, freeMemory the unused memory in the allocation pool
+                    long freeMem = (Runtime.getRuntime().maxMemory()-Runtime.getRuntime().totalMemory()+Runtime.getRuntime().freeMemory()) / 1024 / 1024;
+                    long totalMem = Runtime.getRuntime().maxMemory() / 1024 / 1024;
+                    _print.println("Free memory "+freeMem+" Mb of "+totalMem+" Mb total");
+                    _print.println();
                     _print.flush();
                 }
                 else if (_usrCommand.startsWith("announce"))
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/Config.java	(working copy)
@@ -72,8 +72,11 @@
     
     /** Thread pools size */
     public static int THREAD_P_HIGH;
+    public static int THREAD_P_MEDHIGH;
     public static int THREAD_P_MED;
     public static int THREAD_P_LOW;
+    public static int THREAD_P_AI;
+    public static int THREAD_P_CRAFT;    
     
     /** Auto-loot? */
     public static boolean AUTO_LOOT;
@@ -83,10 +86,16 @@
 
     /** Global chat state */
     public static String  DEFAULT_GLOBAL_CHAT;
+    
     /** For test servers - evrybody has admin rights */
     public static boolean EVERYBODY_HAS_ADMIN_RIGHTS;
+
     /** Alternative game crafting */
     public static boolean ALT_GAME_CREATION;
+    
+    /** Reward XP/SP to crafter based on mana **/
+    public static boolean ALT_GAME_CREATION_BY_MANA;
+    
     /** Alternative game skill learning */
     public static boolean ALT_GAME_SKILL_LEARN;
     /** Cancel ATTACK/cast by hit */
@@ -388,9 +400,11 @@
     
     public static int      EXECUTOR_PRI_LOW;
     public static int      EXECUTOR_PRI_MED;
+    public static int      EXECUTOR_PRI_MEDHIGH;
     public static int      EXECUTOR_PRI_HIGH;
-
-    
+    public static int      EXECUTOR_PRI_AI;
+    public static int      EXECUTOR_PRI_CRAFT;
+      
 	public static enum IdFactoryType
     {
 	    Compaction,
@@ -586,8 +606,11 @@
 
 	            AUTODELETE_INVALID_QUEST_DATA   = Boolean.valueOf(serverSettings.getProperty("AutoDeleteInvalidQuestData", "False"));
 	            THREAD_P_HIGH                   = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeHigh", "4"));
-	            THREAD_P_MED                    = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeMed", "10"));
-	            THREAD_P_LOW                    = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeLow", "4"));
+	            THREAD_P_MEDHIGH                = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeMedHigh","4"));
+                THREAD_P_MED                    = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeMed",  "4"));
+	            THREAD_P_LOW                    = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeLow",   "4"));
+	            THREAD_P_AI                     = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeAi",    "4"));	            
+	            THREAD_P_CRAFT                  = Integer.parseInt(serverSettings.getProperty("ThreadPoolSizeCraft", "4"));
 	            
 	            MAXIMUM_ONLINE_USERS        = Integer.parseInt(serverSettings.getProperty("MaximumOnlineUsers", "100"));
 	            
@@ -620,7 +643,10 @@
                 
                 EXECUTOR_PRI_LOW = Integer.parseInt(serverSettings.getProperty("ExecutorPriLow", "-1"));
                 EXECUTOR_PRI_MED = Integer.parseInt(serverSettings.getProperty("ExecutorPriMed", "0"));
-                EXECUTOR_PRI_HIGH = Integer.parseInt(serverSettings.getProperty("ExecutorPriHigh", "1"));
+                EXECUTOR_PRI_MEDHIGH = Integer.parseInt(serverSettings.getProperty("ExecutorPriMedHigh", "1"));
+                EXECUTOR_PRI_HIGH = Integer.parseInt(serverSettings.getProperty("ExecutorPriHigh", "2"));
+                EXECUTOR_PRI_AI = Integer.parseInt(serverSettings.getProperty("ExecutorPriAi", "0"));
+                EXECUTOR_PRI_CRAFT = Integer.parseInt(serverSettings.getProperty("ExecutorPriCraft", "0"));                
 	        }
 	        catch (Exception e)
 	        {
@@ -793,25 +826,26 @@
 	            altSettings.load(is);
 	            is.close();
 	            
-	            ALT_GAME_TIREDNESS      = Boolean.parseBoolean(altSettings.getProperty("AltGameTiredness", "false"));
-	            ALT_GAME_CREATION       = Boolean.parseBoolean(altSettings.getProperty("AltGameCreation", "false"));
-	            ALT_GAME_SKILL_LEARN    = Boolean.parseBoolean(altSettings.getProperty("AltGameSkillLearn", "false"));
-	            ALT_GAME_CANCEL_BOW     = altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("bow") || altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("all");
-	            ALT_GAME_CANCEL_CAST    = altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("cast") || altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("all");
-	            ALT_GAME_SHIELD_BLOCKS  = Boolean.parseBoolean(altSettings.getProperty("AltShieldBlocks", "false"));
-	            ALT_GAME_DELEVEL        = Boolean.parseBoolean(altSettings.getProperty("Delevel", "true"));
-	            ALT_GAME_MOB_ATTACK_AI  = Boolean.parseBoolean(altSettings.getProperty("AltGameMobAttackAI", "false"));
-	            ALT_GAME_SKILL_FORMULAS = altSettings.getProperty("AltGameSkillFormulas", "none");
-	            ALT_GAME_EXPONENT_XP    = Float.parseFloat(altSettings.getProperty("AltGameExponentXp", "0."));
-	            ALT_GAME_EXPONENT_SP    = Float.parseFloat(altSettings.getProperty("AltGameExponentSp", "0."));
-	            ALLOW_CLASS_MASTERS     = Boolean.valueOf(altSettings.getProperty("AllowClassMasters", "False"));
-	            ALT_GAME_FREIGHTS       = Boolean.parseBoolean(altSettings.getProperty("AltGameFreights", "false"));
-	            ALT_GAME_FREIGHT_PRICE  = Integer.parseInt(altSettings.getProperty("AltGameFreightPrice", "1000"));
-	            ALT_GAME_SKILL_HIT_RATE = Float.parseFloat(altSettings.getProperty("AltGameSkillHitRate", "1."));
-	            ENABLE_RATE_HP          = Boolean.parseBoolean(altSettings.getProperty("EnableRateHp", "false"));
-	            IS_CRAFTING_ENABLED     = Boolean.parseBoolean(altSettings.getProperty("CraftingEnabled", "true"));
-	            SP_BOOK_NEEDED          = Boolean.parseBoolean(altSettings.getProperty("SpBookNeeded", "true"));
-	            AUTO_LOOT               = altSettings.getProperty("AutoLoot").equalsIgnoreCase("True");
+	            ALT_GAME_TIREDNESS         = Boolean.parseBoolean(altSettings.getProperty("AltGameTiredness", "false"));
+	            ALT_GAME_CREATION          = Boolean.parseBoolean(altSettings.getProperty("AltGameCreation", "false"));
+                ALT_GAME_CREATION_BY_MANA  = Boolean.parseBoolean(altSettings.getProperty("AltGameCreationByMana", "false"));
+	            ALT_GAME_SKILL_LEARN       = Boolean.parseBoolean(altSettings.getProperty("AltGameSkillLearn", "false"));
+	            ALT_GAME_CANCEL_BOW        = altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("bow") || altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("all");
+	            ALT_GAME_CANCEL_CAST       = altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("cast") || altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("all");
+	            ALT_GAME_SHIELD_BLOCKS     = Boolean.parseBoolean(altSettings.getProperty("AltShieldBlocks", "false"));
+	            ALT_GAME_DELEVEL           = Boolean.parseBoolean(altSettings.getProperty("Delevel", "true"));
+	            ALT_GAME_MOB_ATTACK_AI     = Boolean.parseBoolean(altSettings.getProperty("AltGameMobAttackAI", "false"));
+	            ALT_GAME_SKILL_FORMULAS    = altSettings.getProperty("AltGameSkillFormulas", "none");
+	            ALT_GAME_EXPONENT_XP       = Float.parseFloat(altSettings.getProperty("AltGameExponentXp", "0."));
+	            ALT_GAME_EXPONENT_SP       = Float.parseFloat(altSettings.getProperty("AltGameExponentSp", "0."));
+	            ALLOW_CLASS_MASTERS        = Boolean.valueOf(altSettings.getProperty("AllowClassMasters", "False"));
+	            ALT_GAME_FREIGHTS          = Boolean.parseBoolean(altSettings.getProperty("AltGameFreights", "false"));
+	            ALT_GAME_FREIGHT_PRICE     = Integer.parseInt(altSettings.getProperty("AltGameFreightPrice", "1000"));
+	            ALT_GAME_SKILL_HIT_RATE    = Float.parseFloat(altSettings.getProperty("AltGameSkillHitRate", "1."));
+	            ENABLE_RATE_HP             = Boolean.parseBoolean(altSettings.getProperty("EnableRateHp", "false"));
+	            IS_CRAFTING_ENABLED        = Boolean.parseBoolean(altSettings.getProperty("CraftingEnabled", "true"));
+	            SP_BOOK_NEEDED             = Boolean.parseBoolean(altSettings.getProperty("SpBookNeeded", "true"));
+	            AUTO_LOOT                  = altSettings.getProperty("AutoLoot").equalsIgnoreCase("True");
                 ALT_GAME_KARMA_PLAYER_CAN_BE_KILLED_IN_PEACEZONE    = Boolean.valueOf(altSettings.getProperty("AltKarmaPlayerCanBeKilledInPeaceZone", "false"));
                 ALT_GAME_KARMA_PLAYER_CAN_SHOP                      = Boolean.valueOf(altSettings.getProperty("AltKarmaPlayerCanShop", "true"));
                 ALT_GAME_KARMA_PLAYER_CAN_TELEPORT                  = Boolean.valueOf(altSettings.getProperty("AltKarmaPlayerCanTeleport", "true"));
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/Server.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/Server.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/Server.java	(working copy)
@@ -79,6 +79,7 @@
 		if ( Config.IS_TELNET_ENABLED ) {
 		    statusServer = new Status(0);
 		    statusServer.start();
+            statusServer.setPriority(statusServer.getPriority()+1); // telnet is very important, even on high cpu load this should make it work properly
 		}
 		else {
 		    System.out.println("Telnet server is currently disabled.");
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SelectorThread.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SelectorThread.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/SelectorThread.java	(working copy)
@@ -146,7 +146,7 @@
 		this._hostname = hostname;
 		this._port = port;
 		this.setDaemon(true);
-		this.setPriority(Thread.NORM_PRIORITY+1);
+		this.setPriority(Thread.NORM_PRIORITY+2);
 		// write buffers (HeapByteBuffer is much faster for our perposes)
 		writeBuffers = new ByteBuffer[WRITE_BUF_HASH_SIZE];
 		for (int i=0; i < WRITE_BUF_HASH_SIZE; i++) {
@@ -723,7 +723,7 @@
             packetHistory.clear();
             byteHistory.clear();
             
-            packetMonitor   = ClientScheduler.getInstance().scheduleLowAtFixedRate(
+            packetMonitor   = ClientScheduler.getInstance().scheduleMedAtFixedRate(
                 new Runnable()
                 {
                     public void run()
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestRecipeItemMakeSelf.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestRecipeItemMakeSelf.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/clientpackets/RequestRecipeItemMakeSelf.java	(working copy)
@@ -19,8 +19,10 @@
 package net.sf.l2j.gameserver.clientpackets;
 
 import java.nio.ByteBuffer;
+import java.util.logging.Logger;
 
 import net.sf.l2j.gameserver.ClientThread;
+import net.sf.l2j.gameserver.GameServer;
 import net.sf.l2j.gameserver.RecipeController;
 import net.sf.l2j.gameserver.model.L2PcInstance;
 
@@ -33,7 +35,7 @@
 public class RequestRecipeItemMakeSelf extends ClientBasePacket 
 {
     private static final String _C__AF_REQUESTRECIPEITEMMAKESELF = "[C] AF RequestRecipeItemMakeSelf";
-	//private static Logger _log = Logger.getLogger(RequestSellItem.class.getName());
+    private static final Logger _log = Logger.getLogger(RequestRecipeItemMakeSelf.class.getName());
 
 	private final int _id;
 	/**
@@ -60,6 +62,7 @@
         if (activeChar.isInCraftMode())
         {
             activeChar.sendMessage("Currently in Craft Mode");
+            _log.warning("Currently in Craft Mode");
             return;
         }
         
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Potion.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Potion.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Potion.java	(working copy)
@@ -24,7 +24,6 @@
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.ClientScheduler;
 
-
 /**
  * 
  * This class ...
@@ -65,15 +64,13 @@
 				{
 					double nowHp = _instance.getCurrentHp();
 					if(_duration == 0)
-					{
 						stopPotionHpRegeneration();
-					}
-					if (_duration != 0)
+					else
 					{
 						nowHp     += _effect;
 						_instance.setCurrentHp(nowHp);
-						_duration = _duration - (_milliseconds / 1000);
-						setCurrentHpPotion2();
+						_duration -= (_milliseconds / 1000);
+						if(_duration==0) stopPotionHpRegeneration();
 					}
 				}
 			}
@@ -100,13 +97,6 @@
 		if (Config.DEBUG) _log.fine("Potion HP regen stop");
 	}
 
-	public void setCurrentHpPotion2()
-	{
-		if (_duration == 0)
-		{
-			stopPotionHpRegeneration();
-		}
-	}
 	public void setCurrentHpPotion1(L2Character activeChar, int item)
 	{
 		_potion = item;
@@ -114,23 +104,8 @@
 
 		switch (_potion)
 		{
-			case (1540): 
-				double nowHp = activeChar.getCurrentHp();
-				nowHp+=435;
-				if (nowHp>= activeChar.getMaxHp())
-				{
-					nowHp = activeChar.getMaxHp();
-				}
-				activeChar.setCurrentHp(nowHp);
-			case (728):	
-				double nowMp = activeChar.getMaxMp();
-				nowMp+=435;
-				if (nowMp>= activeChar.getMaxMp())
-				{
-					nowMp = activeChar.getMaxMp();
-				}
-				activeChar.setCurrentMp(nowMp);
-				break;
+			case (1540): activeChar.setCurrentHp(java.lang.Math.min(activeChar.getCurrentHp()+435,(double)activeChar.getMaxHp()));break;
+			case (728) : activeChar.setCurrentMp(java.lang.Math.min(activeChar.getCurrentMp()+435,(double)activeChar.getMaxMp()));break;
 			case (726):
 				_milliseconds = 500;
 				_duration = 15;
@@ -157,16 +132,13 @@
 				{
 					double nowMp = _instance.getCurrentMp();
 					if(_duration == 0)
+                        stopPotionMpRegeneration();
+                    else
 					{
-						stopPotionMpRegeneration();
-					}
-					if (_duration != 0)
-					{
 						nowMp+=_effect;
 						_instance.setCurrentMp(nowMp);
 						_duration=(_duration-(_milliseconds/1000));
-						setCurrentMpPotion2();
-						
+                        if(_duration == 0) stopPotionMpRegeneration();
 					}
 				}
 			}
@@ -179,7 +151,7 @@
 	
 	private void startPotionMpRegeneration(L2Character activeChar)
 	{
-		_potionmpRegTask = ClientScheduler.getInstance().scheduleMedAtFixedRate(
+		_potionmpRegTask = ClientScheduler.getInstance().scheduleMedHighAtFixedRate(
 				new PotionMpHealing(activeChar), 1000, _milliseconds);
 		if (Config.DEBUG) _log.fine("Potion MP regen Started");
 	}
@@ -195,14 +167,6 @@
 		if (Config.DEBUG) _log.fine("Potion MP regen stop");
 	}
 
-	public void setCurrentMpPotion2()
-	{
-		if (_duration == 0)
-		{
-			stopPotionMpRegeneration();
-		}
-	}
-	
 	public void setCurrentMpPotion1(L2Character activeChar, int item)
 	{
 		_potion = item;
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/actor/character/CharStatus.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/actor/character/CharStatus.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/actor/character/CharStatus.java	(working copy)
@@ -187,7 +187,7 @@
             int period = Formulas.getInstance().getRegeneratePeriod(getActiveChar());
 
             // Create the HP/MP/CP Regeneration task
-            _RegTask = ClientScheduler.getInstance().scheduleMedAtFixedRate(new RegenTask(), period, period);
+            _RegTask = ClientScheduler.getInstance().scheduleMedHighAtFixedRate(new RegenTask(), period, period);
         }
     }
 
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2MonsterInstance.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2MonsterInstance.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2MonsterInstance.java	(working copy)
@@ -109,9 +109,7 @@
                         try
                         {
                             minionList.maintainMinions();
-    			//must be fixed. class exception.
-                            //for(L2MinionInstance minion : minionList.getSpawnedMinions())
-                            //    minion.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
+                            callMinions();
                         }
                         catch (Throwable e) 
                         {
@@ -145,7 +143,8 @@
                     Random rnd = getRnd();
                     int minionX = masterX + (rnd.nextInt(401) - 200);
                     int minionY = masterY + (rnd.nextInt(401) - 200);
-                    int minionZ = masterZ;
+                    int minionZ = masterZ+50;  // just in case master is on high ground, shouldn't hurt ?
                     while (((minionX != (masterX + 30)) && (minionX != (masterX - 30))) || ((minionY != (masterY + 30)) && (minionY != (masterY - 30))))
                     {
                         minionX = masterX + (rnd.nextInt(401) - 200);
@@ -186,7 +183,7 @@
     {
         if (minionMaintainTask != null)
             minionMaintainTask.cancel(true);
-        
+        minionMaintainTask=null;
         super.doDie(killer);
     }
     
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Clan.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Clan.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Clan.java	(working copy)
@@ -118,6 +127,7 @@
 	 */
 	public int getLeaderId()
 	{
+        if (_leader==null) setNewLeader();
 		return _leader.getObjectId();
 	}
     /**
@@ -125,6 +135,7 @@
      */
     public L2ClanMember getLeader()
     {
+        if (_leader==null) setNewLeader();
         return _leader;
     }
 	/**
@@ -160,7 +172,8 @@
 	 */
 	public String getLeaderName()
 	{
-		return _leader.getName();
+		if (_leader==null) setNewLeader();
+        return _leader.getName();
 	}
 
 	/**
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Skill.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Skill.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Skill.java	(working copy)
@@ -159,7 +159,8 @@
         DRAIN_SOUL,
         
         // unimplemented
-        NOTDONE;
+        NOTDONE,
+        MDAM_ELEMENTAL;
         
         private final Class<? extends L2Skill> clazz;
         
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Attackable.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Attackable.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/model/L2Attackable.java	(working copy)
@@ -339,7 +339,7 @@
             if (this instanceof L2MinionInstance)
             {
                 master = ((L2MinionInstance)this).getLeader();
-                if (!master.isInCombat())
+                if (!master.isInCombat()&&!master.isDead())
                     master.addDamage(attacker, 1);
             }
             if (master.hasMinions())
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2AttackableAI.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2AttackableAI.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2AttackableAI.java	(working copy)
@@ -206,45 +206,53 @@
 	 */
 	synchronized void changeIntention(CtrlIntention intention, Object arg0, Object arg1)
 	{
-		if (intention == AI_INTENTION_IDLE || intention == AI_INTENTION_ACTIVE)
+        if (intention == AI_INTENTION_ACTIVE)
+        {
+            intention = AI_INTENTION_IDLE;  // suppose we don't need AI anymore
+
+            // Check if actor is not dead
+            if(!_actor.isAlikeDead())
+            {
+                // find at least one L2PcInstance worth keeping AI active (in knownlist but also not dead)
+                for(L2PcInstance in:((L2Attackable)_actor).getKnownList().getKnownPlayers())
+                {
+                    if(in!=null && !in.isAlikeDead()) 
+                    { 
+                        intention=AI_INTENTION_ACTIVE;  // found one, worth activating
+                        break;
+                    }   
+                }
+            }
+        }
+        
+        // ==================================================================
+			
+        if (intention == AI_INTENTION_IDLE)
 		{
-			// Check if actor is not dead
-			if (!_actor.isAlikeDead())
+			// Set the Intention of this L2AttackableAI to AI_INTENTION_IDLE
+			super.changeIntention(AI_INTENTION_IDLE, null, null);
+			
+			// Stop AI task and detach AI from NPC
+			if (aiTask != null)
 			{
-	            L2Attackable npc = (L2Attackable)_actor;
-				
-				// If its _knownPlayer isn't empty set the Intention to AI_INTENTION_ACTIVE
-				Collection<L2PcInstance> knownPlayers = npc.getKnownList().getKnownPlayers();
-                if (knownPlayers != null && knownPlayers.size() > 0)
-					intention = AI_INTENTION_ACTIVE;
+				aiTask.cancel(true);
+				aiTask = null;
 			}
-			
-			if (intention == AI_INTENTION_IDLE)
-			{
-				// Set the Intention of this L2AttackableAI to AI_INTENTION_IDLE
-				super.changeIntention(AI_INTENTION_IDLE, null, null);
-				
-				// Stop AI task and detach AI from NPC
-				if (aiTask != null)
-				{
-					aiTask.cancel(true);
-					aiTask = null;
-				}
 
-				// Cancel the AI
-				_accessor.detachAI();
+			// Cancel the AI
+			_accessor.detachAI();
 				
-				return;
-			}
+			return;
 		}
 		
+		
 		// Set the Intention of this L2AttackableAI to intention
 		super.changeIntention(intention, arg0, arg1);
 		
 		// If not idle - create an AI task (schedule onEvtThink repeatedly)
 		if (aiTask == null)
 		{
-			aiTask = ClientScheduler.getInstance().scheduleLowAtFixedRate(this, 1000, 1000);
+			aiTask = ClientScheduler.getInstance().scheduleAiAtFixedRate(this, 1000, 1000);
 		}
 		
 	}
@@ -351,7 +359,7 @@
 			
 			
 			// Order to the L2Attackable to attack the target
-			if (hated != null) 
+			if (hated != null && !hated.isAlikeDead()) 
 			{
 				// Get the hate level of the L2Attackable against this L2Character target contained in _aggroList
 				int aggro = npc.getHating(hated);
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2PlayerAI.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2PlayerAI.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/L2PlayerAI.java	(working copy)
@@ -255,6 +255,8 @@
 	private void thinkPickUp() {
 		if (_actor.isAllSkillsDisabled())
 			return;
+        if (_actor.isAlikeDead())
+            return;
 		if (checkTargetLost(getTarget()))
 			return;
 		if (maybeMoveToPawn(getTarget(), 36))
@@ -155,40 +153,41 @@
      */
     synchronized void changeIntention(CtrlIntention intention, Object arg0, Object arg1)
     {
-        if (Config.DEBUG)
-            _log.info("L2SiegeAI.changeIntention(" + intention + ", " + arg0 + ", " + arg1+")");
+        if (intention == AI_INTENTION_ACTIVE)
+        {
+            intention = AI_INTENTION_IDLE;
 
-        if (intention == AI_INTENTION_IDLE || intention == AI_INTENTION_ACTIVE)
-        {
             // Check if actor is not dead
             if(!_actor.isAlikeDead())
             {
-                L2Attackable npc = (L2Attackable)_actor;
-                
-                // If its _knownPlayer isn't empty set the Intention to AI_INTENTION_ACTIVE
-                if(npc.getKnownList().getKnownPlayers().size() > 0)
-                    intention = AI_INTENTION_ACTIVE;
-                else
-                    intention = AI_INTENTION_IDLE;
+                // find at least one L2PcInstance worth keeping AI active (in knownlist but also not dead)
+                for(L2PcInstance in:((L2Attackable)_actor).getKnownList().getKnownPlayers())
+                {
+                    if(in!=null && !in.isAlikeDead()) 
+                    { 
+                        intention=AI_INTENTION_ACTIVE;  // found one, worth activating
+                        break;
+                    }   
+                }
             }
+        }
             
-            if (intention == AI_INTENTION_IDLE)
+        if (intention == AI_INTENTION_IDLE)
+        {
+            // Set the Intention of this L2AttackableAI to AI_INTENTION_IDLE
+            super.changeIntention(AI_INTENTION_IDLE, null, null);
+                
+            // Stop AI task and detach AI from NPC
+            if (aiTask != null)
             {
-                // Set the Intention of this L2AttackableAI to AI_INTENTION_IDLE
-                super.changeIntention(AI_INTENTION_IDLE, null, null);
-                
-                // Stop AI task and detach AI from NPC
-                if (aiTask != null)
-                {
-                    aiTask.cancel(true);
-                    aiTask = null;
-                }
+                aiTask.cancel(true);
+                aiTask = null;
+            }
 
-                // Cancel the AI
-                _accessor.detachAI();
+            // Cancel the AI
+            _accessor.detachAI();
                 
-                return;
-            }
+            return;
         }
         
         // Set the Intention of this L2AttackableAI to intention
@@ -197,7 +196,7 @@
         // If not idle - create an AI task (schedule onEvtThink repeatedly)
         if (aiTask == null)
         {
-            aiTask = ClientScheduler.getInstance().scheduleLowAtFixedRate(this, 1000, 1000);
+            aiTask = ClientScheduler.getInstance().scheduleAiAtFixedRate(this, 1000, 1000);
         }
     }
     
@@ -562,11 +561,22 @@
     {
 //      if(getIntention() != AI_INTENTION_IDLE && (!_actor.isVisible() || !_actor.hasAI() || !_actor.isKnownPlayers()))
 //          setIntention(AI_INTENTION_IDLE);
+        
+        // Check if the actor can't use skills and if a thinking action isn't already in progress
+      if (thinking || _actor.isAllSkillsDisabled())
+        return;
+        
+      if((!_actor.isVisible()) || (!_actor.hasAI()))
+          setIntention(AI_INTENTION_IDLE);
 
+      if((getIntention() == AI_INTENTION_FOLLOW) && (_actor.getKnownList().getKnownPlayers().isEmpty()))
+          setIntention(AI_INTENTION_IDLE);
+      
+      if(getIntention() == AI_INTENTION_IDLE)
+        return;
+
         // Check if the actor can't use skills and if a thinking action isn't already in progress
-        if (thinking || _actor.isAllSkillsDisabled())
-            return;
-        
+      
         // Start thinking action
         thinking = true;
         
@@ -599,6 +609,12 @@
      */
     protected void onEvtAttacked(L2Character attacker)
     {
+        if(attacker==null) 
+            {
+              _log.warning("L2SiegeGuardAI.java: onEvtAttacked(L2Character attacker)   ->  attacker=null, RETURNING with setting attacktimeout");
+              _attack_timeout = GameTimeController.getGameTicks();
+              return;
+            }
         // Calculate the attack timeout
         _attack_timeout = MAX_ATTACK_TIMEOUT + GameTimeController.getGameTicks();
         
@@ -655,9 +671,8 @@
                 if (!_actor.isRunning())
                     _actor.setRunning();
 
-                L2SiegeGuardInstance sGuard = (L2SiegeGuardInstance)_actor;
-                double homeX = target.getX() - sGuard.getHomeX();
-                double homeY = target.getY() - sGuard.getHomeY();
+                double homeX = target.getX() - ((L2SiegeGuardInstance)_actor).getHomeX();
+                double homeY = target.getY() - ((L2SiegeGuardInstance)_actor).getHomeY();
                 
                 // Check if the L2SiegeGuardInstance is not too far from its home location
                 if (homeX*homeX+homeY*homeY < 1200*1200)
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/AbstractAI.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/AbstractAI.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ai/AbstractAI.java	(working copy)
@@ -29,6 +29,7 @@
 import net.sf.l2j.gameserver.ClientScheduler;
 import net.sf.l2j.gameserver.GameTimeController;
 import net.sf.l2j.gameserver.model.L2CharPosition;
+import net.sf.l2j.gameserver.model.L2Attackable;
 import net.sf.l2j.gameserver.model.L2Character;
 import net.sf.l2j.gameserver.model.L2Object;
 import net.sf.l2j.gameserver.model.L2PcInstance;
@@ -714,7 +715,7 @@
         
         // Create and Launch an AI Follow Task to execute every 1s
 		_follow_target = target;
-        _follow_task = ClientScheduler.getInstance().scheduleMedAtFixedRate(new FollowTask(), 5, FOLLOW_INTERVAL);
+        _follow_task = ClientScheduler.getInstance().scheduleAiAtFixedRate(new FollowTask(), 5, FOLLOW_INTERVAL);
     }
 
 	/**
@@ -732,7 +733,7 @@
 	    }
 
 	    _follow_target = target;
-	    _follow_task = ClientScheduler.getInstance().scheduleMedAtFixedRate(new FollowTask(range), 5, ATTACK_FOLLOW_INTERVAL);
+	    _follow_task = ClientScheduler.getInstance().scheduleAiAtFixedRate(new FollowTask(range), 5, ATTACK_FOLLOW_INTERVAL);
 	}
 
 	/**
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/RecipeController.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/RecipeController.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/RecipeController.java	(working copy)
@@ -16,8 +16,20 @@
  *
  * http://www.gnu.org/copyleft/gpl.html
  */
+
+
+
+
+
 package net.sf.l2j.gameserver;
-
+/////
+////
+///
+//     This file is now overcomented to explain all the changes
+//     in detail. Feel free to remove them if it makes you happy
+///
+////
+/////
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
@@ -55,524 +67,687 @@
 
 public class RecipeController
 {
-	protected static Logger _log = Logger.getLogger(RecipeController.class.getName());
-	private static RecipeController _instance;
+    protected static Logger _log = Logger.getLogger(RecipeController.class.getName());
+    private static RecipeController _instance;
+    
+    private Map<Integer, L2RecipeList> _lists;
+    
+	protected static Map<L2PcInstance, RecipeItemMaker> activeMakers = Collections.synchronizedMap(new WeakHashMap<L2PcInstance,RecipeItemMaker>());
 	
-	private Map<Integer, L2RecipeList> _lists;
-	
-	protected static Map<L2PcInstance, ReceipeItemMaker> activeMakers = Collections.synchronizedMap(new WeakHashMap<L2PcInstance,ReceipeItemMaker>());
-	
     protected static final Random _rnd = new Random();
-	
-	public static RecipeController getInstance()
-	{
-		if (_instance == null)
-		{
-			_instance = new RecipeController();
-		}
-		return _instance;
-	}
-	
-	public RecipeController()
-	{
-		_lists = new FastMap<Integer, L2RecipeList>();
-		String line = null;
-		LineNumberReader lnr = null;
-		
-		try
-		{
-			File recipesData = new File(Config.DATAPACK_ROOT, "data/recipes.csv");
-			lnr = new LineNumberReader(new BufferedReader( new FileReader(recipesData)));
-			
-			while ((line=lnr.readLine()) != null)
-			{
-				if (line.trim().length() == 0 || line.startsWith("#"))
-				{
-					continue;
-				}
-				
-				parseList(line);
-				
-			}
-			_log.config("RecipeController: Loaded "+_lists.size()+" Recipes.");
-		}
-		catch (Exception e)
-		{
-			if (lnr != null)
-			{
-				_log.log(Level.WARNING, "error while creating recipe controller in linenr: "+lnr.getLineNumber(), e);
-			}
-			else
-			{
-				_log.warning("No recipes were found in data folder");
-			}
-		}
+    
+    public static RecipeController getInstance()
+    {
+        if (_instance == null)
+        {
+            _instance = new RecipeController();
+        }
+        return _instance;
+    }
+    
+    public RecipeController()
+    {
+        _lists = new FastMap<Integer, L2RecipeList>();
+        String line = null;
+        LineNumberReader lnr = null;
+        
+        try
+        {
+            File recipesData = new File(Config.DATAPACK_ROOT, "data/recipes.csv");
+            lnr = new LineNumberReader(new BufferedReader( new FileReader(recipesData)));
+            
+            while ((line=lnr.readLine()) != null)
+            {
+                if (line.trim().length() == 0 || line.startsWith("#"))
+                {
+                    continue;
+                }
+                
+                parseList(line);
+                
+            }
+            _log.config("RecipeController: Loaded "+_lists.size()+" Recipes.");
+        }
+        catch (Exception e)
+        {
+            if (lnr != null)
+            {
+                _log.log(Level.WARNING, "error while creating recipe controller in linenr: "+lnr.getLineNumber(), e);
+            }
+            else
+            {
+                _log.warning("No recipes were found in data folder");
+            }
+        }
         finally
         {
             try { lnr.close(); } catch (Exception e) { }
         }
-	}
-	
-	public int getRecipesCount()
-	{
-		return _lists.size();
-	}
-	
-	public L2RecipeList getRecipeList(int listId)
-	{
-		return _lists.get(listId);
-	}
-	
-	public L2RecipeList getRecipeByItemId(int itemId)
-	{
-		for (int i = 0; i < _lists.size(); i++)
-		{
-			L2RecipeList find = _lists.get(new Integer(i));
-			if (find.getRecipeId() == itemId)
-			{
-				return find;
-			}
-		}
-		return null;
-	}
-	
-	public synchronized void requestBookOpen(L2PcInstance player)
-	{						
-		if (!Config.ALT_GAME_CREATION){
-			RecipeBookItemList response = new RecipeBookItemList();
-			response.addRecipes(player.getRecipeBook());
-			player.sendPacket(response);
-			return;
-		}
-        ReceipeItemMaker maker = activeMakers.get(player);
+    }
+    
+    public int getRecipesCount()
+    {
+        return _lists.size();
+    }
+    public L2RecipeList getRecipeList(int listId)
+    {
+        return _lists.get(listId);
+    }
+    public L2RecipeList getRecipeByItemId(int itemId)
+    {
+        for (int i = 0; i < _lists.size(); i++)
+        {
+            L2RecipeList find = _lists.get(new Integer(i));
+            if (find.getRecipeId() == itemId)
+            {
+                return find;
+            }
+        }
+        return null;
+    }
+    
+    public synchronized void requestBookOpen(L2PcInstance player)
+    {                       
+        RecipeItemMaker maker=null;
+
+        // @@todo: this must be removed, but also made sure it will happen only if realy crafting 
+        if (Config.ALT_GAME_CREATION) 
+        {
+            maker = activeMakers.get(player);
+            if(!player.isInCraftMode() && maker!=null) 
+            {
+                activeMakers.remove(player);
+                if (Config.DEBUG) 
+                    _log.fine("removed "+player.getName()+" from activeMakers by force, trust only isInCraftMode for acurate state");
+            }
+        }
+        
         if (maker == null) {
-        	RecipeBookItemList response = new RecipeBookItemList();
-        	response.addRecipes(player.getRecipeBook());
-        	player.sendPacket(response);
-        	return;
+            RecipeBookItemList response = new RecipeBookItemList();
+            response.addRecipes(player.getRecipeBook());
+            player.sendPacket(response);
+            return;
         }
-        if (maker.timeReady <= GameTimeController.getGameTicks()) {
-        	maker.run();
-        	return;
-        }
+        
+        if (Config.DEBUG) _log.fine("requestBookOpen:  Busy creating");
         SystemMessage sm = new SystemMessage(614); 
         sm.addString("You are busy creating ");
         sm.addItemName(maker.recipeList.getItemId());
         player.sendPacket(sm);
         return;
-	}
-	
-	public synchronized void requestManufactureItem(L2PcInstance manufacturer, int recipeListId, L2PcInstance player)
-	{
-		L2RecipeList recipeList = getRecipeList(recipeListId-1);
-		
-		SystemMessage sm = new SystemMessage(614);
+    }
+    
+    public synchronized void requestManufactureItem(L2PcInstance manufacturer, int recipeListId, L2PcInstance customer)
+    {
+        L2RecipeList recipeList = getRecipeList(recipeListId-1);
+        SystemMessage sm = new SystemMessage(614);
         
-    		 manufacturer.isInCraftMode(true);
-		if ((recipeList == null) || (recipeList.getRecipes().length == 0))
-		{
-			sm = new SystemMessage(614); 
-			sm.addString("No recipe for: " + recipeListId);
-			player.sendPacket(sm);
-        		manufacturer.isInCraftMode(false);
-			return;
-		}
-		if (!Config.ALT_GAME_CREATION) {
-			new ReceipeItemMaker(manufacturer, recipeList, player);
-		} else {
-			ReceipeItemMaker maker = activeMakers.get(manufacturer);
-			if (maker != null)
-			{
-				sm = new SystemMessage(614); 
-				sm.addString("Manufacturer are busy creating.");
-				sm.addItemName(recipeList.getItemId());
-				player.sendPacket(sm);
-            			manufacturer.isInCraftMode(false);
-				return;
-			}
-			maker = new ReceipeItemMaker(manufacturer, recipeList, player);
-			if (maker.isValid)
-				activeMakers.put(manufacturer, maker);
-		}
-	}
-	public synchronized void requestMakeItem(L2PcInstance player, int recipeListId)
-	{
-		L2RecipeList recipeList = getRecipeList(recipeListId-1);
-		
-		SystemMessage sm = new SystemMessage(614);
+        if(manufacturer.isInCraftMode()) 
+            {
+                if(Config.DEBUG) _log.fine("requestManufactureItem called but manufacturer is in craft mode");
+                sm = new SystemMessage(614); 
+                sm.addString("Manufacturer is busy.");
+                sm.addItemName(recipeList.getItemId());
+                customer.sendPacket(sm);
+                return;
+            }
         
-    		player.isInCraftMode(true);
-		if ((recipeList == null) || (recipeList.getRecipes().length == 0))
-		{
-			sm = new SystemMessage(614); 
-			sm.addString("No recipe for: " + recipeListId);
-			player.sendPacket(sm);
-            player.isInCraftMode(false);
-			return;
-		}
-		if (!Config.ALT_GAME_CREATION) {
-			new ReceipeItemMaker(player, recipeList, null);
-		} else {
-			ReceipeItemMaker maker = activeMakers.get(player);
-			if (maker != null)
-			{
-				sm = new SystemMessage(614); 
-				sm.addString("You are busy creating ");
-				sm.addItemName(recipeList.getItemId());
-				player.sendPacket(sm);
-                player.isInCraftMode(false);
-				return;
-			}
-			maker = new ReceipeItemMaker(player, recipeList, null);
-			if (maker.isValid)
-				activeMakers.put(player, maker);
-		}
-	}
-	
-	public synchronized void requestMakeItemAbort(L2PcInstance player)
-	{
-		activeMakers.remove(player);
-	}
-	
-	private void parseList(String line)
-	{
-		StringTokenizer st = new StringTokenizer(line,";");
-		List<L2RecipeInstance> recipePartList = new FastList<L2RecipeInstance>();
-		
-		String recipeName = st.nextToken();
-		int id = Integer.parseInt(st.nextToken());
-		int recipeId = Integer.parseInt(st.nextToken());
-		int level = Integer.parseInt(st.nextToken());
-		
-		//material
-		StringTokenizer st2 = new StringTokenizer(st.nextToken(), "[],");
-		while (st2.hasMoreTokens())
-		{
-			StringTokenizer st3 = new StringTokenizer(st2.nextToken(), "()");
-			int rpItemId = Integer.parseInt(st3.nextToken());
-			int quantity = Integer.parseInt(st3.nextToken());
-			L2RecipeInstance rp = new L2RecipeInstance(rpItemId, quantity);
-			recipePartList.add(rp);
-			//recipe.addRecipe(rp);
-		}
-		
-		int itemId = Integer.parseInt(st.nextToken());
-		int count = Integer.parseInt(st.nextToken());
-		
-		//npc fee
-		/*String notdoneyet = */ st.nextToken();
-		
-		int mpCost = Integer.parseInt(st.nextToken());
-		int successRate = Integer.parseInt(st.nextToken());
-		
-		L2RecipeList recipeList = new L2RecipeList(id,level,recipeId,recipeName,successRate,mpCost,itemId,count);
-		for (L2RecipeInstance recipePart : recipePartList)
-		{
-			recipeList.addRecipe(recipePart);
-		}
-		_lists.put(new Integer(_lists.size()), recipeList);
-	}
-	
-	
-	
-	
-	class ReceipeItemMaker implements Runnable
-	{
-		int   timeReady;
-		final L2PcInstance player;
-		final L2PcInstance target;
-		final L2RecipeList recipeList;
-		final List<L2ItemInstance> items;
-		int   materialsRefPrice;
-		int   totalItems;
-		int   usedItems;
-		int   price;
-		boolean isValid;
-		
-		ReceipeItemMaker(L2PcInstance player, L2RecipeList recipeList, L2PcInstance target )
-		{
-			this.player = player;
-			this.target = target;
-			this.recipeList = recipeList;
-			this.items = new FastList<L2ItemInstance>();
-			
-			int skillLevel = player.getSkillLevel(L2Skill.SKILL_CRAFTING);
-			if (skillLevel <= 0)
-			{
-				player.sendPacket(new ActionFailed());
-                player.isInCraftMode(false);
-				return;
-			}
-			
-			if ((recipeList == null) || (recipeList.getRecipes().length == 0))
-			{
-				SystemMessage sm = new SystemMessage(614); 
-				sm.addString("No such recipe");
-				player.sendPacket(sm);
-                player.isInCraftMode(false);
-				return;
-			}
-			
-			if (target != null)
-			{
-			    for (L2ManufactureItem temp : player.getCreateList().getList())
-			    {
-				if (temp.getRecipeId() == recipeList.getId())
-				{
-				    price = temp.getCost();
-				    if (target.getAdena() < price)
-				    {
-					target.sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
-					player.isInCraftMode(false);
-					return;
-				    }
-				    break;
-				}
-			    }
-			}
-			if (recipeList.getLevel()>skillLevel)
-			{
-				SystemMessage sm = new SystemMessage(614); 
-				sm.addString("Need skill level "+recipeList.getLevel());
-				player.sendPacket(sm);
-                player.isInCraftMode(false);
-				return;
-			}
-			/*
-			 if (recipeList.getAdenaCost()>activeChar.getAdena())
-			 {
-			 SystemMessage sm = new SystemMessage(614); 
-			 sm.addString("Need "+recipeList.getAdenaCost()+" Adena");
-			 activeChar.sendPacket(sm);
-			 return;
-			 }*/
-			
-			L2RecipeInstance[] recipes = recipeList.getRecipes();
-			
-			Inventory inv = null;
-			if (target == null)
-			    inv = player.getInventory();
-			else
-			    inv = target.getInventory();
-			
-			for (L2RecipeInstance recipe : recipes)
-			{
-				if (recipe.getQuantity() != 0)
-				{
-					L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
-					if ((invItem == null) || (recipe.getQuantity()>invItem.getCount()))
-					{
-						SystemMessage sm = new SystemMessage(614); 
-						sm.addString("You dont have the right elements for making this item");
-						if (target == null)
-						    player.sendPacket(sm);
-						else
-						    target.sendPacket(sm);
-                        player.isInCraftMode(false);
-						return;
-					}
-				}
-			}
-			
-			if (!Config.ALT_GAME_CREATION)
-			{
-				if (player.getCurrentMp() < recipeList.getMpCost())
-				{
-					if (Config.DEBUG) _log.fine("not enough mana");
-					SystemMessage sm = new SystemMessage(SystemMessage.NOT_ENOUGH_MP); 
-					if (target == null)
-					    player.sendPacket(sm);
-					else
-					    target.sendPacket(sm);
-					timeReady = GameTimeController.getGameTicks();
-                    player.isInCraftMode(false);
-					return;
-				}
-			}
-			
-			for (L2RecipeInstance recipe : recipes)
-			{
-				if (recipe.getQuantity() != 0)
-				{
-					L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
-					invItem = inv.dropItem(invItem, recipe.getQuantity());
-					items.add(invItem);
-					materialsRefPrice += invItem.getReferencePrice()*invItem.getCount();
-					totalItems += invItem.getCount();
-				}
-			}
-			
-			isValid = true; 
-			
-			timeReady = GameTimeController.TICKS_PER_SECOND + GameTimeController.getGameTicks();
-			ClientScheduler.getInstance().scheduleLow(this, 1100);
-		}
-		
-		public void run()
-		{
-            player.isInCraftMode(true);
+        if ((recipeList == null) || (recipeList.getRecipes().length == 0))
+        {
+            _log.warning("I bet this can never happen normally, "+
+                         "cause customer can order only listed recipes, which are 100% in manufacturer's recipe book");
             
-			if ( Config.IS_CRAFTING_ENABLED ) {
-				double currentPlayerMp = player.getCurrentMp(); 
-				if (currentPlayerMp < recipeList.getMpCost()) {
-					if (Config.DEBUG) _log.fine("not enough mana");
-					SystemMessage sm = new SystemMessage(SystemMessage.NOT_ENOUGH_MP); 
-					if (target == null)
-					    player.sendPacket(sm);
-					else
-					    target.sendPacket(sm);
-					timeReady = GameTimeController.getGameTicks();
-                    player.isInCraftMode(false);
-					return;
-				}
-				
-				int gameTicks = GameTimeController.getGameTicks();	
-				if (timeReady > gameTicks)
+            sm = new SystemMessage(614); 
+            sm.addString("No recipe for: " + recipeListId);
+            customer.sendPacket(sm);
+            manufacturer.isInCraftMode(false);
+            return;
+        }
+
+        if (Config.ALT_GAME_CREATION) 
+        {
+            RecipeItemMaker maker = activeMakers.get(manufacturer);
+            if (maker != null)
+            {
+                if(!manufacturer.isInCraftMode())
                 {
-                    player.isInCraftMode(false);
-					return;
+                    if(Config.DEBUG) 
+                    {
+                        _log.fine(maker.manufacturer.getName() + " is in activeMakers but not IsInCraftmode");
+                        _log.fine("decision: isincraftmode() is right, activeMakers wrong, removing from activeMakers");
+                    }
+                    activeMakers.remove(manufacturer);
+                } else
+                {
+                    sm = new SystemMessage(614); 
+                    sm.addString("Manufacturer is busy.");
+                    sm.addItemName(recipeList.getItemId());
+                    customer.sendPacket(sm);
+                    manufacturer.isInCraftMode(false);
+                    return;
                 }
-				
-				timeReady = gameTicks + (int)(15 * player.getMReuseRate(player.getKnownSkill(172)) * GameTimeController.TICKS_PER_SECOND);			
-				
-				if (!Config.ALT_GAME_CREATION || items.isEmpty()) {
-					player.reduceCurrentMp(recipeList.getMpCost());
-					
-					StatusUpdate su = new StatusUpdate(player.getObjectId());
-					
-					L2ItemInstance createdItem = ItemTable.getInstance().createItem(recipeList.getItemId());
-					createdItem.setCount(recipeList.getCount());
-					
-					int randCheck = _rnd.nextInt(100);
-					if(recipeList.getSuccessRate() <= randCheck ) {
-						SystemMessage sm = new SystemMessage(614);
-						sm.addString("Item(s) failed to create");
-						player.sendPacket(sm);
-                        player.isInCraftMode(false);
-					}
-					else {		
-						int createdItemCount = createdItem.getCount();
-						SystemMessage sm = new SystemMessage(SystemMessage.EARNED_ITEM);
-						sm.addItemName(createdItem.getItemId());
-						sm.addNumber(createdItemCount);
-						//sm.addString("Item(s) created");
-						if (target == null)
-						{
-						    player.getInventory().addItem(createdItem);
-						    player.sendPacket(sm);
-						    su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad());
-						} else 
-						{
-						    if (price > 0) {
-							target.reduceAdena(price);
-							player.addAdena(price);
-							L2ItemInstance adenaupdate = player.getInventory().findItemByItemId(57);
-							InventoryUpdate iu = new InventoryUpdate();
-							iu.addModifiedItem(adenaupdate);
-							player.sendPacket(iu);
-							SystemMessage sm2 = new SystemMessage(SystemMessage.DISSAPEARED_ADENA);
-							sm2.addNumber(price);
-							target.sendPacket(sm2);
-							sm2 = new SystemMessage(SystemMessage.EARNED_ADENA);
-							sm2.addNumber(price);
-							player.sendPacket(sm2);
-						    }
-						    target.getInventory().addItem(createdItem);
-						    target.sendPacket(sm);
-						    StatusUpdate su2 = new StatusUpdate(target.getObjectId());
-						    su2.addAttribute(StatusUpdate.CUR_LOAD, target.getCurrentLoad());
-						    target.sendPacket(su2);
-						}
-						
-						
-						if (Config.ALT_GAME_CREATION) {
-							int skillLevel = player.getSkillLevel(L2Skill.SKILL_CRAFTING);
-							int receipeLevel = recipeList.getLevel();
-							int exp = createdItem.getReferencePrice()*createdItemCount;
-							// one variation
-							exp -= materialsRefPrice;
-							if (exp < 0) exp = 0;
-							// another variation
-							// exp /= receipeLevel
-							for (int i=skillLevel; i > receipeLevel; i--)
-								exp /= 4;
-							int sp = exp / 10;
-                            player.addExpAndSp((int)player.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_XP, null, null), 
-                                               (int)player.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_SP, null, null));
-						}
-					}				
-					activeMakers.remove(player);
-                    player.isInCraftMode(false);
-					
-					su.addAttribute(StatusUpdate.CUR_MP, (int) player.getCurrentMp());
-					player.sendPacket(su);
-					if (target == null){
-					    player.sendPacket(new ItemList(player, false));
-					    player.sendPacket(new RecipeItemMakeInfo(recipeList.getId(),player));
-					} else
-					{
-					    target.sendPacket(new ItemList(target, false));
-					    target.sendPacket(new RecipeShopItemInfo(player.getObjectId(),recipeList.getId()));
-					}
-				} 
-				else {
-					double currentMp = player.getCurrentMp(); 
-					if (currentMp < recipeList.getMpCost()) {
-						if (Config.DEBUG) _log.fine("not enough mana");
-						SystemMessage sm = new SystemMessage(SystemMessage.NOT_ENOUGH_MP); 
-						if (target == null)
-						    player.sendPacket(sm);
-						else
-						    target.sendPacket(sm);
-						timeReady = GameTimeController.getGameTicks();
-                        player.isInCraftMode(false);
-						return;
-					}
-					player.setCurrentMp(currentMp - recipeList.getMpCost());
-					
-					int numItems = player.getSkillLevel(172);
-					while (numItems > 0 && !items.isEmpty()) {
-						L2ItemInstance item = items.get(0);
-						
-						int count = item.getCount();
-						if (count >= numItems) count = numItems;
-						
-						item.setCount(item.getCount() - count);
-						if (item.getCount() <= 0) items.remove(0);
-						
-						numItems -= count;
-						usedItems += count;
-						
-						SystemMessage sm = new SystemMessage(368);
-						sm.addNumber(count);
-						sm.addItemName(item.getItemId());
-						if (target == null)
-						    player.sendPacket(sm);
-						else
-						    target.sendPacket(sm);
-						
-                        player.isInCraftMode(false);
-					}
-					
-					int delay = (timeReady-gameTicks) * GameTimeController.MILLIS_IN_TICK;
-					MagicSkillUser msk = new MagicSkillUser(player, 1050, 1, delay, 0);
-					player.broadcastPacket(msk);
-					SetupGauge sg = new SetupGauge(0, delay);
-					player.sendPacket(sg);				
-					
-					ClientScheduler.getInstance().scheduleLow(this, 100+delay);
-				}
-			}
-			else {
-				// crafting is disabled...
-				SystemMessage sm = new SystemMessage(614);
-				sm.addString("Crafting is currently disabled.");
-				if (target == null)
-				    player.sendPacket(sm);
-				else
-				    target.sendPacket(sm);
-                player.isInCraftMode(false);
-			}
-		}
-	}
+            }
+            
+            maker = new RecipeItemMaker(manufacturer, recipeList, customer);
+            
+            if (maker!=null && manufacturer!=null && maker.isValid)
+                activeMakers.put(manufacturer, maker);
+        } else // for regular crafting we don't use activeMakers
+            new RecipeItemMaker(manufacturer, recipeList, customer);
+    }
+    public synchronized void requestMakeItem(L2PcInstance manufacturer, int recipeListId)
+    {
+        L2RecipeList recipeList = getRecipeList(recipeListId-1);
+        
+        SystemMessage sm = new SystemMessage(614);
+        
+        if ((recipeList == null) || (recipeList.getRecipes().length == 0))
+        {
+            sm = new SystemMessage(614); 
+            sm.addString("No recipe for: " + recipeListId);
+            manufacturer.sendPacket(sm);
+            return;
+        }
+
+        if(manufacturer.isInCraftMode()) 
+        {
+            sm = new SystemMessage(614); 
+            sm.addString("You are busy creating ");
+            sm.addItemName(recipeList.getItemId());
+            manufacturer.sendPacket(sm);
+            return;
+        } 
+        
+        if (Config.ALT_GAME_CREATION) 
+        {
+            RecipeItemMaker maker = activeMakers.get(manufacturer);
+            if (maker != null)
+                activeMakers.remove(manufacturer);
+            
+            maker = new RecipeItemMaker(manufacturer, recipeList, null);
+            
+            if (manufacturer!=null && maker!=null && maker.isValid)
+                activeMakers.put(manufacturer, maker);
+        } else
+        {
+            new RecipeItemMaker(manufacturer, recipeList, null);
+        }
+    }
+    public synchronized void requestMakeItemAbort(L2PcInstance manufacturer)
+    {
+        manufacturer.isInCraftMode(false);
+        if (Config.DEBUG) _log.fine(manufacturer.getName()+" IsInCraftMode(false)");
+
+        if(Config.ALT_GAME_CREATION && activeMakers!=null) 
+        {
+            if(activeMakers.get(manufacturer)!=null) activeMakers.remove(manufacturer);
+            if (Config.DEBUG) 
+                _log.fine("requestMakeItemAbort called - removing " +manufacturer.getName() +" from activeMakers ");
+        }
+    }
+    
+    private void parseList(String line)
+    {
+        StringTokenizer st = new StringTokenizer(line,";");
+        List<L2RecipeInstance> recipePartList = new FastList<L2RecipeInstance>();
+        
+        String recipeName = st.nextToken();
+        int id = Integer.parseInt(st.nextToken());
+        int recipeId = Integer.parseInt(st.nextToken());
+        int level = Integer.parseInt(st.nextToken());
+        
+        //material
+        StringTokenizer st2 = new StringTokenizer(st.nextToken(), "[],");
+        while (st2.hasMoreTokens())
+        {
+            StringTokenizer st3 = new StringTokenizer(st2.nextToken(), "()");
+            int rpItemId = Integer.parseInt(st3.nextToken());
+            int quantity = Integer.parseInt(st3.nextToken());
+            L2RecipeInstance rp = new L2RecipeInstance(rpItemId, quantity);
+            recipePartList.add(rp);
+            //recipe.addRecipe(rp);
+        }
+        
+        int itemId = Integer.parseInt(st.nextToken());
+        int count = Integer.parseInt(st.nextToken());
+        
+        //npc fee
+        /*String notdoneyet = */ st.nextToken();
+        
+        int mpCost = Integer.parseInt(st.nextToken());
+        int successRate = Integer.parseInt(st.nextToken());
+        
+        L2RecipeList recipeList = new L2RecipeList(id,level,recipeId,recipeName,successRate,mpCost,itemId,count);
+        for (L2RecipeInstance recipePart : recipePartList)
+        {
+            recipeList.addRecipe(recipePart);
+        }
+        _lists.put(new Integer(_lists.size()), recipeList);
+    }
+    
+    class RecipeItemMaker implements Runnable
+    {
+        int   timeReady;
+        final L2PcInstance manufacturer;
+        final L2PcInstance customer;
+        final L2RecipeList recipeList;
+        final List<L2ItemInstance> items;
+        final int skillLevel;
+        int   creationPasses;
+        int   materialsRefPrice;
+        int   totalItems;
+        int   usedItems;
+        int   price;
+        boolean isValid;
+        
+        
+        RecipeItemMaker(L2PcInstance manufacturer, L2RecipeList recipeList, L2PcInstance customer )
+        {
+            this.manufacturer = manufacturer;
+            this.customer = customer;
+            this.recipeList = recipeList;
+            this.items = new FastList<L2ItemInstance>();
+            this.skillLevel = manufacturer.getSkillLevel(L2Skill.SKILL_CRAFTING);
+            
+            // crafting is disabled...
+            if (!Config.IS_CRAFTING_ENABLED)
+            {
+                SystemMessage sm = new SystemMessage(614);
+                sm.addString("Crafting is currently disabled.");
+                if (customer == null)
+                    manufacturer.sendPacket(sm);
+                else
+                    customer.sendPacket(sm);
+                manufacturer.isInCraftMode(false);
+                return;
+            }
+            
+            if (manufacturer.isInCraftMode())
+            {
+                if(Config.DEBUG) _log.fine("manufacturer.isInCraftMode()==true, in RecipeItemMaker constructor");
+                SystemMessage sm = new SystemMessage(614);
+                
+                if (customer == null)
+                {
+                    sm.addString("You are busy crafting");
+                    manufacturer.sendPacket(sm);
+                }
+                else
+                {
+                    sm.addString("Manufacturer is busy crafting");
+                    customer.sendPacket(sm);
+                };
+                return;
+            }
+            
+            if (skillLevel <= 0)
+            {
+                manufacturer.sendPacket(new ActionFailed());
+                manufacturer.isInCraftMode(false);
+                
+                if(customer!=null) 
+                {
+                    customer.sendPacket(new ActionFailed());
+                    if(Config.DEBUG) 
+                        _log.warning("skillLevel <= 0 and customer!=null, so why can manufacturer open manufacture shop if he has no skill?");
+                }
+                return;
+            }
+            
+            if ((recipeList == null) || (recipeList.getRecipes().length == 0))
+            {
+                SystemMessage sm = new SystemMessage(614); 
+                sm.addString("No such recipe");
+                manufacturer.sendPacket(sm);
+
+                if(customer!=null) 
+                {
+                    customer.sendPacket(sm);
+                    if(Config.DEBUG) 
+                        _log.warning("customer!=null, so why can manufacturer offer manufacture for item if he has no recipe ?");
+                }
+
+                return;
+            }
+            
+            if (customer != null)
+            {
+                for (L2ManufactureItem temp : manufacturer.getCreateList().getList())
+                    if (temp.getRecipeId() == recipeList.getId())
+                    {
+                        price = temp.getCost();
+                        if (customer.getAdena() < price)
+                            {
+                                customer.sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
+                                return;
+                            }
+                        break;
+                }
+            }
+            
+            if (recipeList.getLevel()>skillLevel)
+            {
+                SystemMessage sm = new SystemMessage(614); 
+                sm.addString("Need skill level "+recipeList.getLevel());
+                manufacturer.sendPacket(sm);
+                return;
+            }
+            
+            L2RecipeInstance[] recipes = recipeList.getRecipes();
+            
+            Inventory inv = null;
+            
+            if (customer == null)
+                inv = manufacturer.getInventory();
+            else
+                inv = customer.getInventory();
+            
+            for (L2RecipeInstance recipe : recipes)
+            {
+                if (recipe.getQuantity() != 0)
+                {
+                    L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
+                    if ((invItem == null) || (recipe.getQuantity()>invItem.getCount()))
+                    {
+                        SystemMessage sm = new SystemMessage(614); 
+                        sm.addString("You dont have the right elements for making this item");
+                        
+                        if (customer == null) manufacturer.sendPacket(sm);
+                            else customer.sendPacket(sm);
+                        
+                        return;
+                    }
+                }
+            }
+            
+            if (manufacturer.getCurrentMp() < recipeList.getMpCost())
+            {
+                if (Config.DEBUG) _log.fine("not enough mana in RecipeItemMaker constructor");
+                SystemMessage sm = new SystemMessage(SystemMessage.NOT_ENOUGH_MP); 
+                if (customer == null)
+                    manufacturer.sendPacket(sm);
+                else
+                    customer.sendPacket(sm);
+
+                return;
+            }
+            
+            creationPasses=0;
+            for (L2RecipeInstance recipe : recipes)
+            {
+                if (recipe.getQuantity() != 0)
+                {
+                    L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
+                    invItem = inv.dropItem(invItem, recipe.getQuantity());
+                    items.add(invItem);
+                    materialsRefPrice += invItem.getReferencePrice()*invItem.getCount();
+                    totalItems += invItem.getCount();
+                    creationPasses+=invItem.getCount()/skillLevel;
+                    if((invItem.getCount()%skillLevel)>0) creationPasses++;
+                }
+            }
+
+            if(Config.DEBUG)
+            {
+                //_log.warning("calculated creation passes: "+creationPasses);
+            
+                if(creationPasses==0) 
+                {
+                    creationPasses++;
+                    _log.warning("creationPasses was ZERO so creationPasses++  and it is now " + creationPasses);
+                }
+            }
+            isValid = true; 
+            
+            manufacturer.isInCraftMode(true); // here we say craf mode started, no reason to do it sooner, just makes problems
+            
+            //ClientScheduler.scheduleCraftAction(this, 100);
+            run();  // for not-alternative crafting -> no reason why not craft immediately, cause it uses really little cpu
+                    // and will never make lag ... scheduled things tend to make lag, things that are immediately done don't if you 
+                    // have sufficient cpu anyway ...  how long can craft take ? few nanoseconds ?
+                    // and for ALT_CRAFTING=true,  first run is innitial, and takes no time also,  and on end, if needed, another run
+                    // is scheduled
+            
+        }
+        public void run()
+        {
+            if (!Config.ALT_GAME_CREATION || items.isEmpty())   // this method does the actual creation of item,
+            {                                                   // it is called immediately for normal crafting,  
+                completeCreation();                             // cause normal crafting does not take time, bug gives no XP/SP
+                manufacturer.isInCraftMode(false);              // for ALT_CRAFTING it is called only when all items are "equiped"
+                                                                // thru multiple scheduled runs using 
+                                                                // ClientScheduler.ScheduleCraftAction()  - separate thread pool
+                                                                // there should be no thread launching at all 
+
+                if(Config.DEBUG) 
+                {
+                    //_log.warning("MP_Cost:  "+recipeList.getMpCost()+" ");
+                    //_log.warning("passes:   "+creationPasses+" ");
+                    //_log.warning("mana/pass:"+recipeList.getMpCost()/creationPasses+" ");
+                    //_log.warning("error:    "+(recipeList.getMpCost()-((recipeList.getMpCost()/creationPasses)*creationPasses)));
+                }
+                
+                return;
+            }
+            
+            
+            // all this code is for ALT_GAME_CREATION only
+            // previous code was very confusing, which led
+            // to "craft lag" due to misunderstanding of 
+            // "crafting" in normal mode.
+            // normal mode takes no time but gives no XP/SP
+            // ALT_MODE takes time but gives XP/SP as reward
+            // ---------------------------------------------
+            // run() is scheduled multiple times, 
+            // (equiping) skillLevel items on every run, until 
+            // all items are "equiped", and then on next run,
+            // completeCreation() will produce the result
+            // and remove equiped  materials from inventory
+            //  
+            // on every run() part of mana is deducted from
+            // manufacturer, amount is calculated as sum of 
+            // all item counts from recipe.
+
+            double currentManufacturerMp = manufacturer.getCurrentMp();          // we need player to have only mana needed 
+            if (currentManufacturerMp < ((double)recipeList.getMpCost()/(double)creationPasses))                                                                     
+            {                                                                     // for this pass, next pass is in 1 second
+                if (Config.DEBUG) _log.warning("not enough mana in run()");      // so we can allow mp regen to help manufacturer
+                SystemMessage sm = new SystemMessage(SystemMessage.NOT_ENOUGH_MP); 
+                if (customer == null)
+                    manufacturer.sendPacket(sm);
+                else
+                    customer.sendPacket(sm);
+                
+                manufacturer.isInCraftMode(false);
+                activeMakers.remove(manufacturer);
+                return;
+            }
+                
+                
+            manufacturer.reduceCurrentMp((double)recipeList.getMpCost()/(double)creationPasses);
+            
+            int numItems = skillLevel;
+            
+            while (numItems > 0 && !items.isEmpty())  // equip # of items we can in one run()  
+            {                                         // if players complain they lose items during craft on server crashes, try
+                L2ItemInstance item = items.get(0);   // not to item.remove(), but instead copy it somehow and return if crafting 
+                int count = item.getCount();          // did not finish for some reason ?? umh don't know how it works really
+                                                      // when is sql db updated ? all the time ? sometimes ?
+                
+                if (count >= numItems) count = numItems; 
+                item.setCount(item.getCount() - count);
+                if (item.getCount() <= 0) items.remove(0);
+                numItems -= count;
+                usedItems += count;
+                        
+                SystemMessage sm = new SystemMessage(368);
+                sm.addNumber(count);
+                sm.addItemName(item.getItemId());
+                
+                if (customer == null) manufacturer.sendPacket(sm);
+                    else customer.sendPacket(sm);
+            }
+                    
+            int delay = ((int)(manufacturer.getMReuseRate(manufacturer.getKnownSkill(L2Skill.SKILL_CRAFTING)) * GameTimeController.TICKS_PER_SECOND)) * GameTimeController.MILLIS_IN_TICK;
+
+            MagicSkillUser msk = new MagicSkillUser(manufacturer, 1050, 1, delay, 0);
+            manufacturer.broadcastPacket(msk);
+
+            SetupGauge sg = new SetupGauge(0, delay);
+            manufacturer.sendPacket(sg);                
+
+            StatusUpdate su = new StatusUpdate(manufacturer.getObjectId());
+            su.addAttribute(StatusUpdate.CUR_MP, (int) manufacturer.getCurrentMp());
+            manufacturer.sendPacket(su);
+//          // this works but it makes craft of level1 items very fast for alt mode ... uhm 
+//          // I'd allow that, cause crafting "braided hemp" is not very fun and you need to do it
+//          // in huge quantities, even if you are high level, so you get no XP/SP
+//          // but it's not my call        
+//            if (items.isEmpty()) 
+//            {
+//                if(Config.DEBUG) _log.fine("saved "+delay+" miliseconds");
+//                completeCreation();
+//                manufacturer.isInCraftMode(false);
+//                activeMakers.remove(manufacturer);                
+//            } else
+            ClientScheduler.scheduleCraftAction(this, 1+delay);  // Craft thread pool has nothing to do with other pools, so
+                                                                 // only way this can make any kind of lag is when CPU usage is 100%
+                                                                 // when nobody is "in craft mode"  scheduled tasks for 
+                                                                 // craft thread pool must be 0 or we have a bug again :/
+        }
+        
+        private void completeCreation()        // this is where real item production is done
+        {  
+            int createdItemCount=0;
+            if(Config.DEBUG) 
+                _log.fine(manufacturer.getName()+" : completeCreation() ");
+            
+            if(!Config.ALT_GAME_CREATION)       // we reduce Mp in run() for ALT_GAME_CREATION 
+                manufacturer.reduceCurrentMp(recipeList.getMpCost());
+            
+            StatusUpdate su = new StatusUpdate(manufacturer.getObjectId());
+            
+            L2ItemInstance createdItem = ItemTable.getInstance().createItem(recipeList.getItemId());
+            createdItem.setCount(recipeList.getCount());
+            
+            int randCheck = _rnd.nextInt(100);
+            
+            if(recipeList.getSuccessRate() <= randCheck ) 
+            {
+                SystemMessage sm = new SystemMessage(614);
+                sm.addString("Item(s) failed to create");
+                manufacturer.sendPacket(sm);
+                manufacturer.isInCraftMode(false);
+                if(Config.ALT_GAME_CREATION && activeMakers.get(manufacturer)!=null) activeMakers.remove(manufacturer);
+            } else 
+            {   // item succesfully created    
+                createdItemCount = createdItem.getCount();
+                SystemMessage sm = new SystemMessage(SystemMessage.EARNED_ITEM);
+                sm.addItemName(createdItem.getItemId());
+                sm.addNumber(createdItemCount);
+                
+                if (customer == null)
+                {
+                    manufacturer.getInventory().addItem(createdItem);
+                    manufacturer.sendPacket(sm);
+                    su.addAttribute(StatusUpdate.CUR_LOAD, manufacturer.getCurrentLoad());
+                } else 
+                {
+                    if (price > 0) 
+                    {
+                        customer.reduceAdena(price);
+                        manufacturer.addAdena(price);
+                        L2ItemInstance adenaupdate = manufacturer.getInventory().findItemByItemId(57);
+                        InventoryUpdate iu = new InventoryUpdate();
+                        iu.addModifiedItem(adenaupdate);
+                        manufacturer.sendPacket(iu);
+                        SystemMessage sm2 = new SystemMessage(SystemMessage.DISSAPEARED_ADENA);
+                        sm2.addNumber(price);
+                        customer.sendPacket(sm2);
+                        sm2 = new SystemMessage(SystemMessage.EARNED_ADENA);
+                        sm2.addNumber(price);
+                        manufacturer.sendPacket(sm2);
+                    }
+                
+                    customer.getInventory().addItem(createdItem);
+                    customer.sendPacket(sm);
+                    StatusUpdate su2 = new StatusUpdate(customer.getObjectId());
+                    su2.addAttribute(StatusUpdate.CUR_LOAD, customer.getCurrentLoad());
+                    customer.sendPacket(su2);
+                }
+            }
+                
+            if (Config.ALT_GAME_CREATION)              
+            {
+                int RecipeLevel = recipeList.getLevel();
+                int exp;
+                int sp;
+                
+                // if sitting, default formula, standing my new formula based on MP used to craft item(s)
+                if(!Config.ALT_GAME_CREATION_BY_MANA)  // standard formula, tried to fix but no luck
+                {
+                    exp = createdItem.getReferencePrice()*createdItemCount;
+                    //   ensure at least some profit
+                    materialsRefPrice=(int)((double)materialsRefPrice*(double)0.95);
+                    
+                    // one variation
+                    if(Config.DEBUG) 
+                    {
+                      _log.fine("BASED ON ITEM PRICE - MATERIALS PRICE");
+                      _log.fine("createdItemCount: "+createdItemCount);
+                      _log.fine("exp:              "+exp);
+                      _log.fine("referent price:   "+createdItem.getReferencePrice());
+                      _log.fine("referent total:   "+createdItem.getReferencePrice()*createdItemCount);
+                      _log.fine("materials price:  "+materialsRefPrice);
+                      _log.fine("exp:              "+(exp-materialsRefPrice));
+                    }
+                
+                    exp -= materialsRefPrice;  
+
+                    if (exp < 0) exp = 0;
+    
+                    exp/=RecipeLevel;
+                    
+                    for (int i=skillLevel; i > RecipeLevel; i--) exp /= 4;
+
+                    sp = exp / 10;
+                    
+                    if(Config.DEBUG) _log.fine("exp with mods:    "+exp);
+                    
+                } else
+                {
+                    exp=2*(recipeList.getLevel() * recipeList.getMpCost())
+                        /skillLevel;
+                    
+                    sp = exp / 10;
+                    
+                    // one variation
+                    if(Config.DEBUG) 
+                    {
+                      _log.fine("NEW METHOD - BASED ON MANA");
+                      _log.fine("createdItemCount: "+createdItemCount);
+                      _log.fine("exp:              "+exp);
+                    }
+                    
+                }
+                manufacturer.addExpAndSp((int)manufacturer.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_XP, null, null), 
+                                  (int)manufacturer.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_SP, null, null));
+            
+                if(activeMakers.get(manufacturer)!=null) activeMakers.remove(manufacturer);
+            }
+            
+            manufacturer.isInCraftMode(false);
+
+            su.addAttribute(StatusUpdate.CUR_MP, (int) manufacturer.getCurrentMp());
+            manufacturer.sendPacket(su);
+            if (customer == null){
+                manufacturer.sendPacket(new ItemList(manufacturer, false));
+                manufacturer.sendPacket(new RecipeItemMakeInfo(recipeList.getId(),manufacturer));
+            } else
+            {
+                customer.sendPacket(new ItemList(customer, false));
+                customer.sendPacket(new RecipeShopItemInfo(manufacturer.getObjectId(),recipeList.getId()));
+            }
+        }  
+    }
 }
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ClientScheduler.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ClientScheduler.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/ClientScheduler.java	(working copy)
@@ -31,16 +31,6 @@
 import net.sf.l2j.Config;
 import net.sf.l2j.gameserver.clientpackets.ClientBasePacket;
 
-/**
- * This class permit to create 3 Threads pools and to add to it tasks to execute in function of their priority (HIGH, MEDIUM,LOW).<BR><BR>
- * 
- * <B><U> Threads pools </U> :</B><BR><BR>
- * <li> A pool containing 4 Hight Threads </li>
- * <li> A pool containing 10 Medium Threads </li>
- * <li> A pool containing 4 Low priority Threads </li><BR><BR>
- * 
- */
-
 public final class ClientScheduler
 {
 	static Logger _log = Logger.getLogger(ClientScheduler.class.getName());
@@ -53,8 +43,11 @@
 	private static final ClientScheduler _instance = new ClientScheduler();
 	
 	private final ScheduledThreadPoolExecutor _executorHighPriority;
+        private final ScheduledThreadPoolExecutor _executorMedHighPriority;
 	private final ScheduledThreadPoolExecutor _executorMedPriority;
 	private final ScheduledThreadPoolExecutor _executorLowPriority;
+        private final ScheduledThreadPoolExecutor _executorAi;
+        private final ScheduledThreadPoolExecutor _executorCraft;
 
 
 	/**
@@ -67,15 +60,18 @@
 	
 	
 	/**
-	 * Create a pool of 4 Hight Threads, a pool of 10 Medium Threads, and a pool of 4 Low priority Threads to execute Task.<BR><BR>
+	 * Create a pool of 4 Hight Threads, a pool of 4 Medium Threads, and a pool of 4 Low priority Threads to execute Task.<BR><BR>
 	 */
 	private ClientScheduler()
 	{
 		if (Config.ASSERT) assert _instance == null;
 		
 		_executorHighPriority = new ScheduledThreadPoolExecutor(Config.THREAD_P_HIGH, new ThrFactory(Config.EXECUTOR_PRI_HIGH, "PoolHIGH"));
-		_executorMedPriority = new ScheduledThreadPoolExecutor(Config.THREAD_P_MED, new ThrFactory(Config.EXECUTOR_PRI_MED, "PoolMED"));
+        _executorMedHighPriority = new ScheduledThreadPoolExecutor(Config.THREAD_P_HIGH, new ThrFactory(Config.EXECUTOR_PRI_HIGH-1, "PoolHIGH"));
+        _executorMedPriority = new ScheduledThreadPoolExecutor(Config.THREAD_P_MED, new ThrFactory(Config.EXECUTOR_PRI_MED, "PoolMED"));
 		_executorLowPriority = new ScheduledThreadPoolExecutor(Config.THREAD_P_LOW, new ThrFactory(Config.EXECUTOR_PRI_LOW, "PoolLOW"));
+        _executorAi = new ScheduledThreadPoolExecutor(Config.THREAD_P_MED, new ThrFactory((Config.EXECUTOR_PRI_HIGH-1), "PoolMED"));
+        _executorCraft = new ScheduledThreadPoolExecutor(Config.THREAD_P_MED, new ThrFactory((Config.EXECUTOR_PRI_MED-1), "PoolLOW"));
 	}
 	
 	/**
@@ -83,17 +79,26 @@
 	 */
 	public void closeAll()
 	{
-		try { _executorHighPriority.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+		try { _executorHighPriority.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+        try { _executorMedHighPriority.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
 		try { _executorMedPriority.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
 		try { _executorLowPriority.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+        try { _executorAi.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+        try { _executorCraft.shutdown(); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
 		
-		try { _executorHighPriority.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+		try { _executorHighPriority.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+        try { _executorMedHighPriority.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
 		try { _executorMedPriority.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
 		try { _executorLowPriority.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+        try { _executorAi.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
+        try { _executorCraft.awaitTermination(1000, TimeUnit.MILLISECONDS); } catch (Throwable t) { _log.log(Level.WARNING, "", t); }
 		
 		_executorHighPriority.shutdownNow();
-		_executorHighPriority.shutdownNow();
-		_executorHighPriority.shutdownNow();
+		_executorMedHighPriority.shutdownNow();
+        _executorMedPriority.shutdownNow();
+		_executorLowPriority.shutdownNow();
+        _executorAi.shutdownNow();
+        _executorCraft.shutdownNow();
 	}
 	
 	
@@ -105,7 +110,10 @@
 		TaskPriority pr = pkt.getPriority();
 		
 		if (pr == null)
-			pr = PR_LOW;
+        {
+            _log.warning("Packet without priority defaulted to PR_LOW: "+pkt.getType());
+            pr = PR_LOW;
+        }
 		
 		// Add a task to one of the pool of thread in function of its priority (HIGH, MEDIUM,LOW)
 		// This has effect equivalent to schedule(command, 0, anyUnit)
@@ -121,9 +129,9 @@
 			_instance._executorMedPriority.execute(pkt);
 			return;
 		case PR_LOW:
-		default:
-			_instance._executorLowPriority.execute(pkt);
-			return;
+        default:
+            _instance._executorLowPriority.execute(pkt);
+            return;
 		}
 	}
 	
@@ -146,8 +154,9 @@
 		{
 		case PR_HIGH:   return scheduleHighAtFixedRate(r, initial, delay);
 		case PR_MEDIUM: return scheduleMedAtFixedRate(r, initial, delay);
-		default:
-		case PR_LOW:    return scheduleLowAtFixedRate(r, initial, delay);
+        case PR_LOW:    return scheduleLowAtFixedRate(r, initial, delay);
+        default:
+          return scheduleLowAtFixedRate(r, initial, delay);
 		}
 	}
 
@@ -169,7 +178,42 @@
 		} catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
 	}
 
-	
+    /**
+     * Create a MedHigh priority task that is executed after an initial time (in ms) and each delay ms.<BR><BR>
+     *   
+     * @param r The task to launch
+     * @param initial The initial delay (in ms) after what the task is executed for the first time
+     * @param delay The delay (in ms) between 2 consecutive executions of the task
+     * 
+     */
+    public ScheduledFuture scheduleMedHighAtFixedRate(Runnable r, long initial, long delay)
+    {
+        try
+        {
+        if (delay < 0) delay = 0;
+        return _executorMedHighPriority.scheduleAtFixedRate(r, initial, delay, TimeUnit.MILLISECONDS);
+        } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+    }
+
+    public ScheduledFuture scheduleAiAtFixedRate(Runnable r, long initial, long delay)
+    {
+        try
+        {
+        if (delay < 0) delay = 0;
+        return _executorAi.scheduleAtFixedRate(r, initial, delay, TimeUnit.MILLISECONDS);
+        } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+    }
+
+    public ScheduledFuture scheduleCraftAtFixedRate(Runnable r, long initial, long delay)
+    {
+        try
+        {
+        if (delay < 0) delay = 0;
+        return _executorCraft.scheduleAtFixedRate(r, initial, delay, TimeUnit.MILLISECONDS);
+        } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+    }
+
+    
 	/**
 	 * Create a Medium priority task that is executed after an initial time (in ms) and each delay ms.<BR><BR>
 	 *    
@@ -231,8 +275,9 @@
 		{
 		case PR_HIGH:   return scheduleHigh(r, delay);
 		case PR_MEDIUM: return scheduleMed(r, delay);
+        case PR_LOW:    return scheduleLow(r, delay);
 		default:
-		case PR_LOW:    return scheduleLow(r, delay);
+            return scheduleLow(r,delay);
 		}
 	}
 
@@ -254,7 +299,22 @@
 		} catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
 	}
 
-	
+    /**
+     * Create a Medium priority task that is executed after an initial time (in ms).<BR><BR>
+     *   
+     * @param r The task to launch
+     * @param initial The initial delay (in ms) after what the task is executed for the first time
+     * @param delay The delay (in ms) between 2 consecutive executions of the task
+     * 
+     */
+    public ScheduledFuture scheduleMedHigh(Runnable r, long delay)
+    {
+        try
+        {
+        if (delay < 0) delay = 0;
+        return _executorMedHighPriority.schedule(r, delay, TimeUnit.MILLISECONDS);
+        } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+    }	
 	/**
 	 * Create a Medium priority task that is executed after an initial time (in ms).<BR><BR>
 	 *   
@@ -263,6 +323,7 @@
 	 * @param delay The delay (in ms) between 2 consecutive executions of the task
 	 * 
 	 */
+    
 	public ScheduledFuture scheduleMed(Runnable r, long delay)
 	{
 		try
@@ -289,7 +350,24 @@
 		} catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
 	}
 
-	
+    public ScheduledFuture scheduleAi(Runnable r, long delay)
+    {
+        try
+        {
+        if (delay < 0) delay = 0;
+        return _executorAi.schedule(r, delay, TimeUnit.MILLISECONDS);
+        } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+    }
+    
+    public ScheduledFuture scheduleCraft(Runnable r, long delay)
+    {
+        try
+        {
+        if (delay < 0) delay = 0;
+        return _executorCraft.schedule(r, delay, TimeUnit.MILLISECONDS);
+        } catch (RejectedExecutionException e) { return null; /* shutdown, ignore */ }
+    }
+    
 	class ThrFactory implements ThreadFactory 
 	{
 		private final String _prefix;
@@ -316,30 +394,49 @@
     {
         return new String[] {
             "HIGH ("+Config.EXECUTOR_PRI_HIGH+")",
-            "ActiveThreads:   "+_executorHighPriority.getActiveCount(),
-            "CompletedTasks:  "+_executorHighPriority.getCompletedTaskCount(),
-            "getCorePoolSize: "+_executorHighPriority.getCorePoolSize(),
-            "MaximumPoolSize: "+_executorHighPriority.getMaximumPoolSize(),
-            "LargestPoolSize: "+_executorHighPriority.getLargestPoolSize(),
-            "PoolSize:        "+_executorHighPriority.getPoolSize(),
-            "ScheduledTasks:  "+(_executorHighPriority.getTaskCount() - _executorHighPriority.getCompletedTaskCount()),
-            "MEDIUM ("+Config.EXECUTOR_PRI_MED+")",
-            "ActiveThreads:   "+_executorMedPriority.getActiveCount(),
-            "CompletedTasks:  "+_executorMedPriority.getCompletedTaskCount(),
-            "getCorePoolSize: "+_executorMedPriority.getCorePoolSize(),
-            "MaximumPoolSize: "+_executorMedPriority.getMaximumPoolSize(),
-            "LargestPoolSize: "+_executorMedPriority.getLargestPoolSize(),
-            "PoolSize:        "+_executorMedPriority.getPoolSize(),
-            "ScheduledTasks:  "+(_executorMedPriority.getTaskCount() - _executorMedPriority.getCompletedTaskCount()),
+            "ActiveThreads:    "+_executorHighPriority.getActiveCount(),
+            "CompletedTasks:   "+_executorHighPriority.getCompletedTaskCount(),
+            "ScheduledTasks:   "+(_executorHighPriority.getTaskCount() - _executorHighPriority.getCompletedTaskCount()),
+            "TaskCount(total): "+_executorHighPriority.getTaskCount(),
+            "PoolSize:         "+_executorHighPriority.getPoolSize(),
+            "",
+            "MedHigh ("+Config.EXECUTOR_PRI_MEDHIGH+")",
+            "ActiveThreads:    "+_executorMedHighPriority.getActiveCount(),
+            "CompletedTasks:   "+_executorMedHighPriority.getCompletedTaskCount(),
+            "ScheduledTasks:   "+(_executorMedHighPriority.getTaskCount() - _executorMedHighPriority.getCompletedTaskCount()),
+            "TaskCount(total): "+_executorMedHighPriority.getTaskCount(),
+            "PoolSize:         "+_executorMedHighPriority.getPoolSize(),
+            "",
+            "MEDIUM ("+(Config.EXECUTOR_PRI_MED)+")",
+            "ActiveThreads:    "+_executorMedPriority.getActiveCount(),
+            "CompletedTasks:   "+_executorMedPriority.getCompletedTaskCount(),
+            "ScheduledTasks:   "+(_executorMedPriority.getTaskCount() - _executorMedPriority.getCompletedTaskCount()),
+            "TaskCount(total): "+_executorMedPriority.getTaskCount(),
+            "PoolSize:         "+_executorMedPriority.getPoolSize(),
+            "",
             "LOW ("+Config.EXECUTOR_PRI_LOW+")",
-            "ActiveThreads:   "+_executorLowPriority.getActiveCount(),
-            "CompletedTasks:  "+_executorLowPriority.getCompletedTaskCount(),
-            "getCorePoolSize: "+_executorLowPriority.getCorePoolSize(),
-            "MaximumPoolSize: "+_executorLowPriority.getMaximumPoolSize(),
-            "LargestPoolSize: "+_executorLowPriority.getLargestPoolSize(),
-            "PoolSize:        "+_executorLowPriority.getPoolSize(),
-            "ScheduledTasks:  "+(_executorLowPriority.getTaskCount() - _executorLowPriority.getCompletedTaskCount())
+            "ActiveThreads:    "+_executorLowPriority.getActiveCount(),
+            "CompletedTasks:   "+_executorLowPriority.getCompletedTaskCount(),
+            "ScheduledTasks:   "+(_executorLowPriority.getTaskCount() - _executorLowPriority.getCompletedTaskCount()),
+            "TaskCount(total): "+_executorLowPriority.getTaskCount(),
+            "PoolSize:         "+_executorLowPriority.getPoolSize(),
+            "",
+            "AI ("+Config.EXECUTOR_PRI_AI+")",
+            "ActiveThreads:    "+_executorAi.getActiveCount(),
+            "CompletedTasks:   "+_executorAi.getCompletedTaskCount(),
+            "ScheduledTasks:   "+(_executorAi.getTaskCount() - _executorAi.getCompletedTaskCount()),       
+            "TaskCount(total): "+_executorAi.getTaskCount(),
+            "PoolSize:         "+_executorAi.getPoolSize(),
+            "",
+            "CRAFT ("+Config.EXECUTOR_PRI_CRAFT+")",
+            "ActiveThreads:    "+_executorCraft.getActiveCount(),
+            "CompletedTasks:   "+_executorCraft.getCompletedTaskCount(),
+            "ScheduledTasks:   "+(_executorCraft.getTaskCount() - _executorCraft.getCompletedTaskCount()),       
+            "TaskCount(total): "+_executorCraft.getTaskCount(),
+            "PoolSize:         "+_executorCraft.getPoolSize(),
+            ""
         };
+        
     }
 
 
@@ -348,4 +445,14 @@
         return getInstance().scheduleLow(event, delay);
     }
     
+    public static ScheduledFuture scheduleAiAction(Runnable event, long delay)
+    {
+        return getInstance().scheduleAi(event, delay);
+    }
+
+    public static ScheduledFuture scheduleCraftAction(Runnable event, long delay)
+    {
+        return getInstance().scheduleCraft(event, delay);
+    }
+    
 }
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/tasks/TaskCleanUp.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/tasks/TaskCleanUp.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/tasks/TaskCleanUp.java	(working copy)
@@ -1,35 +0,0 @@
-/**
- * 
- */
-package net.sf.l2j.gameserver.taskmanager.tasks;
-
-import net.sf.l2j.gameserver.taskmanager.Task;
-import net.sf.l2j.gameserver.taskmanager.TaskManager;
-import net.sf.l2j.gameserver.taskmanager.TaskTypes;
-import net.sf.l2j.gameserver.taskmanager.TaskManager.ExecutedTask;
-
-/**
- * @author Tempy
- *
- */
-public final class TaskCleanUp extends Task
-{
-    public static String NAME = "CleanUp";
-    
-    public String getName()
-    {
-        return NAME;
-    }
-
-    public void onTimeElapsed(ExecutedTask task)
-    {
-        System.runFinalization();
-        System.gc();
-    }
-    
-    public void initializate()
-    {
-        super.initializate();
-        TaskManager.addUniqueTask(NAME, TaskTypes.TYPE_FIXED_SHEDULED, "0", "1800000", "");
-    }
-}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/TaskManager.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/TaskManager.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/taskmanager/TaskManager.java	(working copy)
@@ -24,12 +24,12 @@
 import javolution.util.FastMap;
 import net.sf.l2j.L2DatabaseFactory;
 import net.sf.l2j.gameserver.ClientScheduler;
-import net.sf.l2j.gameserver.taskmanager.tasks.TaskCleanUp;
 import net.sf.l2j.gameserver.taskmanager.tasks.TaskJython;
 import net.sf.l2j.gameserver.taskmanager.tasks.TaskRecom;
 import net.sf.l2j.gameserver.taskmanager.tasks.TaskRestart;
 import net.sf.l2j.gameserver.taskmanager.tasks.TaskSevenSignsUpdate;
 import net.sf.l2j.gameserver.taskmanager.tasks.TaskShutdown;
+import net.sf.l2j.gameserver.taskmanager.tasks.TaskSevenSignsStatus;
 
 /**
  * @author Layane
@@ -163,12 +163,12 @@
     
     private void initializate()
     {
-        registerTask(new TaskCleanUp());
         registerTask(new TaskJython());
         registerTask(new TaskRecom());
         registerTask(new TaskRestart());
         registerTask(new TaskSevenSignsUpdate());
         registerTask(new TaskShutdown());
+        registerTask(new TaskSevenSignsStatus());
     }
     
     public void registerTask(Task task)
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/script/faenor/FaenorInterface.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/script/faenor/FaenorInterface.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/script/faenor/FaenorInterface.java	(working copy)
@@ -33,6 +33,7 @@
 import net.sf.l2j.gameserver.script.EngineInterface;
 import net.sf.l2j.gameserver.script.Expression;
 import net.sf.l2j.gameserver.templates.L2NpcTemplate;
+import net.sf.l2j.gameserver.NpcTable;
 
 import org.apache.bsf.BSFException;
 import org.apache.bsf.BSFManager;
@@ -77,7 +78,7 @@
      */
     public void addQuestDrop(int npcID, int itemID, int min, int max, int chance, String questID, String[] states)
     {
-        L2NpcTemplate npc = _npcTable.getTemplate(npcID);
+        L2NpcTemplate npc = NpcTable.getInstance().getTemplate(npcID);
         if (npc == null)
         {
             throw new NullPointerException();
@@ -100,7 +101,7 @@
      */
     public void addDrop(int npcID, int itemID, int min, int max, boolean sweep, int chance) throws NullPointerException
     {
-        L2NpcTemplate npc = _npcTable.getTemplate(npcID);
+        L2NpcTemplate npc = NpcTable.getInstance().getTemplate(npcID);
         if (npc == null)
         {
             if (Config.DEBUG) System.out.print("Npc doesnt Exist");
@@ -120,7 +121,7 @@
      */
     public List getQuestDrops(int npcID)
     {
-        L2NpcTemplate npc = _npcTable.getTemplate(npcID);
+        L2NpcTemplate npc = NpcTable.getInstance().getTemplate(npcID);
         if (npc == null)
         {
             return null;
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameTimeController.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameTimeController.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/gameserver/GameTimeController.java	(working copy)
@@ -72,7 +72,7 @@
 		_timer = new TimerThread();
 		_timer.start();
 
-		ClientScheduler.getInstance().scheduleLowAtFixedRate(
+		ClientScheduler.getInstance().scheduleMedHighAtFixedRate(
 				new TimerWatcher(), 0, 1000);
 		ClientScheduler.getInstance().scheduleLowAtFixedRate(
 				new BroadcastSunState(), 0, 60*60*1000
@@ -151,7 +151,7 @@
 		// Create a task to update the _knownObject and _knowPlayers of each L2Character that finished its movement and of their already known L2Object 
 		// then notify AI with EVT_ARRIVED
 		if (ended != null)
-			ClientScheduler.getInstance().scheduleLow(new MovingObjectArrived(ended), 10);
+			ClientScheduler.getInstance().scheduleMed(new MovingObjectArrived(ended), 10);
 		
 	}
 	
@@ -169,7 +169,7 @@
 		{
 			super("TimerThread");
 			setDaemon(true);
-			setPriority(MAX_PRIORITY);
+			setPriority(MAX_PRIORITY-1);
 			_stop = false;
 			_error = null;
 		}
Index: C:/workspace/L2_GameServer/java/net/sf/l2j/L2DatabaseFactory.java
===================================================================
--- C:/workspace/L2_GameServer/java/net/sf/l2j/L2DatabaseFactory.java	(revision 2218)
+++ C:/workspace/L2_GameServer/java/net/sf/l2j/L2DatabaseFactory.java	(working copy)
@@ -63,9 +63,9 @@
 			config.setMinPoolSize(1);
 			config.setMaxPoolSize(Config.DATABASE_MAX_CONNECTIONS);
 			config.setMaxStatements(100);
-			config.setIdleConnectionTestPeriod(0); // test idle connection every 1 minute
-			config.setMaxIdleTime(0); // remove unused connection after 10 minutes
-
+			config.setIdleConnectionTestPeriod(60); // test idle connection every 1 minute
+			config.setMaxIdleTime(600); // remove unused connection after 10 minutes
+			config.setNumHelperThreads(5);
 			Class.forName(Config.DATABASE_DRIVER).newInstance();
 
 			if (Config.DEBUG) _log.fine("Database Connection Working");
Index: C:/workspace/L2_GameServer/dist/LoginServer_loop.sh
===================================================================
--- C:/workspace/L2_GameServer/dist/LoginServer_loop.sh	(revision 2218)
+++ C:/workspace/L2_GameServer/dist/LoginServer_loop.sh	(working copy)
@@ -5,7 +5,7 @@
 do
 	mv log/java0.log.0 "log/`date +%Y-%m-%d_%H-%M-%S`_java.log"
 	mv log/stdout.log "log/`date +%Y-%m-%d_%H-%M-%S`_stdout.log"
-	nice -n -2 java -Xms512m -Xmx512m -cp javolution.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.loginserver.LoginServer > log/stdout.log 2>&1
+	nice -n -2 java -Xss96k -Xincgc -Xms64m -Xmx128m -cp javolution.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.loginserver.LoginServer > log/stdout.log 2>&1
 	err=$?
 #	/etc/init.d/mysql restart
 	sleep 10;
Index: C:/workspace/L2_GameServer/dist/GameServer_loop.sh
===================================================================
--- C:/workspace/L2_GameServer/dist/GameServer_loop.sh	(revision 2218)
+++ C:/workspace/L2_GameServer/dist/GameServer_loop.sh	(working copy)
@@ -5,7 +5,7 @@
 do
 	mv log/java0.log.0 "log/`date +%Y-%m-%d_%H-%M-%S`_java.log"
 	mv log/stdout.log "log/`date +%Y-%m-%d_%H-%M-%S`_stdout.log"
-	nice -n -2 java -Xms512m -Xmx512m -cp bsf.jar:javolution.jar:bsh-2.0.jar:jython.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.gameserver.GameServer > log/stdout.log 2>&1
+	nice -n -2 java -Xincgc -Xss128k -Xms128m -Xmx768m -cp bsf.jar:javolution.jar:bsh-2.0.jar:jython.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.gameserver.GameServer > log/stdout.log 2>&1
 	err=$?
 #	/etc/init.d/mysql restart
 	sleep 10;