All pastes #45951 Raw Edit

Craft fix

public text v1 · immutable
#45951 ·published 2006-03-16 20:33 UTC
rendered paste body
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/serverpackets/RecipeItemMakeInfo.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/serverpackets/RecipeItemMakeInfo.java	(revision 1605)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/serverpackets/RecipeItemMakeInfo.java	(working copy)
@@ -31,14 +31,23 @@
 {
 	private static final String _S__D7_RECIPEITEMMAKEINFO = "[S] D7 RecipeItemMakeInfo";
 	private int _id;
-	private L2PcInstance _player;
+	private L2PcInstance _player;
+	private boolean _success;
 	
-	public RecipeItemMakeInfo(int id, L2PcInstance player)
+	public RecipeItemMakeInfo(int id, L2PcInstance player, boolean success)
 	{
 		_id = id;
-		_player = player;
+		_player = player;
+		_success = success;
 	}	
 	
+	public RecipeItemMakeInfo(int id,L2PcInstance player)
+	{
+		_id = id;
+		_player = player;
+		_success = true;
+	}
+	
 	final void runImpl()
 	{
 		// no long-running tasks
@@ -49,8 +58,10 @@
 		writeC(0xD7);
 		
 		writeD(_id);
+		writeD(0);	// unknown
     		writeD((int)_player.getCurrentMp());
     		writeD((int)_player.getMaxMp());
+    		writeD(_success ? 1 : 0);	// item creation success/failed 		
 	}
 
 	/* (non-Javadoc)
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/PacketHandler.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/PacketHandler.java	(revision 1605)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/PacketHandler.java	(working copy)
@@ -528,10 +528,9 @@
             case 0xab:
             	msg = new SnoopQuit(data, client);
             	break;
-            
-            //case 0xac:
-            //	msg = new RequestRecipeBookOpen(data, client);
-            //    break;
+            case 0xac: 		// we still need this packet to handle BACK button of craft dialog
+            	msg = new RequestRecipeBookOpen(data, client);
+                break;
             case 0xad:
                 msg = new RequestRecipeBookDestroy(data, client);
                 break;
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/RecipeController.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/RecipeController.java	(revision 1612)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/RecipeController.java	(working copy)
@@ -57,61 +57,74 @@
 public class RecipeController
 {
 	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>());
-    protected static final Random _rnd = new Random();
-	
-	public static RecipeController getInstance()	{return _instance == null? _instance = new RecipeController() : _instance;}
-	
+	protected static Map<L2PcInstance, RecipeItemMaker> activeMakers = Collections.synchronizedMap(new WeakHashMap<L2PcInstance, RecipeItemMaker>());
+	protected static final Random _rnd = new Random();
+
+	public static RecipeController getInstance()
+	{
+		return _instance == null ? _instance = new RecipeController() : _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)
+			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.");
+			_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);
+				_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) { }
-        }
+		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++)
@@ -124,120 +137,112 @@
 		}
 		return null;
 	}
+
 	public synchronized void requestBookOpen(L2PcInstance player, boolean isDwarvenCraft)
-	{						
-		if (!Config.ALT_GAME_CREATION){
-			RecipeBookItemList response = new RecipeBookItemList(isDwarvenCraft,player.getMaxMp()); 
-	 		response.addRecipes(isDwarvenCraft ? player.getDwarvenRecipeBook() : player.getCommonRecipeBook()); 
+	{
+		RecipeItemMaker maker = null;
+		if (Config.ALT_GAME_CREATION) maker = activeMakers.get(player);
+
+		if (maker == null)
+		{
+			RecipeBookItemList response = new RecipeBookItemList(isDwarvenCraft, player.getMaxMp());
+			response.addRecipes(isDwarvenCraft	? player.getDwarvenRecipeBook()
+												: player.getCommonRecipeBook());
 			player.sendPacket(response);
 			return;
 		}
-		
-        RecipeItemMaker maker = activeMakers.get(player);
-        
-        if (maker == null) {
-        	RecipeBookItemList response = new RecipeBookItemList(isDwarvenCraft,player.getMaxMp()); 
-        	response.addRecipes(isDwarvenCraft ? player.getDwarvenRecipeBook() : player.getCommonRecipeBook());
-        	player.sendPacket(response);
-        	return;
-        }
-        
-        SystemMessage sm = new SystemMessage(SystemMessage.CANT_ALTER_RECIPEBOOK_WHILE_CRAFTING);
-        player.sendPacket(sm);
-        return;
+
+		SystemMessage sm = new SystemMessage(SystemMessage.CANT_ALTER_RECIPEBOOK_WHILE_CRAFTING);
+		player.sendPacket(sm);
+		return;
 	}
+
 	public synchronized void requestMakeItemAbort(L2PcInstance player)
 	{
 		activeMakers.remove(player);
 	}
-	public synchronized void requestManufactureItem(L2PcInstance manufacturer, int recipeListId, L2PcInstance player)
+
+	public synchronized void requestManufactureItem(L2PcInstance manufacturer, int recipeListId,
+													L2PcInstance player)
 	{
-		L2RecipeList recipeList = getRecipeList(recipeListId-1);
-		
-		SystemMessage sm = new SystemMessage(614);
-		
+		L2RecipeList recipeList = getValidRecipeList(player, recipeListId);
+
+		if (recipeList == null) return;
 		manufacturer.isInCraftMode(true);
-		if ((recipeList == null) || (recipeList.getRecipes().length == 0) || (!manufacturer.hasRecipeList(recipeListId)))
+
+		if (!Config.ALT_GAME_CREATION)
 		{
-			sm = new SystemMessage(614); 
-			sm.addString("No recipe for: " + recipeListId);
-			player.sendPacket(sm);
-        		manufacturer.isInCraftMode(false);
-			return;
+			new RecipeItemMaker(manufacturer, recipeList, player);
 		}
-		if (!Config.ALT_GAME_CREATION) {
-			new RecipeItemMaker(manufacturer, recipeList, player);
-		} else {
+		else
+		{
 			RecipeItemMaker 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);
+				player.sendMessage("Manufacturer is busy creating.");
+				manufacturer.isInCraftMode(false);
 				return;
 			}
 			maker = new RecipeItemMaker(manufacturer, recipeList, player);
-			if (maker.isValid)
-				activeMakers.put(manufacturer, maker);
+			if (maker.isValid) activeMakers.put(manufacturer, maker);
 		}
 	}
+
 	public synchronized void requestMakeItem(L2PcInstance player, int recipeListId)
 	{
-		L2RecipeList recipeList = getRecipeList(recipeListId-1);
-        
-   		player.isInCraftMode(true);
-		if ((recipeList == null) || (recipeList.getRecipes().length == 0))
+		L2RecipeList recipeList = getValidRecipeList(player, recipeListId);
+
+		if (recipeList == null) return;
+
+		player.isInCraftMode(true);
+
+		if (!Config.ALT_GAME_CREATION)
 		{
-			player.sendMessage("No recipe for: " + recipeListId);
-            player.isInCraftMode(false);
-			return;
+			new RecipeItemMaker(player, recipeList, player);
 		}
-		if (!Config.ALT_GAME_CREATION) {
-			new RecipeItemMaker(player, recipeList, player);
-		} else {
+		else
+		{
 			RecipeItemMaker maker = activeMakers.get(player);
 			if (maker != null)
 			{
-				SystemMessage sm = new SystemMessage(614); 
+				SystemMessage sm = new SystemMessage(614);
 				sm.addString("You are busy creating ");
 				sm.addItemName(recipeList.getItemId());
 				player.sendPacket(sm);
-                player.isInCraftMode(false);
+				player.isInCraftMode(false);
 				return;
 			}
 			maker = new RecipeItemMaker(player, recipeList, player);
-			if (maker.isValid)
-				activeMakers.put(player, maker);
+			if (maker.isValid) activeMakers.put(player, maker);
 		}
 	}
+
 	private void parseList(String line)
 	{
-		try 
+		try
 		{
-			StringTokenizer st = new StringTokenizer(line,";");
+			StringTokenizer st = new StringTokenizer(line, ";");
 			List<L2RecipeInstance> recipePartList = new FastList<L2RecipeInstance>();
-		
+
 			//we use common/dwarf for easy reading of the recipes.csv file 
-			String recipeTypeString = st.nextToken(); 
-	 	
+			String recipeTypeString = st.nextToken();
+
 			//now we parse the string into a boolean 
-			boolean isDwarvenRecipe; 
-	 	
-			if (recipeTypeString.equalsIgnoreCase("dwarven")) 		isDwarvenRecipe = true; 
-			else if (recipeTypeString.equalsIgnoreCase("common"))	isDwarvenRecipe = false; 
-			else 
-			{	//prints a helpfull message 
-				_log.warning("Error parsing recipes.csv, unknow recipe type "+recipeTypeString); 
+			boolean isDwarvenRecipe;
+
+			if (recipeTypeString.equalsIgnoreCase("dwarven")) isDwarvenRecipe = true;
+			else if (recipeTypeString.equalsIgnoreCase("common")) isDwarvenRecipe = false;
+			else
+			{ //prints a helpfull message 
+				_log.warning("Error parsing recipes.csv, unknow recipe type " + recipeTypeString);
 				return;
 			}
-		
+
 			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())
@@ -248,28 +253,31 @@
 				L2RecipeInstance rp = new L2RecipeInstance(rpItemId, quantity);
 				recipePartList.add(rp);
 			}
-		
+
 			int itemId = Integer.parseInt(st.nextToken());
 			int count = Integer.parseInt(st.nextToken());
-		
+
 			//npc fee
-			/*String notdoneyet = */ st.nextToken();
-		
+			/*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,isDwarvenRecipe);
+
+			L2RecipeList recipeList = new L2RecipeList(id, level, recipeId, recipeName, successRate,
+														mpCost, itemId, count, isDwarvenRecipe);
 			for (L2RecipeInstance recipePart : recipePartList)
 			{
 				recipeList.addRecipe(recipePart);
 			}
 			_lists.put(new Integer(_lists.size()), recipeList);
-		} catch (Exception e) {
+		}
+		catch (Exception e)
+		{
 			_log.severe("Exception in RecipeController.parseList() - " + e);
-		};
+		}
+		;
 	}
 
-	
 	public class RecipeItemMaker implements Runnable
 	{
 		public boolean isValid;
@@ -280,103 +288,32 @@
 		final L2RecipeList recipeList;
 		final L2PcInstance target;
 		int timeReady;
+		int delay;
+		int gameTicks;
 		int totalItems;
 		int usedItems;
-
+		int skillLevel;
+		
 		public RecipeItemMaker(L2PcInstance player, L2RecipeList recipeList, L2PcInstance target)
 		{
 			this.player = player;
 			this.target = target;
 			this.recipeList = recipeList;
 			this.items = new FastList<L2ItemInstance>();
+			this.isValid = false;
 
-			int skillLevel = recipeList.isDwarvenRecipe()	? player.getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN)
-															: player.getSkillLevel(L2Skill.SKILL_CREATE_COMMON);
+			skillLevel = recipeList.isDwarvenRecipe()	? player.getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN)
+														: player.getSkillLevel(L2Skill.SKILL_CREATE_COMMON);
 
-			if (skillLevel <= 0)
-			{
-				player.sendPacket(new ActionFailed());
-				player.isInCraftMode(false);
-				return;
-			}
+			if (!validateSkillLevel()) return;
+			if (!validateRecipeList()) return;
+			if (!validateCustomerCanAfford(target,player)) return; 
+			if (!validateMaterials()) return;
+			if (!validateMp()) return;
 
-			if ((recipeList == null) || (recipeList.getRecipes().length == 0))
-			{
-				player.sendMessage("No such recipe");
-				player.isInCraftMode(false);
-				return;
-			}
-
-			if (target != player) // target using manufacture services of player 
-			{
-				for (L2ManufactureItem temp : player.getCreateList().getList())
-					if (temp.getRecipeId() == recipeList.getId()) // find recipe for item we want manufactured
-					{
-						price = temp.getCost();
-						if (target.getAdena() < price) // check price
-						{
-							target.sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
-							player.isInCraftMode(false);
-							return;
-						}
-						break;
-					}
-			}
-
-			if (recipeList.getLevel() > skillLevel)
-			{
-				player.sendMessage("Need skill level " + recipeList.getLevel());
-				player.isInCraftMode(false);
-				return;
-			}
-
-			L2RecipeInstance[] recipes = recipeList.getRecipes();
-
-			Inventory inv = target.getInventory();
-
-			for (L2RecipeInstance recipe : recipes)
-			{
-				if (recipe.getQuantity() != 0)
-				{
-					L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
-					if ((invItem == null)
-						|| ((recipeList.isConsumable()	? (int) (recipe.getQuantity() * Config.RATE_CONSUMABLE_COST)
-														: recipe.getQuantity()) > invItem.getCount()))
-					{
-						target.sendMessage("You dont have the right elements for making this item"
-							+ ((recipeList.isConsumable() && Config.RATE_CONSUMABLE_COST != 1)	? ".\nDue to server rates you need "
-																									+ Config.RATE_CONSUMABLE_COST
-																									+ "x more material than listed in recipe"
-																								: ""));
-						player.isInCraftMode(false);
-						return;
-					}
-				}
-			}
-
-			if (!Config.ALT_GAME_CREATION && !validateMp()) return;
-
-			for (L2RecipeInstance recipe : recipes)
-			{
-				if (recipe.getQuantity() != 0)
-				{
-					L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
-					invItem = inv.dropItem(
-											"Manufacture",
-											invItem.getObjectId(),
-											recipeList.isConsumable()	? (int) (recipe.getQuantity() * Config.RATE_CONSUMABLE_COST)
-																		: recipe.getQuantity(), target,
-											player);
-					items.add(invItem);
-					materialsRefPrice += invItem.getReferencePrice() * invItem.getCount();
-					totalItems += invItem.getCount();
-				}
-			}
-
 			isValid = true;
-			timeReady = GameTimeController.TICKS_PER_SECOND + GameTimeController.getGameTicks();
-			if(Config.ALT_GAME_CREATION) ClientScheduler.getInstance().scheduleLow(this, 1100); 
-			else run(); // :)  this also helps remove craft lag
+			updateTime();
+			run();
 		}
 
 		private void finishCrafting()
@@ -385,9 +322,6 @@
 
 			if (Rnd.get(100) < recipeList.getSuccessRate())
 			{
-				int itemId = recipeList.getItemId();
-				int itemCount = recipeList.getCount();
-
 				if (target != player)
 				{
 					if (price > 0)
@@ -395,62 +329,89 @@
 						target.reduceAdena("Manufacture", price, player, false);
 						player.addAdena("Manufacture", price, target, false);
 					}
-
-					StatusUpdate su2 = new StatusUpdate(target.getObjectId());
-					su2.addAttribute(StatusUpdate.CUR_LOAD, target.getCurrentLoad());
-					target.sendPacket(su2);
+					updateCurLoad();
 				}
 
-				L2ItemInstance createdItem = target.getInventory().addItem("Manufacture", itemId, itemCount,
-																			target, player);
-				SystemMessage sm = new SystemMessage(SystemMessage.EARNED_ITEM);
-				sm.addItemName(itemId);
-				sm.addNumber(itemCount);
-				target.sendPacket(sm);
-
-				if (Config.ALT_GAME_CREATION)
-				{
-					int skillLevel;
-					skillLevel = player.getSkillLevel(recipeList.isDwarvenRecipe() ? L2Skill.SKILL_CREATE_DWARVEN : L2Skill.SKILL_CREATE_COMMON);
-					int receipeLevel = recipeList.getLevel();
-					int exp = createdItem.getReferencePrice() * itemCount;
-					// 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));
-					if(Config.DEBUG) 
-						_log.warning("Rewarded "+ player.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_XP, null,null) + 
-					    " XP   "+(int) player.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_SP, null,null) + " SP  to " + player.getName() );
-				}
+				RewardPlayer();
+				updateMakeInfo(true); // success
 			}
 			else
 			{
 				player.sendMessage("Item(s) failed to create");
+				updateMakeInfo(false);
 			}
-			activeMakers.remove(player);  // cause of this, we can't move RecipeItemMaker class out of RecipeController class
-										  // would be nice to rewrite crafting again some day, but for now I am happy with "fix craft lag"
-			
+			activeMakers.remove(player);
 			player.isInCraftMode(false);
 
-			StatusUpdate su = new StatusUpdate(player.getObjectId());
-			su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad());
-			su.addAttribute(StatusUpdate.CUR_MP, (int) player.getCurrentMp());
-			player.sendPacket(su);
+			target.sendPacket(new ItemList(target, false));
+		}
 
-			target.sendPacket(new ItemList(target, false));
-			if (target == player) target.sendPacket(new RecipeItemMakeInfo(recipeList.getId(), target));
+		public void run()
+		{
+			player.isInCraftMode(true);
+			gameTicks = GameTimeController.getGameTicks();
+			if (!validateCraftingEnabled() || !validateMp()) return;
+
+			updateTime();
+
+			if (Config.ALT_GAME_CREATION && !items.isEmpty())
+			{
+				player.reduceCurrentMp(recipeList.getMpCost()); // use some mp
+				grabSomeItems(); // grab (equip) some more items with a nice msg to player
+
+				MagicSkillUser msk = new MagicSkillUser(
+														player,
+														recipeList.isDwarvenRecipe() ? L2Skill.SKILL_CREATE_DWARVEN
+																					: L2Skill.SKILL_CREATE_COMMON,
+														skillLevel, delay, 0);
+
+				player.broadcastPacket(msk);
+
+				player.sendPacket(new SetupGauge(0, delay));
+
+				ClientScheduler.getInstance().scheduleLow(this, 100 + delay);
+			}
+			else finishCrafting();
+
+			// update load and mana bar of craft window
+			updateMakeInfo(true);
+			updateCurMp();
+			updateCurLoad();
+		}
+
+		private void updateTime()
+		{
+			// divided by RATE_CONSUMABLES_COST to remove craft time increase on higher consumable rates (more mats consumed -> more time)
+			timeReady = gameTicks
+				+ (int) (Config.ALT_GAME_CREATION_SPEED
+					* player.getMReuseRate(player.getKnownSkill(172))
+					* GameTimeController.TICKS_PER_SECOND / Config.RATE_CONSUMABLE_COST);
+
+			delay = (timeReady - gameTicks) * GameTimeController.MILLIS_IN_TICK;
+		}
+
+		private void updateMakeInfo(boolean success)
+		{
+			if (target == player) target.sendPacket(new RecipeItemMakeInfo(recipeList.getId(), target, success));
 			else target.sendPacket(new RecipeShopItemInfo(player.getObjectId(), recipeList.getId()));
+		}
 
+		private void updateCurLoad()
+		{
+			StatusUpdate su = new StatusUpdate(target.getObjectId());
+			su.addAttribute(StatusUpdate.CUR_LOAD, target.getCurrentLoad());
+			target.sendPacket(su);
 		}
 
+		private void updateCurMp()
+		{
+
+			StatusUpdate su = new StatusUpdate(target.getObjectId());
+			su.addAttribute(StatusUpdate.CUR_MP, (int) target.getCurrentMp());
+			target.sendPacket(su);
+			;
+		}
+
 		private void grabSomeItems()
 		{
 			int numItems = player.getSkillLevel(172);
@@ -467,7 +428,7 @@
 				numItems -= count;
 				usedItems += count;
 
-				SystemMessage sm = new SystemMessage(368);
+				SystemMessage sm = new SystemMessage(368); // you equipped ...
 				sm.addNumber(count);
 				sm.addItemName(item.getItemId());
 				if (target == null) player.sendPacket(sm);
@@ -475,64 +436,177 @@
 			}
 		}
 
-		public void run()
+		private boolean validateCraftingEnabled()
 		{
-			player.isInCraftMode(true);
-			int gameTicks = GameTimeController.getGameTicks();
-			if (!validateCraftingEnabled() || !validateMp()) return;
+			if (!Config.IS_CRAFTING_ENABLED)
+			{
+				target.sendMessage("Crafting is currently disabled.");
+				player.isInCraftMode(false);
+				activeMakers.remove(player);
+				updateMakeInfo(false);
+				return false;
+			}
+			return true;
+		}
 
-	/*		this is why craft lag happened
-	 
-	 		if (timeReady > gameTicks)
+		private boolean validateCustomerCanAfford(L2PcInstance customer, L2PcInstance manufacturer)
+		{
+			if(customer==manufacturer) return true;
+			for (L2ManufactureItem temp : manufacturer.getCreateList().getList())
+				if (temp.getRecipeId() == recipeList.getId()) // find recipe for item we want manufactured
+				{
+					int price = temp.getCost();
+					if (customer.getAdena() < price) // check price
+					{
+						customer.sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
+						manufacturer.isInCraftMode(false);
+						activeMakers.remove(manufacturer);
+						return false;
+					}
+					break;
+				}
+			return true;
+		}		
+		private boolean validateMp()
+		{
+			if (player.getCurrentMp() < recipeList.getMpCost())
 			{
+				target.sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_MP));
 				player.isInCraftMode(false);
-				return;
+				activeMakers.remove(player);
+				updateMakeInfo(false);
+				return false;
 			}
-	*/
+			return true;
+		}
 
-			// divided by RATE_CONSUMABLES_COST to remove craft time increase on higher consumable rates (more mats consumed -> more time)
-			timeReady = gameTicks
-				+ (int) (Config.ALT_GAME_CREATION_SPEED * player.getMReuseRate(player.getKnownSkill(172)) * GameTimeController.TICKS_PER_SECOND / Config.RATE_CONSUMABLE_COST);
+		private boolean validateMaterials()
+		{
+			L2RecipeInstance[] recipes = recipeList.getRecipes();
 
-			if (Config.ALT_GAME_CREATION && !items.isEmpty()) 
+			Inventory inv = target.getInventory();
+
+			for (L2RecipeInstance recipe : recipes)
 			{
-				if (!validateMp()) return;
+				if (recipe.getQuantity() != 0)
+				{
+					L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
+					if ((invItem == null)
+						|| ((recipeList.isConsumable()	? (int) (recipe.getQuantity() * Config.RATE_CONSUMABLE_COST)
+														: recipe.getQuantity()) > invItem.getCount()))
+					{
+						target.sendMessage("You dont have the right elements for making this item"
+							+ ((recipeList.isConsumable() && Config.RATE_CONSUMABLE_COST != 1)	? ".\nDue to server rates you need "
+																									+ Config.RATE_CONSUMABLE_COST
+																									+ "x more material than listed in recipe"
+																								: ""));
+						player.isInCraftMode(false);
+						activeMakers.remove(player);
+						updateMakeInfo(false);
+						return false;
+					}
+				}
+			}
 
-				player.reduceCurrentMp(recipeList.getMpCost());		// use some mp
-				grabSomeItems();									// grab (equip) some more items with a nice msg to player
+			for (L2RecipeInstance recipe : recipes)
+			{
+				if (recipe.getQuantity() != 0)
+				{
+					L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
+					invItem = inv.dropItem(
+											"Manufacture",
+											invItem.getObjectId(),
+											recipeList.isConsumable()	? (int) (recipe.getQuantity() * Config.RATE_CONSUMABLE_COST)
+																		: recipe.getQuantity(), target,
+											player);
+					items.add(invItem);
+					materialsRefPrice += invItem.getReferencePrice() * invItem.getCount();
+					totalItems += invItem.getCount();
+				}
+			}
 
-				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 finishCrafting();
+			return true;
 		}
 
-		private boolean validateCraftingEnabled()
+		private boolean validateSkillLevel()
 		{
-			if (!Config.IS_CRAFTING_ENABLED)
+			if (recipeList.getLevel() > skillLevel)
 			{
-				target.sendMessage("Crafting is currently disabled.");
+				player.sendMessage("Need skill level " + recipeList.getLevel());
+				player.sendPacket(new ActionFailed());
 				player.isInCraftMode(false);
+				activeMakers.remove(player);
+				updateMakeInfo(false);
 				return false;
 			}
 			return true;
 		}
 
-		private boolean validateMp()
+		private boolean validateRecipeList()
 		{
-			if (player.getCurrentMp() < recipeList.getMpCost())
+			if ((recipeList == null) || (recipeList.getRecipes().length == 0))
 			{
-				target.sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_MP));
+				player.sendMessage("No such recipe");
 				player.isInCraftMode(false);
+				activeMakers.remove(player);
+				updateMakeInfo(false);
 				return false;
 			}
 			return true;
 		}
+
+		private void RewardPlayer()
+		{
+			int itemId = recipeList.getItemId();
+			int itemCount = recipeList.getCount();
+
+			L2ItemInstance createdItem = target.getInventory().addItem("Manufacture", itemId, itemCount,
+																		target, player);
+			SystemMessage sm = new SystemMessage(SystemMessage.EARNED_ITEM);
+			sm.addItemName(itemId);
+			sm.addNumber(itemCount);
+			target.sendPacket(sm);
+
+			if (Config.ALT_GAME_CREATION)
+			{
+				int recipeLevel = recipeList.getLevel();
+				int exp = createdItem.getReferencePrice() * itemCount;
+				// one variation
+				// exp -= materialsRefPrice;
+				
+				if (exp < 0) exp = 0;
+				
+				// another variation
+				exp /= recipeLevel;
+				for (int i = skillLevel; i > recipeLevel; 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));
+
+				sm = new SystemMessage(SystemMessage.YOU_EARNED_S1_EXP_AND_S2_SP);
+				sm.addNumber((int) player.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_XP, null, null));
+				sm.addNumber((int) player.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_SP, null, null));
+				player.sendPacket(sm);
+			}
+		}
 	}
+
+	private L2RecipeList getValidRecipeList(L2PcInstance player, int id)
+	{
+		L2RecipeList recipeList = getRecipeList(id - 1);
+
+		if ((recipeList == null) || (recipeList.getRecipes().length == 0))
+		{
+			player.sendMessage("No recipe for: " + id);
+			player.isInCraftMode(false);
+			return null;
+		}
+		return recipeList;
+	};
 	
-	
+
 }
+