All pastes #44884 Raw Edit

Stuff

public java v1 · immutable
#44884 ·published 2006-03-08 15:02 UTC
rendered paste body
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * 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 later////////////import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.LineNumberReader;import java.util.Collections;import java.util.List;import java.util.Map;import java.util.Random;import java.util.StringTokenizer;import java.util.WeakHashMap;import java.util.logging.Level;import java.util.logging.Logger;import javolution.util.FastList;import javolution.util.FastMap;import net.sf.l2j.Config;import net.sf.l2j.gameserver.model.Inventory;import net.sf.l2j.gameserver.model.L2ItemInstance;import net.sf.l2j.gameserver.model.L2ManufactureItem;import net.sf.l2j.gameserver.model.L2RecipeInstance;import net.sf.l2j.gameserver.model.L2RecipeList;import net.sf.l2j.gameserver.model.L2Skill;import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;import net.sf.l2j.gameserver.serverpackets.ActionFailed;import net.sf.l2j.gameserver.serverpackets.InventoryUpdate;import net.sf.l2j.gameserver.serverpackets.ItemList;import net.sf.l2j.gameserver.serverpackets.MagicSkillUser;import net.sf.l2j.gameserver.serverpackets.RecipeBookItemList;import net.sf.l2j.gameserver.serverpackets.RecipeItemMakeInfo;import net.sf.l2j.gameserver.serverpackets.RecipeShopItemInfo;import net.sf.l2j.gameserver.serverpackets.SetupGauge;import net.sf.l2j.gameserver.serverpackets.StatusUpdate;import net.sf.l2j.gameserver.serverpackets.SystemMessage;import net.sf.l2j.gameserver.skills.Stats;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()    {        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, boolean isDwarvenCraft)    {                               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(isDwarvenCraft,player.getMaxMp());		 	if (isDwarvenCraft) 		 		response.addRecipes(player.getDwarvenRecipeBook()); 		 	else 		 		response.addRecipes(player.getCommonRecipeBook());             player.sendPacket(response);            return;        }                if (Config.DEBUG) _log.fine("requestBookOpen:  Busy creating");        SystemMessage sm = new SystemMessage(SystemMessage.CANT_ALTER_RECIPEBOOK_WHILE_CRAFTING);        sm.addItemName(maker.recipeList.getItemId());        player.sendPacket(sm);        return;    }        public synchronized void requestManufactureItem(L2PcInstance manufacturer, int recipeListId, L2PcInstance customer)    {        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;            }                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");                        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())                {                    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;                }            }                        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>();		        //we use common/dwarf for easy reading of the recipes.csv file 	 	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); 	 		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())		{			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,isDwarvenRecipe);		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;        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>();            if(recipeList.isDwarvenRecipe())             	this.skillLevel = manufacturer.getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN);            else            	this.skillLevel = manufacturer.getSkillLevel(L2Skill.SKILL_CREATE_COMMON);                        // 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(172)) * 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.scheduleEvent(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;                                    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);                                                    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()));            }        }      }}