mh4u: use db data, move to subdir
This commit is contained in:
859
web/mh4u/outfitters.html
Normal file
859
web/mh4u/outfitters.html
Normal file
@@ -0,0 +1,859 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Poogie Outfitters</title>
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/ejs_production.js"></script>
|
||||
|
||||
<script src="js/common.js"></script>
|
||||
|
||||
<style>
|
||||
label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: sans, sans-serif;
|
||||
}
|
||||
|
||||
td.num {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/*@media (max-width: 600) {*/
|
||||
#flexbox {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
var DATA_PATH = get_base_path() + "/jsonapi/";
|
||||
var TYPES = ["Head", "Body", "Arms", "Waist", "Legs"];
|
||||
var GEAR = ["Weapon", "Head", "Body", "Arms", "Waist", "Legs", "Talisman"];
|
||||
var ELEMENTS = ["fire", "water", "thunder", "ice", "dragon"];
|
||||
|
||||
// dict mapping armor name to list containing id
|
||||
var armor_ids = {};
|
||||
|
||||
// dict mapping skill name to object
|
||||
var skill_trees = {};
|
||||
|
||||
// dict mapping skill_tree_id to list of skill dicts, highest point first
|
||||
var tree_skills = {};
|
||||
|
||||
// dict mapping type to armor data, including dummy dict for Weapon and
|
||||
// Talisman (containing "num_slots" and "skills" dicts
|
||||
var armors = {
|
||||
"Talisman": { "skills": {}, "num_slots": 0,
|
||||
"skill_names": [null, null], },
|
||||
"Weapon": { "skills": {}, "num_slots": 0 }
|
||||
};
|
||||
|
||||
var decorations = { "Head": [], "Body": [], "Arms": [],
|
||||
"Waist": [], "Legs": [], "Weapon": [] };
|
||||
var slots_left = {};
|
||||
|
||||
var template_skills = new EJS({ url: "templates/skills.ejs" });
|
||||
var template_resist = new EJS({ url: "templates/resistance.ejs" });
|
||||
var template_decorations = new EJS({ url: "templates/decorations.ejs" });
|
||||
|
||||
$(document).ready(function(){
|
||||
$.getJSON(DATA_PATH + "armor/_index_name.json",
|
||||
function(data) {
|
||||
armor_ids = data;
|
||||
setup_autocomplete();
|
||||
$.getJSON(DATA_PATH + "skilltree/_all.json",
|
||||
function(data) {
|
||||
skill_trees = data;
|
||||
$.getJSON(DATA_PATH +
|
||||
"skill/_index_skill_tree_id.json",
|
||||
function(data) {
|
||||
tree_skills = data;
|
||||
setup_talisman_autocomplete();
|
||||
load_local_storage();
|
||||
});
|
||||
});
|
||||
});
|
||||
$("#armor_table").on("click", "button.add_decoration",
|
||||
function (evt) {
|
||||
add_decoration_by_element(evt.target.id);
|
||||
});
|
||||
$("#armor_table").on("click", "button.remove_decoration",
|
||||
function (evt) {
|
||||
remove_decoration_by_element(evt.target.id);
|
||||
});
|
||||
$("#armor_table").on("click", "button.clear",
|
||||
function (evt) {
|
||||
clear_armor_by_element(evt.target.id);
|
||||
});
|
||||
$("#Weapon_nslots").change(function(evt) {
|
||||
set_slots("Weapon", parseInt($(evt.target).val()));
|
||||
});
|
||||
$("#Talisman_nslots").change(function(evt) {
|
||||
set_slots("Talisman", parseInt($(evt.target).val()));
|
||||
});
|
||||
for (i=1; i<3; i++) {
|
||||
$("#Talisman_skill" + i).on("autocompletechange", { "num": i },
|
||||
function(evt) {
|
||||
set_talisman_skill(evt.data["num"], $(evt.target).val(), 5);
|
||||
});
|
||||
$("#Talisman_points" + i).on("change", { "num": i },
|
||||
function(evt) {
|
||||
set_talisman_skill(evt.data["num"], undefined,
|
||||
parseInt($(evt.target).val()));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function load_local_storage() {
|
||||
_load_slots();
|
||||
_load_talisman_skills();
|
||||
_load_armors(function() {
|
||||
_load_decorations(function() {
|
||||
$.each(GEAR, function(i, type) {
|
||||
display_decorations(type);
|
||||
});
|
||||
display_talisman();
|
||||
display_skills();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function _load_slots() {
|
||||
wslots = localStorage.getItem("weapon_slots");
|
||||
if (wslots != null) {
|
||||
log("loaded weapon slots " + wslots);
|
||||
_reset_slots("Weapon", parseInt(wslots));
|
||||
$("#Weapon_nslots").val(wslots);
|
||||
}
|
||||
|
||||
tslots = localStorage.getItem("talisman_slots");
|
||||
if (tslots != null) {
|
||||
log("loaded talisman slots " + tslots);
|
||||
_reset_slots("Talisman", parseInt(tslots));
|
||||
$("#Talisman_nslots").val(tslots);
|
||||
}
|
||||
}
|
||||
|
||||
function save_talisman_skills() {
|
||||
// save as list of two tuples [name, points]
|
||||
var skills = [];
|
||||
skills_names = armors["Talisman"]["skill_names"];
|
||||
$.each(skill_names, function(i, name) {
|
||||
if (name) {
|
||||
points = armors["Talisman"]["skills"][name];
|
||||
skills.push([name, points]);
|
||||
}
|
||||
});
|
||||
svalue = JSON.stringify(skills);
|
||||
log("saving talisman skills " + svalue);
|
||||
localStorage.setItem("talisman_skills", svalue);
|
||||
}
|
||||
|
||||
function _load_talisman_skills() {
|
||||
var talisman_saved = localStorage.getItem("talisman_skills");
|
||||
if (talisman_saved != null) {
|
||||
log("load talisman skills " + talisman_saved);
|
||||
var talisman_skills = JSON.parse(talisman_saved);
|
||||
$.each(talisman_skills, function(i, name_points) {
|
||||
name = name_points[0];
|
||||
points = name_points[1];
|
||||
set_talisman_skill(i+1, name, points, "nodisplay");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function _load_armors(done_callback) {
|
||||
var armors_saved = localStorage.getItem("armor_names");
|
||||
if (armors_saved != null) {
|
||||
log("load armors " + armors_saved);
|
||||
var armor_names = JSON.parse(armors_saved);
|
||||
var done_count = 0;
|
||||
var total = Object.keys(armor_names).length;
|
||||
log("load armor total " + total);
|
||||
$.each(armor_names, function(type, name) {
|
||||
if (name) {
|
||||
$("#" + type).val(name);
|
||||
set_armor(type, name, "nodisplay", function(type, data) {
|
||||
++done_count;
|
||||
log("load armor " + type + " DONE " + done_count);
|
||||
if (done_count == total) {
|
||||
log("load armor ALL DONE");
|
||||
done_callback();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
++done_count;
|
||||
log("load armor " + type + " DONE " + done_count);
|
||||
if (done_count == total) {
|
||||
log("load armor ALL DONE");
|
||||
done_callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
done_callback();
|
||||
}
|
||||
}
|
||||
|
||||
function _load_decorations(done_callback) {
|
||||
decorations_saved = localStorage.getItem("decoration_name_lists");
|
||||
if (decorations_saved != null) {
|
||||
log("load decorations " + decorations_saved);
|
||||
dname_list_map = JSON.parse(decorations_saved);
|
||||
var types_left = Object.keys(dname_list_map).length;
|
||||
$.each(dname_list_map, function(type, names) {
|
||||
var names_left = names.length;
|
||||
if (names_left == 0) {
|
||||
--types_left;
|
||||
if (types_left == 0) {
|
||||
done_callback();
|
||||
}
|
||||
}
|
||||
$.each(names, function(i, name) {
|
||||
add_decoration(type, name, "nodisplay", function() {
|
||||
--names_left;
|
||||
if (names_left == 0) {
|
||||
--types_left;
|
||||
if (types_left == 0) {
|
||||
done_callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
done_callback();
|
||||
}
|
||||
}
|
||||
|
||||
function add_decoration_by_element(element_id) {
|
||||
parts = element_id.split("_");
|
||||
type = parts[0];
|
||||
value = $("#" + type + "_decoration").val();
|
||||
add_decoration(type, value);
|
||||
}
|
||||
|
||||
function remove_decoration_by_element(element_id) {
|
||||
parts = element_id.split("_");
|
||||
type = parts[0];
|
||||
index = parts[3];
|
||||
remove_decoration(type, index);
|
||||
}
|
||||
|
||||
function setup_decoration_autocomplete(type, max_slots) {
|
||||
options = [];
|
||||
$.each(skill_trees, function(skill_name, stree) {
|
||||
$.each(stree["decoration_values"], function(i, points) {
|
||||
nslots = i + 1;
|
||||
if (nslots <= max_slots && points > 0) {
|
||||
option_name = stree["name"] + " +" + points;
|
||||
options.push(option_name);
|
||||
}
|
||||
});
|
||||
});
|
||||
$("#" + type + "_decoration").autocomplete({ source: options });
|
||||
$("#" + type + "_decoration").keypress(function(e) {
|
||||
if (e.which == 13) {
|
||||
value = $("#" + type + "_decoration").val();
|
||||
add_decoration(type, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function get_value_list(obj_list, obj_key) {
|
||||
values = [];
|
||||
$.each(obj_list, function(key, obj) {
|
||||
values.push(obj[obj_key]);
|
||||
});
|
||||
return values;
|
||||
}
|
||||
|
||||
function save_slots() {
|
||||
if (armors["Weapon"] == undefined) {
|
||||
wslots = 0;
|
||||
} else {
|
||||
wslots = armors["Weapon"]["num_slots"];
|
||||
}
|
||||
localStorage.setItem("weapon_slots", wslots);
|
||||
|
||||
if (armors["Talisman"] == undefined) {
|
||||
tslots = 0;
|
||||
} else {
|
||||
tslots = armors["Talisman"]["num_slots"];
|
||||
}
|
||||
localStorage.setItem("talisman_slots", tslots);
|
||||
}
|
||||
|
||||
function log(msg) {
|
||||
window.console && console.log(msg);
|
||||
}
|
||||
|
||||
function save_armors() {
|
||||
var armor_names = {};
|
||||
$.each(armors, function(type, armor) {
|
||||
if (armor && armor["name"]) {
|
||||
armor_names[type] = armor["name"];
|
||||
}
|
||||
});
|
||||
localStorage.setItem("armor_names", JSON.stringify(armor_names));
|
||||
}
|
||||
|
||||
function save_decorations() {
|
||||
var decoration_name_lists = {};
|
||||
$.each(decorations, function(type, dlist) {
|
||||
if (dlist != undefined) {
|
||||
decoration_name_lists[type] =
|
||||
get_value_list(dlist, "display_name");
|
||||
}
|
||||
});
|
||||
var svalue = JSON.stringify(decoration_name_lists);
|
||||
log("save decorations " + svalue);
|
||||
localStorage.setItem("decoration_name_lists", svalue);
|
||||
}
|
||||
|
||||
function setup_autocomplete() {
|
||||
$.getJSON(DATA_PATH + "armor/_index_slot.json",
|
||||
function(data) {
|
||||
$.each(TYPES,
|
||||
function(i, type) {
|
||||
$("#" + type).autocomplete(
|
||||
{ source: data[type],
|
||||
change: function (event, ui) {
|
||||
set_armor(this.id, ui.item["value"]);
|
||||
}
|
||||
}
|
||||
);
|
||||
$("#" + type).keypress(function(e) {
|
||||
if (e.which == 13) {
|
||||
set_armor(this.id, $("#" + this.id).val());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function setup_talisman_autocomplete() {
|
||||
options = Object.keys(skill_trees);
|
||||
$("#Talisman_skill1").autocomplete({ source: options });
|
||||
$("#Talisman_skill2").autocomplete({ source: options });
|
||||
}
|
||||
|
||||
function get_decoration(display_name, max_slots, ok_fn, fail_fn) {
|
||||
parts = display_name.split(" +");
|
||||
skill = parts[0]
|
||||
points = parts[1]
|
||||
slots = 0;
|
||||
for (i=0; i < 3; i++) {
|
||||
if (skill_trees[skill]["decoration_values"][i] == points) {
|
||||
slots = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (slots > max_slots) {
|
||||
fail_fn(slots);
|
||||
return;
|
||||
}
|
||||
decoration_id = skill_trees[skill]["decoration_ids"][slots-1];
|
||||
$.getJSON(DATA_PATH + "decoration/" + decoration_id + ".json",
|
||||
ok_fn);
|
||||
}
|
||||
|
||||
function add_decoration(type, display_name, nodisplay, done_callback) {
|
||||
log("add_decoration " + type + " " + display_name);
|
||||
get_decoration(display_name, slots_left[type],
|
||||
function (data) {
|
||||
if (! (type in decorations)) {
|
||||
decorations[type] = []
|
||||
}
|
||||
data["display_name"] = display_name;
|
||||
log("adding decoration " + type + " " + display_name);
|
||||
decorations[type].push(data);
|
||||
slots_left[type] -= data["num_slots"];
|
||||
log("add decoration slots left " + type
|
||||
+ " " + slots_left[type]);
|
||||
if (nodisplay == undefined) {
|
||||
save_decorations();
|
||||
display_decorations(type);
|
||||
display_skills();
|
||||
}
|
||||
if (done_callback != undefined) {
|
||||
done_callback(type, data);
|
||||
}
|
||||
},
|
||||
function (slots) {
|
||||
log("not enough slots: have " + slots_left[type]
|
||||
+ " need " + slots);
|
||||
if (done_callback != undefined) {
|
||||
done_callback(type, null);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function remove_decoration(type, index, nodisplay) {
|
||||
d = decorations[type][index];
|
||||
slots_left[type] += d["num_slots"];
|
||||
decorations[type].splice(index, 1);
|
||||
if (nodisplay == undefined) {
|
||||
save_decorations();
|
||||
display_decorations(type);
|
||||
display_skills();
|
||||
}
|
||||
}
|
||||
|
||||
function copy(data) {
|
||||
return JSON.parse(JSON.stringify(data));
|
||||
}
|
||||
|
||||
function set_slots(type, value) {
|
||||
if (typeof value != "number") {
|
||||
log("bad slots value: " + typeof value + " " + value);
|
||||
return;
|
||||
}
|
||||
log("set slots " + type + " " + value);
|
||||
_reset_slots(type, value);
|
||||
save_slots();
|
||||
save_decorations();
|
||||
display_decorations(type);
|
||||
display_skills();
|
||||
}
|
||||
|
||||
function _reset_slots(type, value) {
|
||||
old_armor = armors[type] || { "num_slots": 0 };
|
||||
old_num_slots = old_armor["num_slots"];
|
||||
old_slots_left = slots_left[type] || 0;
|
||||
old_slots_used = old_num_slots - old_slots_left;
|
||||
|
||||
log("_reset_slots slots " + type + " " + value
|
||||
+ " " + old_num_slots + " (" + old_slots_used + ") "
|
||||
+ old_slots_left);
|
||||
|
||||
if (type == "Weapon" || type == "Talisman") {
|
||||
if (armors[type] == undefined) {
|
||||
armors[type] = { "num_slots": value, "skills": {} };
|
||||
} else {
|
||||
armors[type]["num_slots"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
slots_left[type] = value - old_slots_used;
|
||||
while (slots_left[type] < 0) {
|
||||
idx = decorations[type].length - 1;
|
||||
remove_decoration(type, idx, "noupdate");
|
||||
}
|
||||
}
|
||||
|
||||
function clear_armor_by_element(eid) {
|
||||
parts = eid.split("_");
|
||||
type = parts[0];
|
||||
if (type == "Talisman") {
|
||||
skill_num = parseInt(parts[1].charAt(parts[1].length - 1));
|
||||
set_talisman_skill(skill_num, "", 0);
|
||||
display_talisman();
|
||||
} else {
|
||||
$("#" + type).val("");
|
||||
set_armor(type, "");
|
||||
}
|
||||
}
|
||||
|
||||
function set_armor(type, name, nodisplay, done_fn) {
|
||||
log("set_armor " + type + " " + name);
|
||||
if (name.length == 0) {
|
||||
_reset_slots(type, 0);
|
||||
delete armors[type];
|
||||
$("#" + type + "_skills").html("");
|
||||
$("#" + type + "_row").attr("title", "");
|
||||
$("#" + type + "_def").html("");
|
||||
if (nodisplay == undefined) {
|
||||
save_armors();
|
||||
save_decorations();
|
||||
display_decorations(type);
|
||||
display_skills();
|
||||
}
|
||||
if (done_fn != undefined) {
|
||||
done_fn(type, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
armor_id = armor_ids[name][0];
|
||||
$.getJSON(DATA_PATH + "armor/" + armor_id + ".json",
|
||||
function(data) {
|
||||
_reset_slots(type, data["num_slots"]);
|
||||
armors[type] = data;
|
||||
var skill_names = Object.keys(data["skills"]);
|
||||
skill_names.sort();
|
||||
var slist = "";
|
||||
$.each(skill_names, function(i, sname) {
|
||||
if (i != 0) {
|
||||
slist += ", ";
|
||||
}
|
||||
slist += sname + " " + data["skills"][sname];
|
||||
});
|
||||
$("#" + type + "_skills").html(slist);
|
||||
if (nodisplay == undefined) {
|
||||
save_armors();
|
||||
save_decorations();
|
||||
display_decorations(type);
|
||||
display_skills();
|
||||
}
|
||||
if (done_fn != undefined) {
|
||||
done_fn(type, data);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function set_talisman_skill(n, name, value, nodisplay) {
|
||||
log("set_talisman_skill " + n + " " + name + " " + value);
|
||||
idx = n - 1;
|
||||
|
||||
if (name == undefined) {
|
||||
name = armors["Talisman"]["skill_names"][idx];
|
||||
} else {
|
||||
old_name = armors["Talisman"]["skill_names"][idx];
|
||||
if (old_name) {
|
||||
delete armors["Talisman"]["skills"][old_name];
|
||||
}
|
||||
}
|
||||
|
||||
if (name) {
|
||||
armors["Talisman"]["skills"][name] = value;
|
||||
}
|
||||
armors["Talisman"]["skill_names"][idx] = name;
|
||||
|
||||
if (nodisplay == undefined) {
|
||||
save_talisman_skills();
|
||||
display_talisman();
|
||||
display_skills();
|
||||
}
|
||||
}
|
||||
|
||||
function display_talisman() {
|
||||
skill_names = armors["Talisman"]["skill_names"];
|
||||
for(i=1; i<3; i++) {
|
||||
skill = skill_names[i-1];
|
||||
if (skill) {
|
||||
points = armors["Talisman"]["skills"][skill];
|
||||
$("#Talisman_skill" + i).val(skill);
|
||||
$("#Talisman_points" + i).val(points);
|
||||
$("#Talisman_points" + i).removeAttr("disabled");
|
||||
} else {
|
||||
$("#Talisman_skill" + i).val("");
|
||||
$("#Talisman_points" + i).val("");
|
||||
$("#Talisman_points" + i).attr("disabled", "disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function display_decorations(type) {
|
||||
var free_slots = slots_left[type];
|
||||
var slots_html = template_decorations.render(
|
||||
{ decorations: decorations[type] || [],
|
||||
free_slots: free_slots,
|
||||
type: type });
|
||||
log("display_decorations " + type + " free_slots " + free_slots);
|
||||
$("#" + type + "_slots").html(slots_html);
|
||||
if (free_slots > 0) {
|
||||
setup_decoration_autocomplete(type, free_slots);
|
||||
}
|
||||
}
|
||||
|
||||
function display_skills() {
|
||||
// map of skill name to total
|
||||
var skills = {};
|
||||
|
||||
// map of type to dict map of skill name to total including decoration
|
||||
var tskills_by_type = {};
|
||||
|
||||
// map of type to dict map of skill name to total from decorations only
|
||||
var dskills_by_type = {};
|
||||
|
||||
var element_resist = {};
|
||||
var slots = 0;
|
||||
var slots_free = 0;
|
||||
var total_defense = 0;
|
||||
var total_max_defense = 0;
|
||||
|
||||
// map of component name to count
|
||||
var components = {};
|
||||
|
||||
$.each(GEAR, function(i, type) {
|
||||
var gear_decorations = {};
|
||||
var armor_skills = {};
|
||||
var armor = armors[type];
|
||||
if (armor == undefined) {
|
||||
armor = { "skills": [], "num_slots": 0 };
|
||||
} else if (type != "Weapon" && type != "Talisman") {
|
||||
total_defense += armor["defense"];
|
||||
total_max_defense += armor["max_defense"];
|
||||
$("#" + type + "_def").html("" + armor["defense"]);
|
||||
$("#" + type + "_def").attr("title", "Max:"
|
||||
+ armor["max_defense"]);
|
||||
|
||||
var comps_txt = get_object_as_text(armor["create_components"]);
|
||||
$("#" + type + "_row").attr("title", comps_txt);
|
||||
object_add_values(components, armor["create_components"]);
|
||||
}
|
||||
if (decorations[type] == undefined) {
|
||||
decorations[type] = [];
|
||||
}
|
||||
dskills_by_type[type] = {};
|
||||
tskills_by_type[type] = {};
|
||||
if (armor["skills"]["Torso Up"] == 1) {
|
||||
if (armors["Body"]) {
|
||||
armor_skills = armors["Body"]["skills"];
|
||||
gear_decorations = decorations["Body"];
|
||||
} else {
|
||||
armor_skills = {};
|
||||
gear_decorations = {};
|
||||
}
|
||||
} else {
|
||||
armor_skills = armor["skills"];
|
||||
gear_decorations = decorations[type];
|
||||
}
|
||||
|
||||
// add armor skills
|
||||
object_add_values(skills, armor_skills);
|
||||
object_add_values(tskills_by_type[type], armor_skills);
|
||||
|
||||
// add decoration skills
|
||||
$.each(gear_decorations, function(i, decoration) {
|
||||
object_add_values(skills, decoration["skills"]);
|
||||
object_add_values(dskills_by_type[type], decoration["skills"]);
|
||||
object_add_values(tskills_by_type[type], decoration["skills"]);
|
||||
});
|
||||
$.each(ELEMENTS, function(i, element) {
|
||||
key = element + "_res";
|
||||
if (armor[key] == undefined) {
|
||||
armor[key] = 0;
|
||||
}
|
||||
if (! (element in element_resist)) {
|
||||
element_resist[element] = 0;
|
||||
}
|
||||
element_resist[element] += armor[key];
|
||||
$("#" + type + "_" + element).html(armor[key]);
|
||||
});
|
||||
slots += armor["num_slots"];
|
||||
slots_free += slots_left[type] || 0;
|
||||
//$("#" + type + "_slots").html(armor["num_slots"]);
|
||||
});
|
||||
$("#Total_slots").html((slots - slots_free)
|
||||
+ " used / " + slots + " slots");
|
||||
$("#Total_def").html("" + total_defense);
|
||||
$("#Total_def").prop("title", "Max:" + total_max_defense);
|
||||
|
||||
var comps_txt = get_object_as_text(components);
|
||||
$("#Total_row").attr("title", comps_txt);
|
||||
|
||||
var skill_names = Object.keys(skills);
|
||||
skill_names.sort(function(a, b) {
|
||||
sa = skills[a] ? skills[a] : 0;
|
||||
sb = skills[b] ? skills[b] : 0;
|
||||
return sb - sa;
|
||||
});
|
||||
|
||||
var active_skills = {}
|
||||
var skill_res = {}
|
||||
$.each(skills, function(tree_name, total_points) {
|
||||
var skill_tree_id = skill_trees[tree_name]["id"];
|
||||
var current_tree_skills = tree_skills[skill_tree_id] || [];
|
||||
var found = 0; // 1 or -1 for plus/minus
|
||||
for (i=0; i<current_tree_skills.length; i++) {
|
||||
var skill = current_tree_skills[i];
|
||||
required_points = skill["required_skill_tree_points"];
|
||||
if (total_points > 0) {
|
||||
if (total_points >= required_points && required_points > 0) {
|
||||
active_skills[tree_name] = skill;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
} else if (total_points < 0) {
|
||||
if (total_points <= required_points && required_points < 0) {
|
||||
active_skills[tree_name] = skill;
|
||||
found = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found != 0) {
|
||||
var element_res = parse_element_res_skill(skill["name"]);
|
||||
if (element_res) {
|
||||
skill_res[element_res[0]] = element_res[1];
|
||||
element_resist[element] += element_res[1];
|
||||
}
|
||||
var defense_skill = parse_defense_skill(skill["name"]);
|
||||
if (defense_skill && defense_skill[0] == "Up") {
|
||||
total_defense2 = get_defense_up(total_defense,
|
||||
defense_skill[1]);
|
||||
total_max_defense2 = get_defense_up(total_max_defense,
|
||||
defense_skill[1]);
|
||||
$("#Total_def").prop("title",
|
||||
"Max:" + total_max_defense
|
||||
+ " (" + total_max_defense2
|
||||
+ " with armor skill)");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var skills_table = template_skills.render(
|
||||
{ TYPES: GEAR,
|
||||
skills: skills,
|
||||
dskills_by_type: dskills_by_type,
|
||||
tskills_by_type: tskills_by_type,
|
||||
skill_names: skill_names,
|
||||
active_skills: active_skills,
|
||||
armors: armors });
|
||||
$("#skills_div").html(skills_table);
|
||||
|
||||
var resist_table = template_resist.render(
|
||||
{ TYPES: TYPES,
|
||||
ELEMENTS: ELEMENTS,
|
||||
armors: armors,
|
||||
skill_res: skill_res,
|
||||
element_resist: element_resist });
|
||||
$("#resist_div").html(resist_table);
|
||||
}
|
||||
|
||||
function parse_element_res_skill(skill_name) {
|
||||
parts = skill_name.split(" ");
|
||||
//console.log("skill parts: " + JSON.stringify(parts));
|
||||
if (parts.length != 3) {
|
||||
return null;
|
||||
}
|
||||
if (parts[1] != "Res") {
|
||||
return null;
|
||||
}
|
||||
element = parts[0].toLowerCase();
|
||||
amount = parseInt(parts[2]);
|
||||
return [element, amount];
|
||||
}
|
||||
|
||||
function parse_defense_skill(skill_name) {
|
||||
// Return [Up|Down, (S, M, L, or XL)] if defense skill, null otherwise
|
||||
parts = skill_name.split(" ");
|
||||
//console.log("skill parts: " + JSON.stringify(parts));
|
||||
if (parts.length != 3) {
|
||||
return null;
|
||||
}
|
||||
if (parts[0] != "Defense") {
|
||||
return null;
|
||||
}
|
||||
level = parts[2].substring(1, parts[2].length - 1);
|
||||
console.log("defense skill: " + parts[1] + " " + level);
|
||||
return [parts[1], level];
|
||||
}
|
||||
|
||||
function get_defense_up(defense, skill_level) {
|
||||
switch (skill_level) {
|
||||
case "S":
|
||||
defense = defense + 15;
|
||||
break;
|
||||
case "M":
|
||||
defense = Math.floor(defense * 1.03) + 20;
|
||||
break;
|
||||
case "L":
|
||||
defense = Math.floor(defense * 1.05) + 25;
|
||||
break;
|
||||
case "XL":
|
||||
defense = Math.floor(defense * 1.08) + 30;
|
||||
break;
|
||||
}
|
||||
return defense;
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<table id="armor_table" cellpadding="2" cellspacing="2">
|
||||
<tr id="Weapon_row">
|
||||
<td><label for="Weapon">Weapon:</label></td>
|
||||
<td><input id="Weapon_nslots" type="number" value="0" min="0" max="3" /> slots</td>
|
||||
<td id="Weapon_slots"> </td>
|
||||
<td id="Weapon_def"> </td>
|
||||
<td id="Weapon_skills"> </td>
|
||||
</tr>
|
||||
<tr id="Head_row">
|
||||
<td><label for="Head">Head:</label></td>
|
||||
<td><input id="Head" type="text" size="15" />
|
||||
<button id="Head_clear" class="clear">X</button></td>
|
||||
<td id="Head_slots"> </td>
|
||||
<td class="num" id="Head_def"> </td>
|
||||
<td id="Head_skills"> </td>
|
||||
</tr>
|
||||
<tr id="Body_row">
|
||||
<td><label for="Body">Body:</label></td>
|
||||
<td><input id="Body" type="text" size="15" />
|
||||
<button id="Body_clear" class="clear">X</button></td>
|
||||
<td id="Body_slots"> </td>
|
||||
<td class="num" id="Body_def"> </td>
|
||||
<td id="Body_skills"> </td>
|
||||
</tr>
|
||||
<tr id="Arms_row">
|
||||
<td><label for="Arms">Arms:</label></td>
|
||||
<td><input id="Arms" type="text" size="15" />
|
||||
<button id="Arms_clear" class="clear">X</button></td>
|
||||
<td id="Arms_slots"> </td>
|
||||
<td class="num" id="Arms_def"> </td>
|
||||
<td id="Arms_skills"> </td>
|
||||
</tr>
|
||||
<tr id="Waist_row">
|
||||
<td><label for="Waist">Waist:</label></td>
|
||||
<td><input id="Waist" type="text" size="15" />
|
||||
<button id="Waist_clear" class="clear">X</button></td>
|
||||
<td id="Waist_slots"> </td>
|
||||
<td class="num" id="Waist_def"> </td>
|
||||
<td id="Waist_skills"> </td>
|
||||
</tr>
|
||||
<tr id="Legs_row">
|
||||
<td><label for="Legs">Legs:</label></td>
|
||||
<td><input id="Legs" type="text" size="15" />
|
||||
<button id="Legs_clear" class="clear">X</button></td>
|
||||
<td id="Legs_slots"> </td>
|
||||
<td class="num" id="Legs_def"> </td>
|
||||
<td id="Legs_skills"> </td>
|
||||
</tr>
|
||||
<tr id="Talisman_row">
|
||||
<td><label for="Talisman">Talisman:</label></td>
|
||||
<td><input id="Talisman_skill1" type="text" size="15" />
|
||||
<input id="Talisman_points1" type="number" min="1" max="14" />
|
||||
<button id="Talisman_skill1_clear" class="clear">X</button>
|
||||
<br />
|
||||
<input id="Talisman_skill2" type="text" size="15" />
|
||||
<input id="Talisman_points2" type="number" min="1" max="14" />
|
||||
<button id="Talisman_skill2_clear" class="clear">X</button>
|
||||
<br />
|
||||
<input id="Talisman_nslots" type="number" value="0" min="0" max="3" />
|
||||
slots</td>
|
||||
<td id="Talisman_slots"> </td>
|
||||
<td class="num" id="Talisman_def"> </td>
|
||||
<td id="Talisman_skills"> </td>
|
||||
</tr>
|
||||
<tr id="Total_row">
|
||||
<th> </th>
|
||||
<td> </td>
|
||||
<td id="Total_slots">0</td>
|
||||
<td class="num" id="Total_def"> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="flexbox">
|
||||
<fieldset>
|
||||
<legend>Skills</legend>
|
||||
<div id="skills_div"></div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Elemental Resistance</legend>
|
||||
<div id="resist_div"></div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</body>
|
||||
</body>
|
||||
106
web/mh4u/recommends.html
Normal file
106
web/mh4u/recommends.html
Normal file
@@ -0,0 +1,106 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Poogie Recommends (4U)</title>
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
|
||||
|
||||
<script src="/js/common.js"></script>
|
||||
|
||||
<style>
|
||||
.flex {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
font-family: sans, sans-serif;
|
||||
}
|
||||
|
||||
#output { flex: 99 1 auto; }
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
var DATA_PATH = get_base_path() + "/rewards/";
|
||||
|
||||
$(document).ready(function(){
|
||||
$("#search").click(update_search);
|
||||
$("#item").keypress(function(e) {
|
||||
if (e.which == 13) { update_search(); }
|
||||
});
|
||||
setup_item_autocomplete("#item");
|
||||
var item_name = $.QueryString["item"];
|
||||
if (item_name) {
|
||||
console.log("qs item: " + item_name);
|
||||
if (history.state && history.state["item_name"]) {
|
||||
item_name = history.state["item_name"];
|
||||
console.log("override qs with state item: " + item_name);
|
||||
}
|
||||
var normalized_name = normalize_name(item_name);
|
||||
var encoded_name = encodeURIComponent(normalized_name);
|
||||
display_item(normalized_name);
|
||||
console.log("replaceState: " + normalized_name);
|
||||
window.history.replaceState({ "item_name": normalized_name }, "",
|
||||
"/mh4u/recommends.html?item="
|
||||
+ encoded_name );
|
||||
}
|
||||
$(window).on("popstate", function(e) {
|
||||
var oe = e.originalEvent;
|
||||
if (oe.state !== null) {
|
||||
console.log("popState:" + JSON.stringify(oe.state));
|
||||
display_item(oe.state["item_name"]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function update_search() {
|
||||
// update the item search based on the text field, and also push
|
||||
// the state to history
|
||||
var item_name = $.trim($("#item").val());
|
||||
var normalized_name = normalize_name(item_name);
|
||||
if (window.history.state
|
||||
&& window.history.state["item_name"] == normalized_name) {
|
||||
console.log("item not changed, skipping update");
|
||||
return;
|
||||
}
|
||||
var encoded_name = encodeURIComponent(normalized_name);
|
||||
display_item(normalized_name);
|
||||
console.log("pushState: " + normalized_name);
|
||||
window.history.pushState({ "item_name": normalized_name }, "",
|
||||
"/mh4u/recommends.html?item=" + encoded_name );
|
||||
}
|
||||
|
||||
function display_item(normalized_name) {
|
||||
// display the exact item name if available; does not push state
|
||||
$("#item").val(normalized_name);
|
||||
var encoded_name = encodeURIComponent(normalized_name);
|
||||
|
||||
$.get(DATA_PATH + encoded_name + ".txt",
|
||||
function(data) {
|
||||
$("#output").text(data);
|
||||
}).fail(
|
||||
function() {
|
||||
$("#output").text("Error: item '"
|
||||
+ normalized_name + "' not found");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex">
|
||||
<div>
|
||||
<label for="item">Item:</label>
|
||||
<input id="item" type="text" size="20" />
|
||||
<button id="search">Ask Poogie</button>
|
||||
<a href="https://github.com/bd4/monster-hunter-scripts/blob/master/RECOMMENDATIONS.adoc">Understanding Results</a>
|
||||
(<a href="https://github.com/bd4/monster-hunter-scripts">source</a>)
|
||||
</div>
|
||||
<br />
|
||||
<textarea readonly="true" rows="10" cols="80" id="output"></textarea>
|
||||
</div>
|
||||
</body>
|
||||
452
web/mh4u/weaponlist.html
Normal file
452
web/mh4u/weaponlist.html
Normal file
@@ -0,0 +1,452 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Poogie's Weapon List (MH4U)</title>
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../js/ejs_production.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../js/common.js"></script>
|
||||
|
||||
<style>
|
||||
label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: sans, sans-serif;
|
||||
}
|
||||
|
||||
td.plus {
|
||||
background-color: LightCyan;
|
||||
}
|
||||
|
||||
td.minus {
|
||||
background-color: LightPink;
|
||||
}
|
||||
|
||||
td.num {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/*@media (max-width: 600) {*/
|
||||
.flexbox {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.sharpness-bar {
|
||||
border: 1px #a9a9a9 solid;
|
||||
min-width: 82px;
|
||||
height: 10px;
|
||||
background-color: #a9a9a9;
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.sharpness-bar span {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.sharpness-bar .red {
|
||||
background-color: #C00C38 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .orange {
|
||||
background-color: #E85018 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .yellow {
|
||||
background-color: #F0C830 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .green {
|
||||
background-color: #58D000 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .blue {
|
||||
background-color: #3068E8 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .white {
|
||||
background-color: #F0F0F0 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .purple {
|
||||
background-color: #c3c !important;
|
||||
}
|
||||
|
||||
#sharpness_popup {
|
||||
position: absolute;
|
||||
display: none;
|
||||
border: 1px solid;
|
||||
background: rgba(204, 204, 204, 0.9);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
#cp_div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
var WEAPON_LIST = null;
|
||||
var HORN_MELODY_MAP = null;
|
||||
|
||||
$.ajax({
|
||||
url: "../jsonapi/mh4u/weapon/_all.json",
|
||||
async: false,
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
WEAPON_LIST = data;
|
||||
console.log("weapon count " + WEAPON_LIST.length);
|
||||
}
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: "../jsonapi/mh4u/horn_melody/_index_notes.json",
|
||||
async: false,
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
HORN_MELODY_MAP = data;
|
||||
}
|
||||
});
|
||||
|
||||
var template_row = new EJS({ url: "../templates/weaponrow.ejs" });
|
||||
|
||||
$(document).ready(function(){
|
||||
init_page();
|
||||
|
||||
$("#sharpness_popup").on("click", function(evt) {
|
||||
$(this).html("").offset({top:0, left:0}).hide();
|
||||
});
|
||||
|
||||
$("#weapon_table").on("click", "#sharpness_td", function(evt) {
|
||||
var td_obj = $(evt.currentTarget);
|
||||
var offset = td_obj.offset();
|
||||
var sharpness = td_obj.data("sharpness");
|
||||
$("#sharpness_popup").html(sharpness).offset(offset).show();
|
||||
});
|
||||
});
|
||||
|
||||
function init_page() {
|
||||
var qs = load_qs();
|
||||
$(window).on("popstate", function(e) {
|
||||
var oe = e.originalEvent;
|
||||
if (oe.state !== null) {
|
||||
console.log("popState:" + JSON.stringify(oe.state));
|
||||
update_weapon_list(oe.state);
|
||||
}
|
||||
});
|
||||
$("#search").click(function(evt) {
|
||||
var state = get_ui_state();
|
||||
save_state(state);
|
||||
update_weapon_list(state);
|
||||
});
|
||||
|
||||
if (qs) {
|
||||
update_weapon_list(qs);
|
||||
}
|
||||
}
|
||||
|
||||
function load_qs() {
|
||||
if ($.QueryString["weapon_type"]) {
|
||||
load_state($.QueryString);
|
||||
return $.QueryString;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function get_ui_state() {
|
||||
return { "weapon_type": $("#weapon_type").val(),
|
||||
"weapon_element": $("#weapon_element").val(),
|
||||
"weapon_final": $("#weapon_final").is(":checked"),
|
||||
"weapon_name_text": $("#weapon_name_text").val(),
|
||||
"weapon_component_text": $("#weapon_component_text").val(),
|
||||
"village_stars": $("#village_stars").val(),
|
||||
"guild_stars": $("#guild_stars").val(),
|
||||
"arena_stars": $("#arena_stars").val() };
|
||||
}
|
||||
|
||||
function load_state(state) {
|
||||
$("#weapon_type").val(state["weapon_type"]);
|
||||
$("#weapon_element").val(state["weapon_element"]);
|
||||
final = state["weapon_final"];
|
||||
if (typeof final == "string") {
|
||||
final = final.toLowerCase();
|
||||
state["weapon_final"] = (final == "true" || final == "1");
|
||||
}
|
||||
$("#weapon_final").prop("checked", state["weapon_final"]);
|
||||
$("#weapon_name_text").val(state["weapon_name_text"]);
|
||||
$("#weapon_component_text").val(state["weapon_component_text"]);
|
||||
$("#village_stars").val(state["village_stars"] || "Any");
|
||||
$("#guild_stars").val(state["guild_stars"] || "Any");
|
||||
$("#arena_stars").val(state["arena_stars"] || "Any");
|
||||
}
|
||||
|
||||
function save_state(state, replace) {
|
||||
var url = "weaponlist.html?" + encode_qs(state);
|
||||
if (replace) {
|
||||
window.history.replaceState(state, "", url);
|
||||
} else {
|
||||
window.history.pushState(state, "", url);
|
||||
}
|
||||
}
|
||||
|
||||
function match_stars(match_value, weapon_value) {
|
||||
// NOTE: a null weapon_value can be not available, or no data
|
||||
// available (should probably fix this)
|
||||
if (match_value == "Any" || match_value == ""
|
||||
|| match_value == undefined || match_value == null) {
|
||||
return true;
|
||||
}
|
||||
if (match_value == "None") {
|
||||
// for None, allow null values, because null can be no requirements
|
||||
// or no data available
|
||||
if (weapon_value != null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// if matching a specific value, require a non-null weapon value
|
||||
if (weapon_value == null) {
|
||||
return false;
|
||||
}
|
||||
match_value = parseInt(match_value);
|
||||
if (weapon_value > match_value) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function weapon_predicate(state, weapon_data) {
|
||||
var weapon_type = state["weapon_type"];
|
||||
var weapon_element = state["weapon_element"];
|
||||
var final_only = state["weapon_final"];
|
||||
var weapon_names = state["weapon_name_text"].split("|");
|
||||
var village_stars = state["village_stars"];
|
||||
var guild_stars = state["guild_stars"];
|
||||
var arena_stars = state["arena_stars"];
|
||||
|
||||
// do this first to simplify debugging specific weapons that aren't
|
||||
// matching when they should via breakpoints
|
||||
if (weapon_names && !list_match(weapon_names, [weapon_data["name"]])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// allow satisfying quest filter with village or guild, since they
|
||||
// involve essentially the same quests, rewards, and monsters,
|
||||
// but if permit or arena filters are set, they must be satisfied
|
||||
// independently
|
||||
if (! match_stars(village_stars, weapon_data["village_stars"])
|
||||
&& ! match_stars(guild_stars, weapon_data["guild_stars"])) {
|
||||
return false;
|
||||
}
|
||||
if (! match_stars(arena_stars, weapon_data["arena_stars"])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (final_only && weapon_data["final"] != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (weapon_type != "All" && weapon_type != weapon_data["wtype"]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (weapon_element != "All"
|
||||
&& weapon_element != weapon_data["element"]
|
||||
&& weapon_element != weapon_data["element_2"]
|
||||
&& weapon_element != weapon_data["awaken"]
|
||||
&& weapon_element != weapon_data["phial"]) {
|
||||
if (weapon_element != "None"
|
||||
|| (weapon_data["element"] != null && weapon_data["element"] != "")
|
||||
|| (weapon_data["awaken"] != null && weapon_data["awaken"] != "")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function list_match(needles, string_list) {
|
||||
var found = false;
|
||||
for (var i=0; i<string_list.length; i++) {
|
||||
for (var j=0; j<needles.length; j++) {
|
||||
if (string_list[i].search(needles[j]) >= 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
function update_weapon_list(state) {
|
||||
var comps = state["weapon_component_text"];
|
||||
if (comps) {
|
||||
comps = comps.split("|");
|
||||
}
|
||||
var match_count = 0;
|
||||
console.log("updating weapon list: " + JSON.stringify(state));
|
||||
var results = [];
|
||||
$.each(WEAPON_LIST, function(i, weapon_data) {
|
||||
if (weapon_predicate(state, weapon_data)) {
|
||||
if (comps
|
||||
&& !list_match(comps,
|
||||
Object.keys(data["create_components"]))
|
||||
&& !list_match(comps,
|
||||
Object.keys(data["upgrade_components"])))
|
||||
{
|
||||
console.log("skipping '" + data["name"]
|
||||
+ "', failed component match");
|
||||
return;
|
||||
}
|
||||
weapon_data["id"] = i;
|
||||
weapon_data["sharpness_width"] = 1;
|
||||
weapon_data["sharpness_plus2"] = null;
|
||||
weapon_data["url"] = "weaponplanner.html?weapon="
|
||||
+ encodeURIComponent(weapon_data["name"]);
|
||||
weapon_data["bug_type"] = null;
|
||||
weapon_data["arc_type"] = null;
|
||||
match_count += 1;
|
||||
set_sharpness_titles(weapon_data);
|
||||
set_bow_values(weapon_data);
|
||||
set_horn_melodies_title(weapon_data, HORN_MELODY_MAP);
|
||||
weapon_data["wtype_short"] =
|
||||
WEAPON_TYPE_ABBR[weapon_data["wtype"]];
|
||||
weapon_data["ELEMENT_ABBR"] = ELEMENT_ABBR;
|
||||
var html = template_row.render(weapon_data);
|
||||
results.push([weapon_data, html]);
|
||||
}
|
||||
});
|
||||
results.sort(function (a, b) {
|
||||
avals = get_weapon_sort_values(a[0]);
|
||||
bvals = get_weapon_sort_values(b[0]);
|
||||
return cmp_arrays(bvals, avals);
|
||||
});
|
||||
$("#weapon_table").empty();
|
||||
$.each(results, function(i, pair) {
|
||||
$("#weapon_table").append(pair[1]);
|
||||
});
|
||||
console.log("match count: " + match_count);
|
||||
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="weapon_type"
|
||||
title="Only show weapons of this type"
|
||||
>Type:</label></td>
|
||||
<td><select id="weapon_type">
|
||||
<option value="All">All</option>
|
||||
<option value="Great Sword">Great Sword</option>
|
||||
<option value="Long Sword">Long Sword</option>
|
||||
<option value="Sword and Shield">Sword and Shield</option>
|
||||
<option value="Dual Blades">Dual Blades</option>
|
||||
<option value="Hammer">Hammer</option>
|
||||
<option value="Hunting Horn">Hunting Horn</option>
|
||||
<option value="Lance">Lance</option>
|
||||
<option value="Gunlance">Gunlance</option>
|
||||
<option value="Switch Axe">Switch Axe</option>
|
||||
<option value="Charge Blade">Charge Blade</option>
|
||||
<option value="Insect Glaive">Insect Glaive</option>
|
||||
<!--option value="Light Bowgun">Light Bowgun</option-->
|
||||
<!--option value="Heavy Bowgun">Heavy Bowgun</option-->
|
||||
<option value="Bow">Bow</option>
|
||||
</select></td>
|
||||
<td><label for="weapon_element"
|
||||
title="Only show weapons with this element (native or requiring awaken)"
|
||||
>Element:</label></td>
|
||||
<td><select id="weapon_element">
|
||||
<option value="All">All</option>
|
||||
<option value="None">None</option>
|
||||
<option value="Fire">Fire</option>
|
||||
<option value="Water">Water</option>
|
||||
<option value="Thunder">Thunder</option>
|
||||
<option value="Ice">Ice</option>
|
||||
<option value="Dragon">Dragon</option>
|
||||
<option value="Poison">Poison</option>
|
||||
<option value="Paralysis">Paralysis</option>
|
||||
<option value="Sleep">Sleep</option>
|
||||
<option value="Blastblight">Blast</option>
|
||||
</select></td>
|
||||
<td><label for="weapon_final"
|
||||
title="Only show weapons with no furthur upgrades"
|
||||
>Final?</label></td>
|
||||
<td><input id="weapon_final" type="checkbox" /></td>
|
||||
<td><button id="search">Search</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<label>Quest Level:</label>
|
||||
<select id="village_stars">
|
||||
<option value="Any">Village Any</option>
|
||||
<option value="1">Village 1*</option>
|
||||
<option value="2">Village 2*</option>
|
||||
<option value="3">Village 3*</option>
|
||||
<option value="4">Village 4*</option>
|
||||
<option value="5">Village 5*</option>
|
||||
<option value="6">Village 6*</option>
|
||||
<option value="7">Village 7*</option>
|
||||
<option value="8">Village 8*</option>
|
||||
<option value="9">Village 9*</option>
|
||||
<option value="10">Village 10*</option>
|
||||
</select>
|
||||
<select id="guild_stars">
|
||||
<option value="Any">Guild Any</option>
|
||||
<option value="1">Guild 1*</option>
|
||||
<option value="2">Guild 2*</option>
|
||||
<option value="3">Guild 3*</option>
|
||||
<option value="4">Guild 4*</option>
|
||||
<option value="5">Guild 5*</option>
|
||||
<option value="6">Guild 6*</option>
|
||||
<option value="7">Guild 7*</option>
|
||||
<option value="8">Guild 8*</option>
|
||||
<option value="9">Guild 9*</option>
|
||||
<option value="10">Guild 10*</option>
|
||||
</select>
|
||||
<select id="arena_stars">
|
||||
<option value="Any">Arena Any</option>
|
||||
<option value="None">Arena None</option>
|
||||
<option value="1">Arena 1*</option>
|
||||
<option value="2">Arena 2*</option>
|
||||
<option value="3">Arena 3*</option>
|
||||
<option value="4">Arena 4*</option>
|
||||
<option value="5">Arena 5*</option>
|
||||
<option value="6">Arena 6*</option>
|
||||
<option value="7">Arena 7*</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<label for="weapon_name_text"
|
||||
title="Show only weapons with a match in the name. List of strings separated by '|' (vertical bar)."
|
||||
>Name:</label>
|
||||
<input id="weapon_name_text" size="15" />
|
||||
<label for="weapon_component_text"
|
||||
title="Show only weapons with a matching create or upgrade component. List separated by '|' (veritical bar)."
|
||||
>Components:</label>
|
||||
<input id="weapon_component_text" size="15" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<table id="weapon_table">
|
||||
</table>
|
||||
<div id="sharpness_popup"></div>
|
||||
</body>
|
||||
276
web/mh4u/weaponplanner.html
Normal file
276
web/mh4u/weaponplanner.html
Normal file
@@ -0,0 +1,276 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Poogie's Weapon Planner</title>
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/js/ejs_production.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/js/common.js"></script>
|
||||
|
||||
<style>
|
||||
label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: sans, sans-serif;
|
||||
}
|
||||
|
||||
td.plus {
|
||||
background-color: LightCyan;
|
||||
}
|
||||
|
||||
td.minus {
|
||||
background-color: LightPink;
|
||||
}
|
||||
|
||||
td.num {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/*@media (max-width: 600) {*/
|
||||
.flexbox {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.sharpness-bar {
|
||||
border: 1px #d3d3d3 solid;
|
||||
min-width: 92px;
|
||||
height: 10px;
|
||||
background-color: #d3d3d3;
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.sharpness-bar span {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.sharpness-bar .red {
|
||||
background-color: #C00C38 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .orange {
|
||||
background-color: #E85018 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .yellow {
|
||||
background-color: #F0C830 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .green {
|
||||
background-color: #58D000 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .blue {
|
||||
background-color: #3068E8 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .white {
|
||||
background-color: #F0F0F0 !important;
|
||||
}
|
||||
|
||||
.sharpness-bar .purple {
|
||||
background-color: #c3c !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
var DATA_PATH = "/jsonapi/mh4u/";
|
||||
|
||||
var template_path = new EJS({ url: "/templates/weaponpath.ejs" });
|
||||
var template_stats = new EJS({ url: "/templates/weaponstats.ejs" });
|
||||
|
||||
$(document).ready(function(){
|
||||
setup_weapon_autocomplete("#weapon", autocomplete_predicate,
|
||||
init_page, update_search);
|
||||
});
|
||||
|
||||
function init_page() {
|
||||
load_qs();
|
||||
$("#search").click(update_search);
|
||||
$(window).on("popstate", function(e) {
|
||||
var oe = e.originalEvent;
|
||||
if (oe.state !== null) {
|
||||
console.log("popState:" + JSON.stringify(oe.state));
|
||||
$("#weapon_type").val(oe.state["weapon_type"]);
|
||||
$("#weapon_type").change();
|
||||
show_trees(oe.state["weapon"]);
|
||||
}
|
||||
});
|
||||
$("#weapon_type").change(function(evt) {
|
||||
update_weapon_autocomplete("#weapon", autocomplete_predicate,
|
||||
update_search);
|
||||
$("#weapon").val("");
|
||||
});
|
||||
}
|
||||
|
||||
function load_qs() {
|
||||
var wtype = $.QueryString["weapon_type"];
|
||||
var weapon = $.QueryString["weapon"];
|
||||
if (!wtype) {
|
||||
wtype = "All";
|
||||
}
|
||||
$("#weapon_type").val(wtype);
|
||||
$("#weapon_type").change();
|
||||
if (weapon) {
|
||||
show_trees(weapon);
|
||||
console.log("replaceState: " + weapon);
|
||||
save_state(get_state(), true);
|
||||
}
|
||||
}
|
||||
|
||||
function get_state() {
|
||||
return { "weapon": $("#weapon").val(),
|
||||
"weapon_type": $("#weapon_type").val() };
|
||||
}
|
||||
|
||||
function save_state(state, replace) {
|
||||
var url = "/mh4u/weaponplanner.html?" + encode_qs(state);
|
||||
if (replace) {
|
||||
window.history.replaceState(state, "", url);
|
||||
} else {
|
||||
window.history.pushState(state, "", url);
|
||||
}
|
||||
}
|
||||
|
||||
function autocomplete_predicate(weapon_data) {
|
||||
var weapon_type = $("#weapon_type").val();
|
||||
|
||||
if (weapon_type != "All" && weapon_type != weapon_data["wtype"]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function update_search() {
|
||||
var weapon_name = $("#weapon").val();
|
||||
|
||||
if (!weapon_name) return;
|
||||
|
||||
if (window.history.state
|
||||
&& window.history.state["weapon"] == weapon_name) {
|
||||
console.log("weapon not changed, skipping update");
|
||||
return;
|
||||
}
|
||||
|
||||
show_trees(weapon_name);
|
||||
console.log("pushState: " + weapon_name);
|
||||
save_state(get_state(), false);
|
||||
}
|
||||
|
||||
function show_trees(weapon_name) {
|
||||
console.log("show_trees '" + weapon_name + "'");
|
||||
if (!weapon_name) return;
|
||||
weapon_id = WEAPON_NAME_IDX[weapon_name][0];
|
||||
console.log("show_trees(" + weapon_name + "): " + weapon_id);
|
||||
$("#weapon").val(weapon_name);
|
||||
$("#results").html("");
|
||||
$("#weapon_stats").html("");
|
||||
$.getJSON(DATA_PATH + "weapon/" + weapon_id + ".json",
|
||||
function(data) {
|
||||
set_sharpness_titles(data);
|
||||
set_horn_melodies_title(data);
|
||||
if (data["parent_id"]) {
|
||||
var parent_obj = WEAPON_ID_IDX[data["parent_id"]][0];
|
||||
data["parent_name"] = parent_obj["name"];
|
||||
} else {
|
||||
data["parent_name"] = null;
|
||||
}
|
||||
data["sharpness_width"] = 1;
|
||||
data["sharpness_plus2"] = null;
|
||||
var html = template_stats.render(data);
|
||||
$("#weapon_stats").html(html);
|
||||
});
|
||||
|
||||
$.getJSON(DATA_PATH + "weapon/" + weapon_id + "_tree.json",
|
||||
function(data) {
|
||||
// first pass: collect all components and sort them
|
||||
var all_dict = {};
|
||||
for (i=0; i<data.length; i++) {
|
||||
var components = Object.keys(data[i]["components"]);
|
||||
for (j=0; j<components.length; j++) {
|
||||
all_dict[components[j]] = 0;
|
||||
}
|
||||
}
|
||||
var all_components = Object.keys(all_dict);
|
||||
all_components.sort();
|
||||
// second pass: generate the fieldset for each weapon
|
||||
// path. Note that the template uses all components
|
||||
// to order the components and make them line up
|
||||
for (i=0; i<data.length; i++) {
|
||||
delta = {};
|
||||
path = data[i];
|
||||
components = path["components"]
|
||||
path_string = "";
|
||||
for (j=0; j<path["path"].length; j++) {
|
||||
if (j != 0) {
|
||||
path_string += " -> ";
|
||||
}
|
||||
path_string += path["path"][j]["name"];
|
||||
}
|
||||
path["path_string"] = path_string.replace(/"/g,
|
||||
'"');
|
||||
path["all_components"] = all_components;
|
||||
path["component_list"] = Object.keys(components);
|
||||
if (i > 0) {
|
||||
prev_comps = data[i-1]["components"];
|
||||
$.each(components, function(name, quantity) {
|
||||
if (name in prev_comps) {
|
||||
delta[name] = components[name]
|
||||
- prev_comps[name];
|
||||
}
|
||||
});
|
||||
}
|
||||
path["delta"] = delta;
|
||||
path["component_list"].sort();
|
||||
var html = template_path.render(path);
|
||||
$("#results").append(html);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="weapon_type">Type:</label></td>
|
||||
<td><select id="weapon_type">
|
||||
<option value="All">All</option>
|
||||
<option value="Great Sword">Great Sword</option>
|
||||
<option value="Long Sword">Long Sword</option>
|
||||
<option value="Sword and Shield">Sword and Shield</option>
|
||||
<option value="Dual Blades">Dual Blades</option>
|
||||
<option value="Hammer">Hammer</option>
|
||||
<option value="Hunting Horn">Hunting Horn</option>
|
||||
<option value="Lance">Lance</option>
|
||||
<option value="Gunlance">Gunlance</option>
|
||||
<option value="Switch Axe">Switch Axe</option>
|
||||
<option value="Charge Blade">Charge Blade</option>
|
||||
<option value="Insect Glaive">Insect Glaive</option>
|
||||
<option value="Light Bowgun">Light Bowgun</option>
|
||||
<option value="Heavy Bowgun">Heavy Bowgun</option>
|
||||
<option value="Bow">Bow</option>
|
||||
</select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="weapon">Weapon:</label></td>
|
||||
<td><input id="weapon" name="weapon" size="20" />
|
||||
<button id="search">Ask Poogie</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="weapon_stats"></div>
|
||||
<div id="results" class="flexbox"></div>
|
||||
</body>
|
||||
Reference in New Issue
Block a user