PageRenderTime 1826ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/mechanisms/src/main/java/com/sk89q/craftbook/mech/CauldronCookbook.java

http://github.com/sk89q/craftbook
Java | 307 lines | 164 code | 22 blank | 121 comment | 30 complexity | 424717ac9f96b61d577dfdc09b45479c MD5 | raw file
Possible License(s): GPL-3.0
  1. // $Id$
  2. /*
  3. * CraftBook
  4. * Copyright (C) 2010 sk89q <http://www.sk89q.com>
  5. *
  6. * This program 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. * This program 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
  14. * GNU 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.sk89q.craftbook.mech;
  20. import java.util.logging.Logger;
  21. import java.io.BufferedReader;
  22. import java.io.File;
  23. import java.io.FileNotFoundException;
  24. import java.io.FileReader;
  25. import java.io.IOException;
  26. import java.util.Collections;
  27. import java.util.HashMap;
  28. import java.util.Map;
  29. import java.util.List;
  30. import java.util.ArrayList;
  31. import java.util.logging.Level;
  32. //import java.io.*;
  33. /**
  34. * Store of recipes.
  35. *
  36. * @author sk89q
  37. */
  38. public class CauldronCookbook {
  39. /**
  40. * Constructs a CauldronCookbook - reads recipes.
  41. */
  42. public CauldronCookbook(){
  43. try {
  44. CauldronCookbook recipes = readCauldronRecipes("cauldron-recipes.txt");
  45. if (recipes.size() != 0) {
  46. log.info(recipes.size()
  47. + " cauldron recipe(s) loaded");
  48. } else {
  49. log.warning("cauldron-recipes.txt had no recipes");
  50. }
  51. } catch (FileNotFoundException e) {
  52. log.info("cauldron-recipes.txt not found: " + e.getMessage());
  53. try {
  54. log.info("Looked in: " + (new File(".")).getCanonicalPath() + "/plugins/CraftBookMechanisms");
  55. } catch (IOException ioe) {
  56. // Eat error
  57. }
  58. } catch (IOException e) {
  59. log.warning("cauldron-recipes.txt not loaded: " + e.getMessage());
  60. }
  61. }
  62. /**
  63. * For fast recipe lookup.
  64. *
  65. */
  66. private List<Recipe> recipes =
  67. new ArrayList<Recipe>();
  68. /**
  69. * For logging purposes.
  70. */
  71. static Logger log = Logger.getLogger("Minecraft");
  72. /**
  73. * Adds a recipe.
  74. *
  75. * @param recipe
  76. */
  77. public void add(Recipe recipe) {
  78. recipes.add(recipe);
  79. }
  80. /**
  81. * Gets a recipe by its ingredients. The list will be sorted.
  82. *
  83. * @param ingredients
  84. * @return
  85. */
  86. public Recipe find(Map<Integer,Integer> ingredients) {
  87. for (Recipe recipe : recipes) {
  88. if (recipe.hasAllIngredients(ingredients)) {
  89. return recipe;
  90. }
  91. }
  92. return null;
  93. }
  94. /**
  95. * Get the number of recipes.
  96. *
  97. * @return
  98. */
  99. public int size() {
  100. return recipes.size();
  101. }
  102. private CauldronCookbook readCauldronRecipes(String path)
  103. throws IOException {
  104. File file = new File("plugins/CraftBookMechanisms", path);
  105. FileReader input = null;
  106. try {
  107. input = new FileReader(file);
  108. BufferedReader buff = new BufferedReader(input);
  109. String line;
  110. while ((line = buff.readLine()) != null) {
  111. line = line.trim();
  112. // Blank lines
  113. if (line.length() == 0) {
  114. continue;
  115. }
  116. // Comment
  117. if (line.charAt(0) == ';' || line.charAt(0) == '#' || line.equals("")) {
  118. continue;
  119. }
  120. String[] parts = line.split(":");
  121. if (parts.length < 3) {
  122. log.log(Level.WARNING, "Invalid cauldron recipe line in "
  123. + file.getName() + ": '" + line + "'");
  124. } else {
  125. String name = parts[0];
  126. List<Integer> ingredients = parseCauldronItems(parts[1]);
  127. List<Integer> results = parseCauldronItems(parts[2]);
  128. String[] groups = null;
  129. if (parts.length >= 4 && parts[3].trim().length() > 0) {
  130. groups = parts[3].split(",");
  131. }
  132. CauldronCookbook.Recipe recipe =
  133. new CauldronCookbook.Recipe(name, ingredients, results, groups);
  134. add(recipe);
  135. }
  136. }
  137. return this;
  138. } finally {
  139. try {
  140. if (input != null) {
  141. input.close();
  142. }
  143. } catch (IOException e) {
  144. }
  145. }
  146. }
  147. /**
  148. * Parse a list of cauldron items.
  149. *
  150. * @param list
  151. * @return
  152. */
  153. private List<Integer> parseCauldronItems(String list) {
  154. String[] parts = list.split(",");
  155. List<Integer> out = new ArrayList<Integer>();
  156. for (String part : parts) {
  157. int multiplier = 1;
  158. try {
  159. // Multiplier
  160. if (part.matches("^.*\\*([0-9]+)$")) {
  161. int at = part.lastIndexOf("*");
  162. multiplier = Integer.parseInt(
  163. part.substring(at + 1, part.length()));
  164. part = part.substring(0, at);
  165. }
  166. try {
  167. for (int i = 0; i < multiplier; i++) {
  168. out.add(Integer.valueOf(part));
  169. }
  170. } catch (NumberFormatException e) {
  171. /*int item = server.getConfiguration().getItemId(part);
  172. if (item > 0) {
  173. for (int i = 0; i < multiplier; i++) {
  174. out.add(item);
  175. }
  176. } else {*/
  177. log.log(Level.WARNING, "Cauldron: Unknown item " + part);
  178. //}
  179. }
  180. } catch (NumberFormatException e) { // Bad multiplier
  181. log.log(Level.WARNING, "Cauldron: Bad multiplier in '" + part + "'");
  182. }
  183. }
  184. return out;
  185. }
  186. /**
  187. *
  188. * @author sk89q
  189. */
  190. public static final class Recipe {
  191. /**
  192. * Recipe name.
  193. */
  194. private final String name;
  195. /**
  196. * Stores a list of ingredients.
  197. */
  198. private final List<Integer> ingredients;
  199. /**
  200. * Stores a list of ingredients.
  201. */
  202. private final Map<Integer,Integer> ingredientLookup
  203. = new HashMap<Integer,Integer>();
  204. /**
  205. * List of resulting items or blocks.
  206. */
  207. private final List<Integer> results;
  208. /**
  209. * List of groups that can use this recipe. This may be null.
  210. */
  211. private final String[] groups;
  212. /**
  213. * Construct the instance. The list will be sorted.
  214. *
  215. * @param name
  216. * @param ingredients
  217. * @param results
  218. * @param groups
  219. */
  220. public Recipe(String name, List<Integer> ingredients,
  221. List<Integer> results, String[] groups) {
  222. this.name = name;
  223. this.ingredients = Collections.unmodifiableList(ingredients);
  224. this.results = Collections.unmodifiableList(results);
  225. this.groups = groups;
  226. // Make a list of required ingredients by item ID
  227. for (Integer id : ingredients) {
  228. if (ingredientLookup.containsKey(id)) {
  229. ingredientLookup.put(id, ingredientLookup.get(id) + 1);
  230. } else {
  231. ingredientLookup.put(id, 1);
  232. }
  233. }
  234. }
  235. /**
  236. * @return the name
  237. */
  238. public String getName() {
  239. return name;
  240. }
  241. /**
  242. * @return the ingredients
  243. */
  244. public List<Integer> getIngredients() {
  245. return ingredients;
  246. }
  247. /**
  248. * @return the groups
  249. */
  250. public String[] getGroups() {
  251. return groups;
  252. }
  253. /**
  254. * Checks to see if all the ingredients are met.
  255. *
  256. * @param check
  257. * @return
  258. */
  259. public boolean hasAllIngredients(Map<Integer,Integer> check) {
  260. for (Map.Entry<Integer,Integer> entry : ingredientLookup.entrySet()) {
  261. int id = entry.getKey();
  262. if (!check.containsKey(id)) {
  263. return false;
  264. } else if (check.get(id) < entry.getValue()) {
  265. return false;
  266. }
  267. }
  268. return true;
  269. }
  270. /**
  271. * @return the results
  272. */
  273. public List<Integer> getResults() {
  274. return results;
  275. }
  276. /**
  277. * Read a file containing cauldron recipes.
  278. *
  279. * @param file
  280. * @return
  281. * @throws IOException
  282. */
  283. }
  284. }