add html/jsonapi armor builder
- make decoration calculator use 1-slot decorations multiple times
This commit is contained in:
@@ -7,9 +7,9 @@ import codecs
|
||||
import _pathfix
|
||||
|
||||
from mhapi.db import MHDB
|
||||
from mhapi.model import get_decoration_values
|
||||
from mhapi.util import get_utf8_writer
|
||||
|
||||
def get_utf8_writer(writer):
|
||||
return codecs.getwriter("utf8")(writer)
|
||||
|
||||
def parse_args(argv):
|
||||
parser = argparse.ArgumentParser(description=
|
||||
@@ -46,7 +46,7 @@ def find_armors(args):
|
||||
ds = db.get_decorations_by_skills([sid])
|
||||
for d in ds:
|
||||
d.set_skills(db.get_item_skills(d.id))
|
||||
decoration_values = get_decoration_values(sid, ds)
|
||||
decoration_values = get_decoration_values(sid, ds)[1]
|
||||
decorations[sid] = (ds, decoration_values)
|
||||
print "%s[%s]:" % (skill_name, sid), ", ".join(d.name for d in ds), \
|
||||
decoration_values
|
||||
@@ -88,20 +88,6 @@ def find_armors(args):
|
||||
print " ", a.one_line_skills_u(args.skills)
|
||||
|
||||
|
||||
def get_decoration_values(skill_id, decorations):
|
||||
# TODO: write script to compute this and shove innto skill_tree table
|
||||
values = [0, 0, 0]
|
||||
for d in decorations:
|
||||
assert d.num_slots is not None
|
||||
# some skills like Handicraft have multiple decorations with
|
||||
# same number of slots - use the best one
|
||||
new = d.skills[skill_id]
|
||||
current = values[d.num_slots-1]
|
||||
if new > current:
|
||||
values[d.num_slots-1] = new
|
||||
return values
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_args(None)
|
||||
|
||||
|
||||
@@ -35,13 +35,21 @@ def file_path(path, model_object, use_name=False):
|
||||
def write_list_file(path, model_list):
|
||||
list_path = os.path.join(path, "_list.json")
|
||||
with open(list_path, "w") as f:
|
||||
json.dump([o.as_list_data() for o in model_list], f, indent=2)
|
||||
json.dump([o.as_list_data() for o in model_list],
|
||||
f, cls=model.ModelJSONEncoder, indent=2)
|
||||
|
||||
|
||||
def write_index_file(path, indexes):
|
||||
index_path = os.path.join(path, "_index.json")
|
||||
for key, data in indexes.iteritems():
|
||||
index_path = os.path.join(path, "_index_%s.json" % key)
|
||||
with open(index_path, "w") as f:
|
||||
json.dump(indexes, f, indent=2)
|
||||
json.dump(data, f, cls=model.ModelJSONEncoder, indent=2)
|
||||
|
||||
|
||||
def write_all_file(path, all_data):
|
||||
all_path = os.path.join(path, "_all.json")
|
||||
with open(all_path, "w") as f:
|
||||
json.dump(all_data, f, cls=model.ModelJSONEncoder, indent=2)
|
||||
|
||||
|
||||
def monster_json(db, path):
|
||||
@@ -63,6 +71,73 @@ def monster_json(db, path):
|
||||
write_index_file(path, indexes)
|
||||
|
||||
|
||||
def armor_json(db, path):
|
||||
armors = db.get_armors()
|
||||
mkdirs_p(path)
|
||||
write_list_file(path, armors)
|
||||
all_data = []
|
||||
|
||||
indexes = {}
|
||||
for a in armors:
|
||||
armor_path = file_path(path, a)
|
||||
a.update_indexes(indexes)
|
||||
skills = db.get_item_skills(a.id)
|
||||
if not skills:
|
||||
print "WARN: armor '%s' (%d) has no skills" % (a.name, a.id)
|
||||
a.set_skills(skills)
|
||||
|
||||
all_data.append(a.as_data())
|
||||
|
||||
with open(armor_path, "w") as f:
|
||||
a.json_dump(f)
|
||||
|
||||
write_index_file(path, indexes)
|
||||
write_all_file(path, all_data)
|
||||
|
||||
|
||||
def decoration_json(db, path):
|
||||
decorations = db.get_decorations()
|
||||
mkdirs_p(path)
|
||||
write_list_file(path, decorations)
|
||||
all_data = []
|
||||
|
||||
indexes = {}
|
||||
for a in decorations:
|
||||
decoration_path = file_path(path, a)
|
||||
a.update_indexes(indexes)
|
||||
skills = db.get_item_skills(a.id)
|
||||
if not skills:
|
||||
print "WARN: decoration '%s' (%d) has no skills" % (a.name, a.id)
|
||||
a.set_skills(skills)
|
||||
|
||||
all_data.append(a.as_data())
|
||||
|
||||
with open(decoration_path, "w") as f:
|
||||
a.json_dump(f)
|
||||
|
||||
write_index_file(path, indexes)
|
||||
write_all_file(path, all_data)
|
||||
|
||||
|
||||
def skilltree_json(db, path):
|
||||
skill_trees = db.get_skill_trees()
|
||||
mkdirs_p(path)
|
||||
write_list_file(path, skill_trees)
|
||||
|
||||
all_data = {}
|
||||
for st in skill_trees:
|
||||
ds = db.get_decorations_by_skills([st.id])
|
||||
for d in ds:
|
||||
d.set_skills(db.get_item_skills(d.id))
|
||||
st.set_decorations(ds)
|
||||
skilltree_path = file_path(path, st)
|
||||
all_data[st.name] = st
|
||||
with open(skilltree_path, "w") as f:
|
||||
st.json_dump(f)
|
||||
|
||||
write_all_file(path, all_data)
|
||||
|
||||
|
||||
def weapon_json(db, path):
|
||||
weapons = db.get_weapons()
|
||||
mkdirs_p(path)
|
||||
@@ -104,7 +179,10 @@ def main():
|
||||
items_json(db, os.path.join(outpath, "item"))
|
||||
weapon_json(db, os.path.join(outpath, "weapon"))
|
||||
monster_json(db, os.path.join(outpath, "monster"))
|
||||
#quest_json
|
||||
armor_json(db, os.path.join(outpath, "armor"))
|
||||
skilltree_json(db, os.path.join(outpath, "skilltree"))
|
||||
decoration_json(db, os.path.join(outpath, "decoration"))
|
||||
#quest_json(db, os.path.join(outpath, "quest"))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
27
mhapi/db.py
27
mhapi/db.py
@@ -299,27 +299,31 @@ class MHDB(object):
|
||||
|
||||
def get_weapon_by_name(self, name):
|
||||
return self._query_one("weapon", """
|
||||
SELECT * FROM weapons
|
||||
SELECT items._id, items.name, items.buy, weapons.*
|
||||
FROM weapons
|
||||
LEFT JOIN items ON weapons._id = items._id
|
||||
WHERE items.name=?
|
||||
""", (name,), model_cls=model.Weapon)
|
||||
|
||||
def get_armors(self):
|
||||
return self._query_all("armors", """
|
||||
SELECT * FROM armor
|
||||
SELECT items._id, items.name, items.buy, armor.*
|
||||
FROM armor
|
||||
LEFT JOIN items ON armor._id = items._id
|
||||
""", model_cls=model.Armor)
|
||||
|
||||
def get_armor(self, armor_id):
|
||||
return self._query_one("armor", """
|
||||
SELECT * FROM armor
|
||||
SELECT items._id, items.name, items.buy, armor.*
|
||||
FROM armor
|
||||
LEFT JOIN items ON armor._id = items._id
|
||||
WHERE armor._id=?
|
||||
""", (armor_id,), model_cls=model.Armor)
|
||||
|
||||
def get_armor_by_name(self, name):
|
||||
return self._query_one("armor", """
|
||||
SELECT * FROM armor
|
||||
SELECT items._id, items.name, items.buy, armor.*
|
||||
FROM armor
|
||||
LEFT JOIN items ON armor._id = items._id
|
||||
WHERE items.name=?
|
||||
""", (name,), model_cls=model.Armor)
|
||||
@@ -335,7 +339,7 @@ class MHDB(object):
|
||||
|
||||
def get_decorations(self):
|
||||
return self._query_all("decorations", """
|
||||
SELECT *
|
||||
SELECT items._id, items.name, items.buy, decorations.*
|
||||
FROM decorations
|
||||
INNER JOIN items
|
||||
ON items._id = decorations._id
|
||||
@@ -343,7 +347,7 @@ class MHDB(object):
|
||||
|
||||
def get_decoration(self, decoration_id):
|
||||
return self._query_one("decoration", """
|
||||
SELECT *
|
||||
SELECT items._id, items.name, items.buy, decorations.*
|
||||
FROM decorations
|
||||
INNER JOIN items
|
||||
ON items._id = decorations._id
|
||||
@@ -352,13 +356,18 @@ class MHDB(object):
|
||||
|
||||
def get_decoration_by_name(self, name):
|
||||
return self._query_all("decoration", """
|
||||
SELECT *
|
||||
SELECT items._id, items.name, items.buy, decorations.*
|
||||
FROM decorations
|
||||
INNER JOIN items
|
||||
ON items._id = decorations._id
|
||||
WHERE items.name = ?
|
||||
""", (name,), model_cls=model.Decoration)
|
||||
|
||||
def get_skill_trees(self):
|
||||
return self._query_all("skills", """
|
||||
SELECT _id, name FROM skill_trees
|
||||
""", model_cls=model.SkillTree)
|
||||
|
||||
def get_skill_tree_id(self, skill_tree_name):
|
||||
result = self._query_one("skill", """
|
||||
SELECT _id FROM skill_trees
|
||||
@@ -372,7 +381,7 @@ class MHDB(object):
|
||||
args = sorted(skill_tree_ids)
|
||||
placeholders = ", ".join(["?"] * len(skill_tree_ids))
|
||||
return self._query_all("decorations", """
|
||||
SELECT items.*, decorations.*
|
||||
SELECT items._id, items.name, items.buy, decorations.*
|
||||
FROM item_to_skill_tree
|
||||
LEFT JOIN items
|
||||
ON items._id = item_to_skill_tree.item_id
|
||||
@@ -389,7 +398,7 @@ class MHDB(object):
|
||||
placeholders = ", ".join(["?"] * len(skill_tree_ids))
|
||||
args += [hunter_type]
|
||||
return self._query_all("decorations", """
|
||||
SELECT items.*, armor.*
|
||||
SELECT items._id, items.name, items.buy, armor.*
|
||||
FROM item_to_skill_tree
|
||||
LEFT JOIN items
|
||||
ON items._id = item_to_skill_tree.item_id
|
||||
|
||||
@@ -76,6 +76,9 @@ class RowModel(ModelBase):
|
||||
self.update_index(key_field, value_fields, data[key_field])
|
||||
|
||||
def update_index(self, key_field, value_fields, data):
|
||||
if isinstance(value_fields, str):
|
||||
item = self[value_fields]
|
||||
else:
|
||||
item = dict((k, self[k]) for k in value_fields)
|
||||
key_value = self[key_field]
|
||||
if key_value not in data:
|
||||
@@ -212,16 +215,29 @@ class ItemWithSkills(RowModel):
|
||||
return self.skills.get(skill_id_or_name, 0)
|
||||
|
||||
def one_line_skills_u(self, skill_names=None):
|
||||
"""
|
||||
Get comma separated list of skills on the item. If @skill_names
|
||||
is passed, only include skills that are in that list.
|
||||
"""
|
||||
if skill_names is None:
|
||||
skill_names = sorted(self.skill_names)
|
||||
return ", ".join("%s %d" % (name, self.skills[name])
|
||||
for name in skill_names
|
||||
if name in self.skills)
|
||||
|
||||
def as_data(self):
|
||||
data = super(ItemWithSkills, self).as_data()
|
||||
if self.skills is not None:
|
||||
data["skills"] = dict((name, self.skills[name])
|
||||
for name in self.skill_names)
|
||||
#data["skills_by_id"] = dict((sid, self.skills[sid])
|
||||
# for sid in self.skill_ids)
|
||||
return data
|
||||
|
||||
|
||||
class Armor(ItemWithSkills):
|
||||
_indexes = { "name": ["id"],
|
||||
"slot": ["id", "name"] }
|
||||
_indexes = { "name": "id",
|
||||
"slot": "name" }
|
||||
|
||||
_one_line_template = string.Template(
|
||||
"$name ($slot) Def $defense-$max_defense Slot $num_slots"
|
||||
@@ -236,9 +252,10 @@ class Armor(ItemWithSkills):
|
||||
def skill(self, skill_id_or_name, decoration_values=()):
|
||||
"""
|
||||
decoration_values should be a list of points from the given
|
||||
number of slots, e.g. [1, 3] means that one slot gets 1 point
|
||||
and two slots get 3 points, [1, 0, 4] means that one slot gets 1 point,
|
||||
there is no two slot gem, and three slots gets 4 points.
|
||||
number of slots, e.g. [1, 3] or [1, 3, 0] means that one slot
|
||||
gets 1 point and two slots get 3 points, [1, 0, 4] means that
|
||||
one slot gets 1 point, there is no two slot gem, and three slots
|
||||
gets 4 points. If not passed, just returns native skill points.
|
||||
"""
|
||||
assert self.skills is not None
|
||||
total = self.skills.get(skill_id_or_name, 0)
|
||||
@@ -249,7 +266,7 @@ class Armor(ItemWithSkills):
|
||||
decoration_value = decoration_values[slots-1]
|
||||
if not decoration_value:
|
||||
continue
|
||||
if slots <= slots_left:
|
||||
while slots <= slots_left:
|
||||
total += decoration_value
|
||||
slots_left -= slots
|
||||
return total
|
||||
@@ -263,6 +280,27 @@ class ItemSkill(RowModel):
|
||||
pass
|
||||
|
||||
|
||||
class SkillTree(RowModel):
|
||||
def __init__(self, skill_tree_row):
|
||||
super(SkillTree, self).__init__(skill_tree_row)
|
||||
self.decoration_values = None
|
||||
self.decoration_ids = None
|
||||
|
||||
def set_decorations(self, decorations):
|
||||
if decorations is None:
|
||||
self.decoration_values = None
|
||||
else:
|
||||
self.decoration_ids, self.decoration_values = \
|
||||
get_decoration_values(self.id, decorations)
|
||||
|
||||
def as_data(self):
|
||||
data = super(SkillTree, self).as_data()
|
||||
if self.decoration_values is not None:
|
||||
data["decoration_values"] = self.decoration_values
|
||||
data["decoration_ids"] = self.decoration_ids
|
||||
return data
|
||||
|
||||
|
||||
class Weapon(RowModel):
|
||||
_list_fields = ["id", "wtype", "name"]
|
||||
_indexes = { "name": ["id"],
|
||||
@@ -401,6 +439,22 @@ class MonsterDamage(ModelBase):
|
||||
part_damage.breakable = True
|
||||
|
||||
|
||||
def get_decoration_values(skill_id, decorations):
|
||||
# TODO: write script to compute this and shove into skill_tree table
|
||||
values = [0, 0, 0]
|
||||
ids = [None, None, None]
|
||||
for d in decorations:
|
||||
assert d.num_slots is not None
|
||||
# some skills like Handicraft have multiple decorations with
|
||||
# same number of slots - use the best one
|
||||
new = d.skills[skill_id]
|
||||
current = values[d.num_slots-1]
|
||||
if new > current:
|
||||
values[d.num_slots-1] = new
|
||||
ids[d.num_slots-1] = d.id
|
||||
return (ids, values)
|
||||
|
||||
|
||||
def _break_find(part, parts, breaks):
|
||||
# favor 'Tail Tip' over Tail for Basarios
|
||||
if part == "Tail" and "Tail Tip" in parts:
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
Shared utility classes and functions.
|
||||
"""
|
||||
|
||||
import codecs
|
||||
|
||||
|
||||
class EnumBase(object):
|
||||
_names = dict()
|
||||
@@ -9,3 +11,7 @@ class EnumBase(object):
|
||||
@classmethod
|
||||
def name(cls, enum_value):
|
||||
return cls._names[enum_value]
|
||||
|
||||
|
||||
def get_utf8_writer(writer):
|
||||
return codecs.getwriter("utf8")(writer)
|
||||
|
||||
402
web/armor.html
Normal file
402
web/armor.html
Normal file
@@ -0,0 +1,402 @@
|
||||
<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>
|
||||
|
||||
<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 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 type to armor name
|
||||
var armors = {};
|
||||
|
||||
var decorations = { "Head": [], "Body": [], "Arms": [],
|
||||
"Waist": [], "Legs": [] };
|
||||
var slots_left = {};
|
||||
|
||||
$(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;
|
||||
load_armors();
|
||||
load_decorations();
|
||||
// if nothing is loaded update won't be
|
||||
// called, so force an update
|
||||
update_skills();
|
||||
});
|
||||
});
|
||||
$("#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);
|
||||
});
|
||||
// TODO: update skills
|
||||
});
|
||||
|
||||
function load_armors() {
|
||||
armors_saved = localStorage.getItem("armor_names");
|
||||
if (armors_saved != null) {
|
||||
armor_names = JSON.parse(armors_saved);
|
||||
$.each(armor_names, function(type, name) {
|
||||
if (name) {
|
||||
$("#" + type).val(name);
|
||||
set_armor(type, name);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function load_decorations() {
|
||||
decorations_saved = localStorage.getItem("decoration_name_lists");
|
||||
if (decorations_saved != null) {
|
||||
dname_list = JSON.parse(decorations_saved);
|
||||
$.each(dname_list, function(type, names) {
|
||||
$.each(names, function(i, name) {
|
||||
add_decoration(type, name);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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 save_armors() {
|
||||
var armor_names = {};
|
||||
$.each(armors, function(type, armor) {
|
||||
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) {
|
||||
$.each(dlist, function(i, d) {
|
||||
if (! (type in decoration_name_lists)) {
|
||||
decoration_name_lists[type] = [];
|
||||
}
|
||||
decoration_name_lists[type].push(d["display_name"]);
|
||||
});
|
||||
});
|
||||
localStorage.setItem("decoration_name_lists",
|
||||
JSON.stringify(decoration_name_lists));
|
||||
}
|
||||
|
||||
function get_base_path() {
|
||||
var path = document.location.pathname;
|
||||
return path.substring(0, path.lastIndexOf('/'));
|
||||
}
|
||||
|
||||
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 add_decoration(type, value) {
|
||||
parts = value.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;
|
||||
}
|
||||
}
|
||||
decoration_id = skill_trees[skill]["decoration_ids"][slots-1];
|
||||
$.getJSON(DATA_PATH + "decoration/" + decoration_id + ".json",
|
||||
function (data) {
|
||||
if (! (type in decorations)) {
|
||||
decorations[type] = []
|
||||
}
|
||||
data["display_name"] = value;
|
||||
decorations[type].push(data);
|
||||
slots_left[type] -= data["num_slots"];
|
||||
save_decorations();
|
||||
update_slots(type);
|
||||
update_skills();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function remove_decoration(type, index) {
|
||||
d = decorations[type][index];
|
||||
slots_left[type] += d["num_slots"];
|
||||
decorations[type].splice(index, 1);
|
||||
save_decorations();
|
||||
update_slots(type);
|
||||
update_skills();
|
||||
}
|
||||
|
||||
function set_armor(type, name, noupdate) {
|
||||
armor_id = armor_ids[name][0];
|
||||
$.getJSON(DATA_PATH + "armor/" + armor_id + ".json",
|
||||
function(data) {
|
||||
armors[type] = data;
|
||||
if (noupdate == undefined) {
|
||||
save_armors();
|
||||
decorations[type] = [];
|
||||
slots_left[type] = data["num_slots"];
|
||||
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);
|
||||
update_slots(type);
|
||||
update_skills();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function update_slots(type) {
|
||||
var free_slots = slots_left[type];
|
||||
var slots_html = new EJS(
|
||||
{ url: "templates/decorations.ejs" }
|
||||
).render({ decorations: decorations[type],
|
||||
free_slots: free_slots,
|
||||
type: type });
|
||||
$("#" + type + "_slots").html(slots_html);
|
||||
if (free_slots > 0) {
|
||||
setup_decoration_autocomplete(type, free_slots);
|
||||
}
|
||||
}
|
||||
|
||||
function update_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;
|
||||
|
||||
$.each(armors, function(type, armor) {
|
||||
dskills_by_type[type] = {};
|
||||
tskills_by_type[type] = {};
|
||||
$.each(armor["skills"], function(skill_name, skill_value) {
|
||||
if (! (skill_name in skills)) {
|
||||
skills[skill_name] = 0;
|
||||
}
|
||||
skills[skill_name] += skill_value;
|
||||
|
||||
if (! (skill_name in tskills_by_type[type])) {
|
||||
tskills_by_type[type][skill_name] = 0;
|
||||
}
|
||||
tskills_by_type[type][skill_name] += skill_value;
|
||||
})
|
||||
$.each(decorations[type], function(i, decoration) {
|
||||
$.each(decoration["skills"],
|
||||
function(skill_name, skill_value) {
|
||||
if (! (skill_name in skills)) {
|
||||
skills[skill_name] = 0;
|
||||
}
|
||||
skills[skill_name] += skill_value;
|
||||
|
||||
if (! (skill_name in dskills_by_type[type])) {
|
||||
dskills_by_type[type][skill_name] = 0;
|
||||
}
|
||||
dskills_by_type[type][skill_name] += skill_value;
|
||||
|
||||
if (! (skill_name in tskills_by_type[type])) {
|
||||
tskills_by_type[type][skill_name] = 0;
|
||||
}
|
||||
tskills_by_type[type][skill_name] += skill_value;
|
||||
}
|
||||
);
|
||||
})
|
||||
$.each(ELEMENTS, function(i, element) {
|
||||
key = element + "_res";
|
||||
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];
|
||||
//$("#" + type + "_slots").html(armor["num_slots"]);
|
||||
});
|
||||
$("#Total_slots").html((slots - slots_free)
|
||||
+ " used / " + slots + " slots");
|
||||
|
||||
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 skills_table = new EJS(
|
||||
{ url: "templates/skills.ejs" }
|
||||
).render({ TYPES: TYPES,
|
||||
skills: skills,
|
||||
dskills_by_type: dskills_by_type,
|
||||
tskills_by_type: tskills_by_type,
|
||||
active_skills: skill_names,
|
||||
armors: armors });
|
||||
$("#skills_div").html(skills_table);
|
||||
|
||||
var resist_table = new EJS(
|
||||
{ url: "templates/resistance.ejs" }
|
||||
).render({ TYPES: TYPES,
|
||||
ELEMENTS: ELEMENTS,
|
||||
armors: armors,
|
||||
element_resist: element_resist });
|
||||
$("#resist_div").html(resist_table);
|
||||
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<table id="armor_table" cellpadding="2" cellspacing="2">
|
||||
<tr>
|
||||
<td><label for="Head">Head:</label></td>
|
||||
<td><input id="Head" type="text" size="15" /></td>
|
||||
<td id="Head_slots"> </td>
|
||||
<td id="Head_skills"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="Body">Body:</label></td>
|
||||
<td><input id="Body" type="text" size="15" /></td>
|
||||
<td id="Body_slots"> </td>
|
||||
<td id="Body_skills"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="Arms">Arms:</label></td>
|
||||
<td><input id="Arms" type="text" size="15" /></td>
|
||||
<td id="Arms_slots"> </td>
|
||||
<td id="Arms_skills"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="Waist">Waist:</label></td>
|
||||
<td><input id="Waist" type="text" size="15" /></td>
|
||||
<td id="Waist_slots"> </td>
|
||||
<td id="Waist_skills"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="Legs">Legs:</label></td>
|
||||
<td><input id="Legs" type="text" size="15" /></td>
|
||||
<td id="Legs_slots"> </td>
|
||||
<td id="Legs_skills"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<td> </td>
|
||||
<td id="Total_slots">0</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>
|
||||
1
web/js/ejs_production.js
Normal file
1
web/js/ejs_production.js
Normal file
File diff suppressed because one or more lines are too long
18
web/templates/decorations.ejs
Normal file
18
web/templates/decorations.ejs
Normal file
@@ -0,0 +1,18 @@
|
||||
<table>
|
||||
<% for(var i=0; i<decorations.length; i++) { %>
|
||||
<tr>
|
||||
<td><%= Array(decorations[i]["num_slots"] + 1).join("\u26ab") %></td>
|
||||
<td><%= decorations[i]["display_name"] %>
|
||||
<button id="<%= type %>_remove_decoration_<%= i %>"
|
||||
class="remove_decoration">-</button></td>
|
||||
</tr>
|
||||
<% } %>
|
||||
<% if (free_slots > 0) { %>
|
||||
<tr>
|
||||
<td><%= Array(free_slots + 1).join("\u26aa") %><%= Array(3- free_slots + 1).join(" ") %></td>
|
||||
<td><input id="<%= type %>_decoration" type="text" size="12">
|
||||
<button id="<%= type %>_add_decoration"
|
||||
class="add_decoration">+</button></td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</table>
|
||||
21
web/templates/resistance.ejs
Normal file
21
web/templates/resistance.ejs
Normal file
@@ -0,0 +1,21 @@
|
||||
<table id="resist_table" cellpadding="2" border="0">
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>Total</th>
|
||||
<th>Head</th>
|
||||
<th>Body</th>
|
||||
<th>Arms</th>
|
||||
<th>Waist</th>
|
||||
<th>Legs</th>
|
||||
</tr>
|
||||
<% for(var i=0; i<ELEMENTS.length; i++) { %>
|
||||
<tr>
|
||||
<th><%= ELEMENTS[i] %></th>
|
||||
<td class="num"><%= element_resist[ELEMENTS[i]] %></td>
|
||||
<% for(var j=0; j<TYPES.length; j++) { %>
|
||||
<td class="num">
|
||||
<%= armors[TYPES[j]]
|
||||
? armors[TYPES[j]][ELEMENTS[i] + "_res"] : " " %></td>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</table>
|
||||
25
web/templates/skills.ejs
Normal file
25
web/templates/skills.ejs
Normal file
@@ -0,0 +1,25 @@
|
||||
<table id="skills_table" cellpadding="2" border="0">
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>Total</th>
|
||||
<% for(var i=0; i<TYPES.length; i++) { %>
|
||||
<td><%= TYPES[i] %></td>
|
||||
<% } %>
|
||||
</tr>
|
||||
<% for(var i=0; i<active_skills.length; i++) { %>
|
||||
<tr>
|
||||
<td><%= active_skills[i] %></td>
|
||||
<td class="num"><%= skills[active_skills[i]] %></td>
|
||||
<% for(var j=0; j<TYPES.length; j++) { %>
|
||||
<td class="num">
|
||||
<%= (armors[TYPES[j]] && tskills_by_type[TYPES[j]][active_skills[i]])
|
||||
? tskills_by_type[TYPES[j]][active_skills[i]]
|
||||
: " " %>
|
||||
<%= 0 && (armors[TYPES[j]] && dskills_by_type[TYPES[j]][active_skills[i]])
|
||||
? " (" + dskills_by_type[TYPES[j]][active_skills[i]] + ")"
|
||||
: " " %>
|
||||
</td>
|
||||
<% } %>
|
||||
</tr>
|
||||
<% } %>
|
||||
</table>
|
||||
24
web/templates/skills.ejs.bak
Normal file
24
web/templates/skills.ejs.bak
Normal file
@@ -0,0 +1,24 @@
|
||||
<table id="skills_table" cellpadding="2">
|
||||
<tr>
|
||||
<th>Skill</th>
|
||||
<th>Total</th>
|
||||
<% for(var i=0; i<TYPES.length; i++) { %>
|
||||
<th><%= TYPES[i] %></th>
|
||||
<% } %>
|
||||
</tr>
|
||||
<% for(var i=0; i<active_skills.length; i++) { %>
|
||||
<tr>
|
||||
<td><%= active_skills[i] %></td>
|
||||
<td><%= skills[active_skills[i]] %></td>
|
||||
<% for(var j=0; j<TYPES.length; j++) { %>
|
||||
<td>
|
||||
<%= (armors[TYPES[j]] && armors[TYPES[j]]["skills"][active_skills[i]])
|
||||
? armors[TYPES[j]]["skills"][active_skills[i]] : " " %>
|
||||
<%= (armors[TYPES[j]] && dskills_by_type[TYPES[j]][active_skills[i]])
|
||||
? " (" + dskills_by_type[TYPES[j]][active_skills[i]] + ")"
|
||||
: " " %>
|
||||
</td>
|
||||
<% } %>
|
||||
</tr>
|
||||
<% } %>
|
||||
</table>
|
||||
Reference in New Issue
Block a user