/* * Copyright (C) 2004-2015 L2J Server * * This file is part of L2J Server. * * L2J Server is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * L2J Server is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.l2jserver.gameserver.data.xml.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import com.l2jserver.gameserver.model.L2RecipeInstance; import com.l2jserver.gameserver.model.L2RecipeList; import com.l2jserver.gameserver.model.L2RecipeStatInstance; import com.l2jserver.gameserver.model.StatsSet; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.util.data.xml.IXmlReader; /** * The Class RecipeData. * @author Zoey76 */ public class RecipeData implements IXmlReader { private final Map _recipes = new HashMap<>(); /** * Instantiates a new recipe data. */ protected RecipeData() { load(); } @Override public void load() { _recipes.clear(); parseDatapackFile("data/recipes.xml"); LOGGER.info("{}: Loaded {} recipes.", getClass().getSimpleName(), _recipes.size()); } @Override public void parseDocument(Document doc) { // TODO: Cleanup checks enforced by XSD. final List recipePartList = new ArrayList<>(); final List recipeStatUseList = new ArrayList<>(); final List recipeAltStatChangeList = new ArrayList<>(); for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) { if ("list".equalsIgnoreCase(n.getNodeName())) { RECIPES_FILE: for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) { if ("item".equalsIgnoreCase(d.getNodeName())) { recipePartList.clear(); recipeStatUseList.clear(); recipeAltStatChangeList.clear(); NamedNodeMap attrs = d.getAttributes(); Node att; int id = -1; boolean haveRare = false; StatsSet set = new StatsSet(); att = attrs.getNamedItem("id"); if (att == null) { LOGGER.error("{}: Missing id for recipe item, skipping!", getClass().getSimpleName()); continue; } id = Integer.parseInt(att.getNodeValue()); set.set("id", id); att = attrs.getNamedItem("recipeId"); if (att == null) { LOGGER.error("{}: Missing recipeId for recipe item ID: {}, skipping!", getClass().getSimpleName(), id); continue; } set.set("recipeId", Integer.parseInt(att.getNodeValue())); att = attrs.getNamedItem("name"); if (att == null) { LOGGER.error("{}: Missing name for recipe item ID: {}, skipping!", getClass().getSimpleName(), id); continue; } set.set("recipeName", att.getNodeValue()); att = attrs.getNamedItem("craftLevel"); if (att == null) { LOGGER.error("{}: Missing level for recipe item ID: {}, skipping!", getClass().getSimpleName(), id); continue; } set.set("craftLevel", Integer.parseInt(att.getNodeValue())); att = attrs.getNamedItem("type"); if (att == null) { LOGGER.error("{}: Missing type for recipe item ID: {}, skipping!", getClass().getSimpleName(), id); continue; } set.set("isDwarvenRecipe", att.getNodeValue().equalsIgnoreCase("dwarven")); att = attrs.getNamedItem("successRate"); if (att == null) { LOGGER.error("{}: Missing successRate for recipe item ID: {}, skipping!", getClass().getSimpleName(), id); continue; } set.set("successRate", Integer.parseInt(att.getNodeValue())); for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling()) { if ("statUse".equalsIgnoreCase(c.getNodeName())) { String statName = c.getAttributes().getNamedItem("name").getNodeValue(); int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue()); try { recipeStatUseList.add(new L2RecipeStatInstance(statName, value)); } catch (Exception e) { LOGGER.error("{}: Error in StatUse parameter for recipe item ID: {}, skipping!", getClass().getSimpleName(), id); continue RECIPES_FILE; } } else if ("altStatChange".equalsIgnoreCase(c.getNodeName())) { String statName = c.getAttributes().getNamedItem("name").getNodeValue(); int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue()); try { recipeAltStatChangeList.add(new L2RecipeStatInstance(statName, value)); } catch (Exception e) { LOGGER.error("{}: Error in AltStatChange parameter for recipe item ID: {}, skipping!", getClass().getSimpleName(), id); continue RECIPES_FILE; } } else if ("ingredient".equalsIgnoreCase(c.getNodeName())) { int ingId = Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()); int ingCount = Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()); recipePartList.add(new L2RecipeInstance(ingId, ingCount)); } else if ("production".equalsIgnoreCase(c.getNodeName())) { set.set("itemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue())); set.set("count", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue())); } else if ("productionRare".equalsIgnoreCase(c.getNodeName())) { set.set("rareItemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue())); set.set("rareCount", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue())); set.set("rarity", Integer.parseInt(c.getAttributes().getNamedItem("rarity").getNodeValue())); haveRare = true; } } L2RecipeList recipeList = new L2RecipeList(set, haveRare); for (L2RecipeInstance recipePart : recipePartList) { recipeList.addRecipe(recipePart); } for (L2RecipeStatInstance recipeStatUse : recipeStatUseList) { recipeList.addStatUse(recipeStatUse); } for (L2RecipeStatInstance recipeAltStatChange : recipeAltStatChangeList) { recipeList.addAltStatChange(recipeAltStatChange); } _recipes.put(id, recipeList); } } } } } /** * Gets the recipe list. * @param listId the list id * @return the recipe list */ public L2RecipeList getRecipeList(int listId) { return _recipes.get(listId); } /** * Gets the recipe by item id. * @param itemId the item id * @return the recipe by item id */ public L2RecipeList getRecipeByItemId(int itemId) { for (L2RecipeList find : _recipes.values()) { if (find.getRecipeId() == itemId) { return find; } } return null; } /** * Gets the all item ids. * @return the all item ids */ public int[] getAllItemIds() { int[] idList = new int[_recipes.size()]; int i = 0; for (L2RecipeList rec : _recipes.values()) { idList[i++] = rec.getRecipeId(); } return idList; } /** * Gets the valid recipe list. * @param player the player * @param id the recipe list id * @return the valid recipe list */ public L2RecipeList getValidRecipeList(L2PcInstance player, int id) { L2RecipeList recipeList = _recipes.get(id); if ((recipeList == null) || (recipeList.getRecipes().length == 0)) { player.sendMessage(getClass().getSimpleName() + ": No recipe for: " + id); player.isInCraftMode(false); return null; } return recipeList; } /** * Gets the single instance of RecipeData. * @return single instance of RecipeData */ public static RecipeData getInstance() { return SingletonHolder._instance; } /** * The Class SingletonHolder. */ private static class SingletonHolder { protected static final RecipeData _instance = new RecipeData(); } }