diff --git a/eos/db/gamedata/queries.py b/eos/db/gamedata/queries.py index 30f51fe6b..db333fdbd 100644 --- a/eos/db/gamedata/queries.py +++ b/eos/db/gamedata/queries.py @@ -17,7 +17,7 @@ # along with eos. If not, see . # =============================================================================== -from sqlalchemy.orm import join, exc +from sqlalchemy.orm import join, exc, aliased from sqlalchemy.sql import and_, or_, select import eos.config @@ -315,3 +315,24 @@ def directAttributeRequest(itemIDs, attrIDs): result = gamedata_session.execute(q).fetchall() return result + +def getRequiredFor(itemID, attrMapping): + Attribute1 = aliased(Attribute) + Attribute2 = aliased(Attribute) + + skillToLevelClauses = [] + + for attrSkill, attrLevel in attrMapping.iteritems(): + skillToLevelClauses.append(and_(Attribute1.attributeID == attrSkill, Attribute2.attributeID == attrLevel)) + + queryOr = or_(*skillToLevelClauses) + + q = select((Attribute2.typeID, Attribute2.value), + and_(Attribute1.value == itemID, queryOr), + from_obj=[ + join(Attribute1, Attribute2, Attribute1.typeID == Attribute2.typeID) + ]) + + result = gamedata_session.execute(q).fetchall() + + return result diff --git a/eos/gamedata.py b/eos/gamedata.py index 8700229dc..e0c4ac863 100644 --- a/eos/gamedata.py +++ b/eos/gamedata.py @@ -250,6 +250,7 @@ class Item(EqBase): def init(self): self.__race = None self.__requiredSkills = None + self.__requiredFor = None self.__moved = False self.__offensive = None self.__assistive = None @@ -330,6 +331,24 @@ class Item(EqBase): requiredSkills[item] = skillLvl return self.__requiredSkills + @property + def requiredFor(self): + if self.__requiredFor is None: + self.__requiredFor = dict() + + # Map containing attribute IDs we may need for required skills + srqIDMap = {182: 277, 183: 278, 184: 279, 1285: 1286, 1289: 1287, 1290: 1288} + + # Get relevant attribute values from db (required skill IDs and levels) for our item + q = eos.db.getRequiredFor(self.ID, srqIDMap) + + for itemID, lvl in q: + # Fetch item from database and fill map + item = eos.db.getItem(itemID) + self.__requiredFor[item] = lvl + + return self.__requiredFor + factionMap = { 500001: "caldari", 500002: "minmatar", @@ -442,7 +461,6 @@ class Item(EqBase): @property def price(self): - # todo: use `from sqlalchemy import inspect` instead (need to verify it works in old and new OS X builds) if self.__price is not None and getattr(self.__price, '_sa_instance_state', None): pyfalog.debug("Price data for {} was deleted, resetting object".format(self.ID)) diff --git a/eos/saveddata/character.py b/eos/saveddata/character.py index bb316e01d..9a1bc686d 100644 --- a/eos/saveddata/character.py +++ b/eos/saveddata/character.py @@ -324,8 +324,8 @@ class Skill(HandledItem): return self.activeLevel or 0 - @level.setter - def level(self, level): + def setLevel(self, level, persist=False): + if (level < 0 or level > 5) and level is not None: raise ValueError(str(level) + " is not a valid value for level") @@ -333,10 +333,21 @@ class Skill(HandledItem): raise ReadOnlyException() self.activeLevel = level - self.character.dirtySkills.add(self) - if self.activeLevel == self.__level and self in self.character.dirtySkills: - self.character.dirtySkills.remove(self) + for item, rlevel in self.item.requiredFor.iteritems(): + if item.group.category.ID == 16: # Skill category + if level < rlevel: + skill = self.character.getSkill(item.ID) + #print "Removing skill: {}, Dependant level: {}, Required level: {}".format(skill, level, rlevel) + skill.setLevel(None, persist) + + if persist: + self.saveLevel() + else: + self.character.dirtySkills.add(self) + + if self.activeLevel == self.__level and self in self.character.dirtySkills: + self.character.dirtySkills.remove(self) @property def item(self): diff --git a/service/character.py b/service/character.py index 602bcb273..f53b1e424 100644 --- a/service/character.py +++ b/service/character.py @@ -371,12 +371,9 @@ class Character(object): char = eos.db.getCharacter(charID) skill = char.getSkill(skillID) if isinstance(level, basestring) or level > 5 or level < 0: - skill.level = None + skill.setLevel(None, persist) else: - skill.level = level - - if persist: - skill.saveLevel() + skill.setLevel(level, persist) eos.db.commit()