RecipeData.java 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * Copyright (C) 2004-2014 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.datatables;
  20. import java.util.ArrayList;
  21. import java.util.HashMap;
  22. import java.util.List;
  23. import java.util.Map;
  24. import org.w3c.dom.NamedNodeMap;
  25. import org.w3c.dom.Node;
  26. import com.l2jserver.gameserver.engines.DocumentParser;
  27. import com.l2jserver.gameserver.model.L2RecipeInstance;
  28. import com.l2jserver.gameserver.model.L2RecipeList;
  29. import com.l2jserver.gameserver.model.L2RecipeStatInstance;
  30. import com.l2jserver.gameserver.model.StatsSet;
  31. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  32. /**
  33. * The Class RecipeData.
  34. * @author Zoey76
  35. */
  36. public class RecipeData extends DocumentParser
  37. {
  38. private static final Map<Integer, L2RecipeList> _recipes = new HashMap<>();
  39. /**
  40. * Instantiates a new recipe data.
  41. */
  42. protected RecipeData()
  43. {
  44. load();
  45. }
  46. @Override
  47. public void load()
  48. {
  49. _recipes.clear();
  50. parseDatapackFile("data/recipes.xml");
  51. _log.info(getClass().getSimpleName() + ": Loaded " + _recipes.size() + " recipes.");
  52. }
  53. @Override
  54. protected void parseDocument()
  55. {
  56. // TODO: Cleanup checks enforced by XSD.
  57. final List<L2RecipeInstance> recipePartList = new ArrayList<>();
  58. final List<L2RecipeStatInstance> recipeStatUseList = new ArrayList<>();
  59. final List<L2RecipeStatInstance> recipeAltStatChangeList = new ArrayList<>();
  60. for (Node n = getCurrentDocument().getFirstChild(); n != null; n = n.getNextSibling())
  61. {
  62. if ("list".equalsIgnoreCase(n.getNodeName()))
  63. {
  64. RECIPES_FILE: for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
  65. {
  66. if ("item".equalsIgnoreCase(d.getNodeName()))
  67. {
  68. recipePartList.clear();
  69. recipeStatUseList.clear();
  70. recipeAltStatChangeList.clear();
  71. NamedNodeMap attrs = d.getAttributes();
  72. Node att;
  73. int id = -1;
  74. boolean haveRare = false;
  75. StatsSet set = new StatsSet();
  76. att = attrs.getNamedItem("id");
  77. if (att == null)
  78. {
  79. _log.severe(getClass().getSimpleName() + ": Missing id for recipe item, skipping");
  80. continue;
  81. }
  82. id = Integer.parseInt(att.getNodeValue());
  83. set.set("id", id);
  84. att = attrs.getNamedItem("recipeId");
  85. if (att == null)
  86. {
  87. _log.severe(getClass().getSimpleName() + ": Missing recipeId for recipe item id: " + id + ", skipping");
  88. continue;
  89. }
  90. set.set("recipeId", Integer.parseInt(att.getNodeValue()));
  91. att = attrs.getNamedItem("name");
  92. if (att == null)
  93. {
  94. _log.severe(getClass().getSimpleName() + ": Missing name for recipe item id: " + id + ", skipping");
  95. continue;
  96. }
  97. set.set("recipeName", att.getNodeValue());
  98. att = attrs.getNamedItem("craftLevel");
  99. if (att == null)
  100. {
  101. _log.severe(getClass().getSimpleName() + ": Missing level for recipe item id: " + id + ", skipping");
  102. continue;
  103. }
  104. set.set("craftLevel", Integer.parseInt(att.getNodeValue()));
  105. att = attrs.getNamedItem("type");
  106. if (att == null)
  107. {
  108. _log.severe(getClass().getSimpleName() + ": Missing type for recipe item id: " + id + ", skipping");
  109. continue;
  110. }
  111. set.set("isDwarvenRecipe", att.getNodeValue().equalsIgnoreCase("dwarven"));
  112. att = attrs.getNamedItem("successRate");
  113. if (att == null)
  114. {
  115. _log.severe(getClass().getSimpleName() + ": Missing successRate for recipe item id: " + id + ", skipping");
  116. continue;
  117. }
  118. set.set("successRate", Integer.parseInt(att.getNodeValue()));
  119. for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
  120. {
  121. if ("statUse".equalsIgnoreCase(c.getNodeName()))
  122. {
  123. String statName = c.getAttributes().getNamedItem("name").getNodeValue();
  124. int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue());
  125. try
  126. {
  127. recipeStatUseList.add(new L2RecipeStatInstance(statName, value));
  128. }
  129. catch (Exception e)
  130. {
  131. _log.severe(getClass().getSimpleName() + ": Error in StatUse parameter for recipe item id: " + id + ", skipping");
  132. continue RECIPES_FILE;
  133. }
  134. }
  135. else if ("altStatChange".equalsIgnoreCase(c.getNodeName()))
  136. {
  137. String statName = c.getAttributes().getNamedItem("name").getNodeValue();
  138. int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue());
  139. try
  140. {
  141. recipeAltStatChangeList.add(new L2RecipeStatInstance(statName, value));
  142. }
  143. catch (Exception e)
  144. {
  145. _log.severe(getClass().getSimpleName() + ": Error in AltStatChange parameter for recipe item id: " + id + ", skipping");
  146. continue RECIPES_FILE;
  147. }
  148. }
  149. else if ("ingredient".equalsIgnoreCase(c.getNodeName()))
  150. {
  151. int ingId = Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue());
  152. int ingCount = Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue());
  153. recipePartList.add(new L2RecipeInstance(ingId, ingCount));
  154. }
  155. else if ("production".equalsIgnoreCase(c.getNodeName()))
  156. {
  157. set.set("itemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()));
  158. set.set("count", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()));
  159. }
  160. else if ("productionRare".equalsIgnoreCase(c.getNodeName()))
  161. {
  162. set.set("rareItemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()));
  163. set.set("rareCount", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()));
  164. set.set("rarity", Integer.parseInt(c.getAttributes().getNamedItem("rarity").getNodeValue()));
  165. haveRare = true;
  166. }
  167. }
  168. L2RecipeList recipeList = new L2RecipeList(set, haveRare);
  169. for (L2RecipeInstance recipePart : recipePartList)
  170. {
  171. recipeList.addRecipe(recipePart);
  172. }
  173. for (L2RecipeStatInstance recipeStatUse : recipeStatUseList)
  174. {
  175. recipeList.addStatUse(recipeStatUse);
  176. }
  177. for (L2RecipeStatInstance recipeAltStatChange : recipeAltStatChangeList)
  178. {
  179. recipeList.addAltStatChange(recipeAltStatChange);
  180. }
  181. _recipes.put(id, recipeList);
  182. }
  183. }
  184. }
  185. }
  186. }
  187. /**
  188. * Gets the recipe list.
  189. * @param listId the list id
  190. * @return the recipe list
  191. */
  192. public L2RecipeList getRecipeList(int listId)
  193. {
  194. return _recipes.get(listId);
  195. }
  196. /**
  197. * Gets the recipe by item id.
  198. * @param itemId the item id
  199. * @return the recipe by item id
  200. */
  201. public L2RecipeList getRecipeByItemId(int itemId)
  202. {
  203. for (L2RecipeList find : _recipes.values())
  204. {
  205. if (find.getRecipeId() == itemId)
  206. {
  207. return find;
  208. }
  209. }
  210. return null;
  211. }
  212. /**
  213. * Gets the all item ids.
  214. * @return the all item ids
  215. */
  216. public int[] getAllItemIds()
  217. {
  218. int[] idList = new int[_recipes.size()];
  219. int i = 0;
  220. for (L2RecipeList rec : _recipes.values())
  221. {
  222. idList[i++] = rec.getRecipeId();
  223. }
  224. return idList;
  225. }
  226. /**
  227. * Gets the valid recipe list.
  228. * @param player the player
  229. * @param id the recipe list id
  230. * @return the valid recipe list
  231. */
  232. public L2RecipeList getValidRecipeList(L2PcInstance player, int id)
  233. {
  234. L2RecipeList recipeList = _recipes.get(id);
  235. if ((recipeList == null) || (recipeList.getRecipes().length == 0))
  236. {
  237. player.sendMessage(getClass().getSimpleName() + ": No recipe for: " + id);
  238. player.isInCraftMode(false);
  239. return null;
  240. }
  241. return recipeList;
  242. }
  243. /**
  244. * Gets the single instance of RecipeData.
  245. * @return single instance of RecipeData
  246. */
  247. public static RecipeData getInstance()
  248. {
  249. return SingletonHolder._instance;
  250. }
  251. /**
  252. * The Class SingletonHolder.
  253. */
  254. private static class SingletonHolder
  255. {
  256. protected static final RecipeData _instance = new RecipeData();
  257. }
  258. }