diff --git a/eos/modifiedAttributeDict.py b/eos/modifiedAttributeDict.py index ceb44148c..cb90d6679 100644 --- a/eos/modifiedAttributeDict.py +++ b/eos/modifiedAttributeDict.py @@ -112,7 +112,7 @@ class ModifiedAttributeDict(collections.MutableMapping): @property def mutators(self): - return {x.attr.name: x for x in self.__mutators.values()} + return {x.attribute.name: x for x in self.__mutators.values()} @mutators.setter def mutators(self, val): diff --git a/eos/saveddata/mutator.py b/eos/saveddata/mutator.py index 2784ec30b..39dd49533 100644 --- a/eos/saveddata/mutator.py +++ b/eos/saveddata/mutator.py @@ -31,6 +31,13 @@ class Mutator(EqBase): """ Mutators are the object that represent an attribute override on the module level, in conjunction with mutaplasmids. Each mutated module, when created, is instantiated with a list of these objects, dictated by the mutaplasmid that is used on the base module. + + A note on the different attributes on this object: + * attribute: points to the definition of the attribute from dgmattribs. + * baseAttribute: points to the attribute defined for the base item (contains the base value with with to mutate) + * dynamicAttribute: points to the Mutaplasmid definition of the attribute, including min/max + + This could probably be cleaned up with smarter relationships, but whatever """ def __init__(self, module, attr, value): @@ -38,7 +45,8 @@ class Mutator(EqBase): self.moduleID = module.ID self.attrID = attr.ID self.__attr = attr - self.value = value + self.build() + self.value = value # must run after the build(), because the validator requires build() to run first @reconstructor def init(self): @@ -50,28 +58,26 @@ class Mutator(EqBase): pyfalog.error("Attribute (id: {0}) does not exist", self.attrID) return - self.value = self.value # run the validator (to ensure we catch any changed min/max values CCP releases) self.build() + self.value = self.value # run the validator (to ensure we catch any changed min/max values might CCP release) def build(self): - pass + # dynamic attribute links to the Mutaplasmids attribute definition for this mutated definition + self.dynamicAttribute = next(a for a in self.module.mutaplasmid.attributes if a.attributeID == self.attrID) + # base attribute links to the base ite's attribute for this mutated definition (contains original, base value) + self.baseAttribute = self.module.item.attributes[self.dynamicAttribute.name] @validates("value") def validator(self, key, val): - """ Validates values as properly falling within the range of the modules mutaplasmid """ - dynAttr = next(a for a in self.module.mutaplasmid.attributes if a.attributeID == self.attrID) - baseAttr = self.module.item.attributes[dynAttr.name] + """ Validates values as properly falling within the range of the modules' Mutaplasmid """ + mod = val/self.baseValue - minValue = dynAttr.min * baseAttr.value - maxValue = dynAttr.max * baseAttr.value - mod = val/baseAttr.value - - if dynAttr.min < mod < dynAttr.max: + if self.minMod < mod < self.maxMod: # sweet, all good returnVal = val else: # need to fudge the numbers a bit. Go with the value closest to base - returnVal = min(maxValue, max(minValue, val)) + returnVal = min(self.maxValue, max(self.minValue, val)) return returnVal @@ -85,9 +91,31 @@ class Mutator(EqBase): return self.__attr is None @property - def attr(self): - return self.__attr + def highIsGood(self): + return self.attribute.highIsGood @property - def item(self): - return self.__item + def minMod(self): + return self.dynamicAttribute.min + + @property + def maxMod(self): + return self.dynamicAttribute.max + + @property + def baseValue(self): + return self.baseAttribute.value + + @property + def minValue(self): + return self.minMod * self.baseAttribute.value + + @property + def maxValue(self): + return self.maxMod * self.baseAttribute.value + + @property + def attribute(self): + return self.__attr + + diff --git a/gui/builtinItemStatsViews/attributeSlider.py b/gui/builtinItemStatsViews/attributeSlider.py index c06f49a8b..127d3c1b8 100644 --- a/gui/builtinItemStatsViews/attributeSlider.py +++ b/gui/builtinItemStatsViews/attributeSlider.py @@ -5,7 +5,7 @@ from gui.attribute_gauge import AttributeGauge import eos import eos.db -_ValueChanged, EVT_NOTEBOOK_PAGE_CHANGED = wx.lib.newevent.NewEvent() +_ValueChanged, EVT_VALUE_CHANGED = wx.lib.newevent.NewEvent() class AttributeSliderChangeEvent: @@ -115,7 +115,7 @@ class TestAttributeSlider(wx.Frame): wx.Frame.__init__(self, parent, id, title, pos, size, sty) self.panel = AttributeSlider(self, -50, 0.8, 1.5, False) - self.panel.Bind(EVT_NOTEBOOK_PAGE_CHANGED, self.thing) + self.panel.Bind(EVT_VALUE_CHANGED, self.thing) self.panel.SetValue(-55) self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) diff --git a/gui/builtinItemStatsViews/itemMutator.py b/gui/builtinItemStatsViews/itemMutator.py index f5cecd756..a8130f9a2 100644 --- a/gui/builtinItemStatsViews/itemMutator.py +++ b/gui/builtinItemStatsViews/itemMutator.py @@ -31,43 +31,32 @@ class ItemMutator(wx.Panel): self.goodColor = wx.Colour(96, 191, 0) self.badColor = wx.Colour(255, 64, 0) - for x in sorted(stuff.mutaplasmid.attributes, key=lambda a: a.displayName): - # JFC this is ugly as sin - min = round(x.min, 2) - max = round(x.max, 2) - - base_value = stuff.item.attributes[x.name].value - - mutator = stuff.mutators[x.attributeID] - - slider = AttributeSlider(self, base_value, min, max, not x.highIsGood) - slider.SetValue(mutator.value) + for m in sorted(stuff.mutators.values(), key=lambda x: x.attribute.displayName): + slider = AttributeSlider(self, m.baseValue, m.minMod, m.maxMod, not m.highIsGood) + slider.SetValue(m.value) headingSizer = wx.BoxSizer(wx.HORIZONTAL) - minValue = round(base_value * min, 3) - maxValue = round(base_value * max, 3) - # create array for the two ranges - min_t = [minValue, min, None] - max_t = [maxValue, max, None] + min_t = [round(m.minValue, 3), m.minMod, None] + max_t = [round(m.maxValue, 3), m.maxMod, None] # Then we need to determine if it's better than original, which will be the color - min_t[2] = min_t[1] < 1 if not x.highIsGood else 1 < min_t[1] - max_t[2] = max_t[1] < 1 if not x.highIsGood else 1 < max_t[1] + min_t[2] = min_t[1] < 1 if not m.highIsGood else 1 < min_t[1] + max_t[2] = max_t[1] < 1 if not m.highIsGood else 1 < max_t[1] # Lastly, we need to determine which range value is "worse" (left side) or "better" (right side) - if (x.highIsGood and min_t[1] > max_t[1]) or (not x.highIsGood and min_t[1] < max_t[1]): + if (m.highIsGood and min_t[1] > max_t[1]) or (not m.highIsGood and min_t[1] < max_t[1]): better_range = min_t else: better_range = max_t - if (x.highIsGood and max_t[1] < min_t[1]) or (not x.highIsGood and max_t[1] > min_t[1]): + if (m.highIsGood and max_t[1] < min_t[1]) or (not m.highIsGood and max_t[1] > min_t[1]): worse_range = max_t else: worse_range = min_t - print("{}: \nHigh is good: {}".format(x.displayName, x.highIsGood)) - print("Value {}".format(base_value)) + print("{}: \nHigh is good: {}".format(m.attribute.displayName, m.attribute.highIsGood)) + print("Value {}".format(m.baseValue)) print(min_t) print(max_t) @@ -77,17 +66,17 @@ class ItemMutator(wx.Panel): font = parent.GetFont() font.SetWeight(wx.BOLD) - headingSizer.Add(BitmapLoader.getStaticBitmap(x.info.icon.iconFile, self, "icons"), 0, wx.RIGHT, 10) + headingSizer.Add(BitmapLoader.getStaticBitmap(m.attribute.icon.iconFile, self, "icons"), 0, wx.RIGHT, 10) - displayName = wx.StaticText(self, wx.ID_ANY, x.displayName) + displayName = wx.StaticText(self, wx.ID_ANY, m.attribute.displayName) displayName.SetFont(font) headingSizer.Add(displayName, 3, wx.ALL | wx.EXPAND, 0) - range_low = wx.StaticText(self, wx.ID_ANY, "{} {}".format(worse_range[0], x.unit.displayName)) - range_low.SetForegroundColour(self.goodColor if worse_range[2] else self.badColor) + range_low = wx.StaticText(self, wx.ID_ANY, "{} {}".format(worse_range[0], m.attribute.unit.displayName)) + range_low.SetForegroundColour(self.goodColor if worse_range[2] else self.badColor) - range_high = wx.StaticText(self, wx.ID_ANY, "{} {}".format(better_range[0], x.unit.displayName)) + range_high = wx.StaticText(self, wx.ID_ANY, "{} {}".format(better_range[0], m.attribute.unit.displayName)) range_high.SetForegroundColour(self.goodColor if better_range[2] else self.badColor) headingSizer.Add(range_low, 0, wx.ALL | wx.EXPAND, 0)