add html/jsonapi armor builder

- make decoration calculator use 1-slot decorations multiple times
This commit is contained in:
Bryce Allen
2015-04-29 02:16:01 -05:00
parent 784299dd53
commit 6329e7028b
11 changed files with 662 additions and 38 deletions

View File

@@ -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

View File

@@ -76,7 +76,10 @@ class RowModel(ModelBase):
self.update_index(key_field, value_fields, data[key_field])
def update_index(self, key_field, value_fields, data):
item = dict((k, self[k]) for k in value_fields)
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:
data[key_value] = []
@@ -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:

View File

@@ -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)