From af6fe7976e09e36079c5ab7f2969f3485dfed90e Mon Sep 17 00:00:00 2001 From: Andrew Miner Date: Sat, 17 Aug 2013 15:31:00 -0700 Subject: [PATCH] Initial version --- crafting.js | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 53 +++++++++++++++ vanilla.json | 79 ++++++++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 crafting.js create mode 100644 index.html create mode 100644 vanilla.json diff --git a/crafting.js b/crafting.js new file mode 100644 index 000000000..9eed17375 --- /dev/null +++ b/crafting.js @@ -0,0 +1,187 @@ +// Constants ////////////////////////////////////////////////////////////////////////////////////////////////////////// + +var FADE_DURATION = 250; // ms +var ERROR_DISPLAY_DURATION = 5000; // ms + +// UI Functions /////////////////////////////////////////////////////////////////////////////////////////////////////// + +function onPageLoad() { + $("#recipe_load_button").click(onRecipeLoadButtonClicked); + $("#crafting_selector").change(onCraftingSelectorChanged); + + loadRecipes("vanilla.json"); +} + +function onCraftingSelectorChanged() { + var recipeName = $("#crafting_selector option:selected").val(); + var recipe = __recipes[recipeName]; + if (recipe === undefined) { + $("#crafting_error").html("Cannot find recipe for " + recipeName); + $("#crafting_error").fadeIn(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).fadeOut(FADE_DURATION); + } else { + var inventory = createManifest(); + var missingMaterials = recipe.computeMissingMaterials(inventory); + $("#missing_materials").html(missingMaterials.toHtml()); + $("#leftover_materials").html(inventory.toHtml()); + $("#crafting_output").fadeIn(FADE_DURATION); + } +} + +function onRecipeLoadButtonClicked() { + loadRecipes($("#recipe_url").val()); +} + +// UI Helper Functions //////////////////////////////////////////////////////////////////////////////////////////////// + +function loadRecipes(recipeUrl) { + $.ajax({ + url: recipeUrl, + dataType: "text", + success: function(data) { + try { + recipeData = $.parseJSON(data)["recipes"]; + __recipes = parseRecipeData(recipeData); + $("#loaded_recipes ul").append("
  • " + recipeUrl + "
  • "); + $("#loaded_recipes").fadeIn(FADE_DURATION); + + updateCraftingSelector(); + $("#crafting").fadeIn(FADE_DURATION); + } catch (e) { + $("#load_error").html(e); + $("#load_error").slideDown(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).slideUp(FADE_DURATION); + } + }, + error: function(response, status, error) { + $("#load_error").html(error); + $("#load_error").slideDown(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).slideUp(FADE_DURATION); + } + }); +} + +function updateCraftingSelector() { + var $selector = $("#crafting_selector"); + if (__recipes.length == 0) { + $selector.attr("disabled", "disabled"); + } else { + for (var name in __recipes) { + if (!__recipes.hasOwnProperty(name)) continue; + $selector.append(""); + } + $selector.removeAttr("disabled"); + } +} + +// Manifest Object //////////////////////////////////////////////////////////////////////////////////////////////////// + +function createManifest() { + var object = {materials: {}}; + + object.add = function(count, name) { + if (object.materials[name] === undefined) { + object.materials[name] = count; + } else { + object.materials[name] = object.materials[name] + count; + } + }; + + object.contains = function(count, name) { + if (object.materials[name] === undefined) return false; + return (object.materials[name] >= count); + }; + + object.remove = function(count, name) { + if (object.materials[name] !== undefined) { + if (object.materials[name] <= count) { + delete object.materials[name] + } else { + object.materials[name] -= count; + } + } + }; + + object.toHtml = function() { + var result = ""; + var count = 0; + for (var name in object.materials) { + result += "
  • " + object.materials[name] + " " + name + "
  • "; + count += 1 + } + + if (count === 0) result = "
  • Nothing
  • "; + return result; + }; + + return object; +} + +// Recipe Object ////////////////////////////////////////////////////////////////////////////////////////////////////// + +function parseRecipeData(recipeData) { + var recipes = {}; + $.each(recipeData, function(i, data) { + var recipe = createRecipe(data); + $.each(recipe.output, function(j, output) { + recipes[output.name] = recipe + }); + }); + return recipes; +} + +function createRecipe(data) { + var object = {output: [], input: [], tools: data.tools}; + + $.each(data.output, function(index, value) { + object.output.push({count: value[0], name: value[1]}); + }); + + $.each(data.input, function(index, value) { + object.input.push({count: value[0], name: value[1]}); + }); + + // Methods //////////////////////////////////////////// + + object.computeMissingMaterials = function(inventory) { + if (inventory === undefined) inventory = createManifest(); + var missingMaterials = createManifest(); + var queue = []; + + function craftItem(ingredient) { + var recipe = __recipes[ingredient.name]; + if (recipe === undefined) { + missingMaterials.add(1, ingredient.name); + ingredient.count -= 1 + } else { + $.each(recipe.input, function(j, childIngredient) { + queue.push({count: childIngredient.count, name: childIngredient.name}); + }); + $.each(recipe.output, function(j, childProduct) { + inventory.add(childProduct.count, childProduct.name); + }); + $.each(recipe.tools, function(j, tool) { + if (! inventory.contains(1, tool)) { + craftItem({count: 1, name: tool}); + } + }); + } + return recipe; + } + + craftItem({count: 1, name: object.output[0].name}); + + while (queue.length > 0) { + var ingredient = queue.shift(); + while (ingredient.count > 0) { + if (inventory.contains(1, ingredient.name)) { + inventory.remove(1, ingredient.name); + ingredient.count -= 1; + } else { + craftItem(ingredient); + } + } + } + + return missingMaterials; + } + + return object; +} diff --git a/index.html b/index.html new file mode 100644 index 000000000..da8e4cbe8 --- /dev/null +++ b/index.html @@ -0,0 +1,53 @@ + + + + + + +
    +

    Recipes

    +

    + + +

    +
    +

    Loaded recipes:

    +
      +
      +

      +
      + +
      +

      Crafting

      + +
      +

      You'll need:

      +
        +

        You'll get:

        +
          +
          +
          +
          + + + + + + + diff --git a/vanilla.json b/vanilla.json new file mode 100644 index 000000000..8b0573d4f --- /dev/null +++ b/vanilla.json @@ -0,0 +1,79 @@ + +{ + "recipes": [ + { + "output": [[1, "Boat"]], + "input": [[5, "Oak Plank"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Crafting Table"]], + "input": [[4, "Oak Plank"]], + "tools": [] + }, { + "output": [[1, "Furnace"]], + "input": [[8, "Cobblestone"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Iron Ingot"]], + "input": [[1, "Iron Ore"], [1, "Furnace Fuel"]], + "tools": ["Furnace"] + }, { + "output": [[1, "Iron Ax"]], + "input": [[3, "Iron Ingot"], [2, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Iron Hoe"]], + "input": [[2, "Iron Ingot"], [2, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Iron Pick"]], + "input": [[3, "Iron Ingot"], [2, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Iron Sword"]], + "input": [[2, "Iron Ingot"], [1, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[4, "Oak Plank"]], + "input": [[1, "Oak Log"]], + "tools": [] + }, { + "output": [[4, "Stick"]], + "input": [[2, "Oak Plank"]], + "tools": [] + }, { + "output": [[1, "Stone Ax"]], + "input": [[3, "Cobblestone"], [2, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Stone Hoe"]], + "input": [[2, "Cobblestone"], [2, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Stone Pick"]], + "input": [[3, "Cobblestone"], [2, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Stone Sword"]], + "input": [[2, "Cobblestone"], [1, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Wooden Ax"]], + "input": [[3, "Oak Plank"], [2, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Wooden Hoe"]], + "input": [[2, "Oak Plank"], [2, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Wooden Pick"]], + "input": [[3, "Oak Plank"], [2, "Stick"]], + "tools": ["Crafting Table"] + }, { + "output": [[1, "Wooden Sword"]], + "input": [[2, "Oak Plank"], [1, "Stick"]], + "tools": ["Crafting Table"] + } + ] +} +