* If a "tool" is also a raw material (e.g., as a "cow" is for producing milk), be sure to add it to the inventory so that it shows up as one of the outputs
282 lines
9.3 KiB
JavaScript
282 lines
9.3 KiB
JavaScript
// Constants //////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var FADE_DURATION = 250; // ms
|
|
var ERROR_DISPLAY_DURATION = 5000; // ms
|
|
|
|
// Global Variables ///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var __recipebooks = [];
|
|
|
|
// UI Functions ///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
$(function() {
|
|
$("#recipebook_load_button").click(onRecipeLoadButtonClicked);
|
|
$("#crafting_selector").change(onCraftingSelectorChanged);
|
|
$("#crafting_count").change(onCraftingSelectorChanged);
|
|
|
|
loadRecipebook("data/vanilla.json", function() {
|
|
loadRecipebook("data/buildcraft.json", function() {
|
|
parseUrlParameters();
|
|
onCraftingSelectorChanged();
|
|
});
|
|
});
|
|
});
|
|
|
|
function onCraftingSelectorChanged() {
|
|
var recipeName = $("#crafting_selector option:selected").val();
|
|
if (recipeName === undefined) return;
|
|
|
|
var recipe = findRecipe(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 count = parseInt($("#crafting_count option:selected").val());
|
|
|
|
var inventory = createManifest();
|
|
var missingMaterials = createManifest();
|
|
for (var i = 0; i < count; i++) {
|
|
recipe.craft(inventory, missingMaterials);
|
|
if (inventory.contains(count, recipeName)) break;
|
|
}
|
|
|
|
$("#missing_materials").html(missingMaterials.toHtml());
|
|
$("#leftover_materials").html(inventory.toHtml());
|
|
$("#crafting_output").fadeIn(FADE_DURATION);
|
|
}
|
|
}
|
|
|
|
function onRecipeLoadButtonClicked() {
|
|
$("#reipebook_load_button").attr("disabled", true);
|
|
loadRecipebook($("#recipebook_url").val(), function() {
|
|
$("#recipebook_url").val("");
|
|
$("#reipebook_load_button").removeAttr("disabled");
|
|
});
|
|
}
|
|
|
|
// UI Helper Functions ////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function loadRecipebook(recipebookUrl, onSuccess) {
|
|
$.ajax({
|
|
url: recipebookUrl,
|
|
dataType: "text",
|
|
success: function(text) {
|
|
try {
|
|
var recipebook = createRecipebook(recipebookUrl, $.parseJSON(text));
|
|
__recipebooks.push(recipebook);
|
|
|
|
recipebook.asTableRow().insertBefore($("#recipebook_table tr").last());
|
|
|
|
updateCraftingSelector();
|
|
$("#crafting").fadeIn(FADE_DURATION);
|
|
|
|
if (onSuccess !== undefined) onSuccess();
|
|
} 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 parseUrlParameters() {
|
|
var quantity = $.url().param('quantity');
|
|
if (quantity !== undefined) {
|
|
$("#crafting_count").val(quantity);
|
|
|
|
if ($("#crafting_count option:selected").val() === undefined) {
|
|
$("#crafting_count").val(1);
|
|
|
|
$("#crafting_error").html("Unsupported quantity: " + quantity);
|
|
$("#crafting_error").fadeIn(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).fadeOut(FADE_DURATION);
|
|
}
|
|
}
|
|
|
|
var recipeName = $.url().param('recipeName');
|
|
if (recipeName !== undefined) {
|
|
$("#crafting_selector").val(recipeName);
|
|
|
|
if ($("#crafting_selector option:selected").val() === undefined) {
|
|
$("#crafting_error").html("Cannot find recipe for " + recipeName);
|
|
$("#crafting_error").fadeIn(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).fadeOut(FADE_DURATION);
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateCraftingSelector() {
|
|
var $selector = $("#crafting_selector");
|
|
$selector.html("");
|
|
|
|
if (__recipebooks.length == 0) {
|
|
$selector.attr("disabled", "disabled");
|
|
$selector.html("<option>No recipes</option>");
|
|
} else {
|
|
$(__recipebooks).each(function(i, recipebook) {
|
|
var $optgroup = $("<optgroup label=\"" + recipebook.name + "\">");
|
|
$selector.append($optgroup);
|
|
|
|
for (var name in recipebook.recipes) {
|
|
$optgroup.append("<option value=\"" + name + "\">" + name + "</option>");
|
|
}
|
|
});
|
|
$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.removeAll = function() {
|
|
object.materials = {};
|
|
}
|
|
|
|
object.toHtml = function() {
|
|
var result = "";
|
|
var count = 0;
|
|
for (var name in object.materials) {
|
|
result += "<li>" + object.materials[name] + " " + name + "</li>";
|
|
count += 1
|
|
}
|
|
|
|
if (count === 0) result = "<li class=\"disabled\">Nothing</li>";
|
|
return result;
|
|
};
|
|
|
|
return object;
|
|
}
|
|
|
|
// Recipe Object //////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
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.craft = function(inventory, missingMaterials) {
|
|
if (inventory === undefined) inventory = createManifest();
|
|
if (missingMaterials === undefined) missingMaterials = createManifest();
|
|
var toCraftManifest = createManifest();
|
|
|
|
function drainCraftingManifest(consumeItems) {
|
|
for (var name in toCraftManifest.materials) {
|
|
var count = toCraftManifest.materials[name];
|
|
var itemRecipe = findRecipe(name);
|
|
|
|
for (var i = 0; i < count; i++) {
|
|
if (inventory.contains(1, name)) {
|
|
if (consumeItems) {
|
|
inventory.remove(1, name);
|
|
}
|
|
} else if (itemRecipe === undefined) {
|
|
missingMaterials.add(1, name);
|
|
if (! consumeItems) {
|
|
inventory.add(1, name);
|
|
}
|
|
} else {
|
|
itemRecipe.craft(inventory, missingMaterials);
|
|
if (consumeItems) {
|
|
inventory.remove(1, name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
toCraftManifest.removeAll();
|
|
}
|
|
|
|
$(object.input).each(function(i, input) {
|
|
for (var j = 0; j < input.count; j++) {
|
|
toCraftManifest.add(1, input.name);
|
|
}
|
|
});
|
|
drainCraftingManifest(true);
|
|
|
|
$(object.tools).each(function(i, tool) {
|
|
if (! inventory.contains(1, tool)) {
|
|
toCraftManifest.add(1, tool);
|
|
}
|
|
});
|
|
drainCraftingManifest(false);
|
|
|
|
$(object.output).each(function(i, output) {
|
|
inventory.add(output.count, output.name);
|
|
});
|
|
};
|
|
|
|
return object;
|
|
}
|
|
|
|
// RecipeBook Object //////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function createRecipebook(sourceUrl, data) {
|
|
var object = {
|
|
name: data.name,
|
|
description: data.description,
|
|
sourceUrl: sourceUrl,
|
|
recipes: {}
|
|
};
|
|
|
|
$(data.recipes).each(function(i, data) {
|
|
var recipe = createRecipe(data);
|
|
$(recipe.output).each(function(j, output) {
|
|
object.recipes[output.name] = recipe
|
|
});
|
|
});
|
|
|
|
object.asTableRow = function() {
|
|
return $(
|
|
"<tr>" +
|
|
"<td width=\"25%\"><a target=\"new\" href=\"" + object.sourceUrl + "\">" + object.name + "</a></td>" +
|
|
"<td width=\"*\">" + object.description + "</td>" +
|
|
"</tr>"
|
|
);
|
|
};
|
|
|
|
return object;
|
|
}
|
|
|
|
function findRecipe(name) {
|
|
for (var i = 0; i < __recipebooks.length; i++) {
|
|
var recipe = __recipebooks[i].recipes[name];
|
|
if (recipe !== undefined) return recipe;
|
|
}
|
|
return undefined;
|
|
}
|
|
|