diff --git a/eos/gamedata.py b/eos/gamedata.py index 717676915..f4ea61719 100644 --- a/eos/gamedata.py +++ b/eos/gamedata.py @@ -543,7 +543,101 @@ class MetaType(EqBase): class Unit(EqBase): - pass + + def __init__(self): + self.name = None + self.displayName = None + + @property + def translations(self): + """ This is a mapping of various tweaks that we have to do between the internal representation of an attribute + value and the display (for example, 'Millisecond' units have the display name of 's', so we have to convert value + from ms to s) """ + return { + "Inverse Absolute Percent": ( + lambda v: (1 - v) * 100, + lambda d: -1 * (d / 100) + 1, + lambda u: u), + "Inversed Modifier Percent": ( + lambda v: (1 - v) * 100, + lambda d: -1 * (d / 100) + 1, + lambda u: u), + "Modifier Percent": ( + lambda v: ("%+.2f" if ((v - 1) * 100) % 1 else "%+d") % ((v - 1) * 100), + lambda d: (d / 100) + 1, + lambda u: u), + "Volume": ( + lambda v: v, + lambda d: d, + lambda u: "m³"), + "Sizeclass": ( + lambda v: v, + lambda d: d, + lambda u: ""), + "Absolute Percent": ( + lambda v: (v * 100), + lambda d: d / 100, + lambda u: u), + "Milliseconds": ( + lambda v: v / 1000.0, + lambda d: d * 1000.0, + lambda u: u), + "Boolean": ( + lambda v, u: "Yes" if v == 1 else "No", + lambda d: 1.0 if d == "Yes" else 0.0, + lambda u: ""), + "typeID": ( + self.itemIDCallback, + None, # we could probably convert these back if we really tried hard enough + lambda u: ""), + "groupID": ( + self.groupIDCallback, + None, + lambda u: ""), + "attributeID": ( + self.attributeIDCallback, + None, + lambda u: ""), + } + + @staticmethod + def itemIDCallback(v): + v = int(v) + item = eos.db.getItem(int(v)) + return "%s (%d)" % (item.name, v) if item is not None else str(v) + + @staticmethod + def groupIDCallback(v): + v = int(v) + group = eos.db.getGroup(v) + return "%s (%d)" % (group.name, v) if group is not None else str(v) + + @staticmethod + def attributeIDCallback(v): + v = int(v) + if not v: # some attributes come through with a value of 0? See #1387 + return "%d" % (v) + attribute = eos.db.getAttributeInfo(v, eager=("unit")) + return "%s (%d)" % (attribute.name.capitalize(), v) + + def TranslateValue(self, value): + """Attributes have to be translated certain ways based on their unit (ex: decimals converting to percentages). + This allows us to get an easy representation of how the attribute should be printed """ + + override = self.translations.get(self.name) + if override is not None: + return override[0](value), override[2](self.displayName) + + return value, self.displayName + + def ComplicateValue(self, value): + """Takes the display value and turns it back into the internal representation of it""" + + override = self.translations.get(self.name) + if override is not None: + return override[1](value) + + return value class Traits(EqBase): diff --git a/gui/builtinItemStatsViews/itemAttributes.py b/gui/builtinItemStatsViews/itemAttributes.py index 5f413020d..1c9b05c4f 100644 --- a/gui/builtinItemStatsViews/itemAttributes.py +++ b/gui/builtinItemStatsViews/itemAttributes.py @@ -7,8 +7,6 @@ import wx from .helpers import AutoListCtrl from gui.bitmap_loader import BitmapLoader -from service.market import Market -from service.attribute import Attribute from gui.utils.numberFormatter import formatAmount @@ -215,14 +213,14 @@ class ItemParams(wx.Panel): if self.toggleView != 1: valueUnit = str(value) elif info and info.unit: - valueUnit = self.TranslateValueUnit(value, info.unit.displayName, info.unit.name) + valueUnit = self.FormatValue(*info.unit.TranslateValue(value)) else: valueUnit = formatAmount(value, 3, 0, 0) if self.toggleView != 1: valueUnitDefault = str(valueDefault) elif info and info.unit: - valueUnitDefault = self.TranslateValueUnit(valueDefault, info.unit.displayName, info.unit.name) + valueUnitDefault = self.FormatValue(*info.unit.TranslateValue(valueDefault)) else: valueUnitDefault = formatAmount(valueDefault, 3, 0, 0) @@ -237,44 +235,11 @@ class ItemParams(wx.Panel): self.Layout() @staticmethod - def TranslateValueUnit(value, unitName, unitDisplayName): - def itemIDCallback(): - item = Market.getInstance().getItem(value) - return "%s (%d)" % (item.name, value) if item is not None else str(value) - - def groupIDCallback(): - group = Market.getInstance().getGroup(value) - return "%s (%d)" % (group.name, value) if group is not None else str(value) - - def attributeIDCallback(): - if not value: # some attributes come through with a value of 0? See #1387 - return "%d" % (value) - attribute = Attribute.getInstance().getAttributeInfo(value) - return "%s (%d)" % (attribute.name.capitalize(), value) - - trans = { - "Inverse Absolute Percent" : (lambda: (1 - value) * 100, unitName), - "Inversed Modifier Percent": (lambda: (1 - value) * 100, unitName), - "Modifier Percent" : ( - lambda: ("%+.2f" if ((value - 1) * 100) % 1 else "%+d") % ((value - 1) * 100), unitName), - "Volume" : (lambda: value, "m\u00B3"), - "Sizeclass" : (lambda: value, ""), - "Absolute Percent" : (lambda: (value * 100), unitName), - "Milliseconds" : (lambda: value / 1000.0, unitName), - "typeID" : (itemIDCallback, ""), - "groupID" : (groupIDCallback, ""), - "attributeID" : (attributeIDCallback, "") - } - - override = trans.get(unitDisplayName) - if override is not None: - v = override[0]() - if isinstance(v, str): - fvalue = v - elif isinstance(v, (int, float)): - fvalue = formatAmount(v, 3, 0, 0) - else: - fvalue = v - return "%s %s" % (fvalue, override[1]) + def FormatValue(value, unit): + """Formats a value / unit combination into a string + @todo: move this to a more central location, since this is also used in the item mutator panel""" + if isinstance(value, (int, float)): + fvalue = formatAmount(value, 3, 0, 0) else: - return "%s %s" % (formatAmount(value, 3, 0), unitName) + fvalue = value + return "%s %s" % (fvalue, unit) diff --git a/gui/builtinItemStatsViews/itemMutator.py b/gui/builtinItemStatsViews/itemMutator.py index 1803086a8..dcfcaf897 100644 --- a/gui/builtinItemStatsViews/itemMutator.py +++ b/gui/builtinItemStatsViews/itemMutator.py @@ -6,6 +6,7 @@ from .attributeSlider import AttributeSlider, EVT_VALUE_CHANGED import gui.mainFrame from gui.contextMenu import ContextMenu +from .itemAttributes import ItemParams from gui.bitmap_loader import BitmapLoader import gui.globalEvents as GE import gui.mainFrame @@ -69,14 +70,15 @@ class ItemMutator(wx.Panel): headingSizer.Add(displayName, 3, wx.ALL | wx.EXPAND, 0) - range_low = wx.StaticText(self, wx.ID_ANY, "{} {}".format(worse_range[0], m.attribute.unit.displayName)) + + range_low = wx.StaticText(self, wx.ID_ANY, ItemParams.FormatValue(*m.attribute.unit.TranslateValue(worse_range[0]))) range_low.SetForegroundColour(self.goodColor if worse_range[2] else self.badColor) - range_high = wx.StaticText(self, wx.ID_ANY, "{} {}".format(better_range[0], m.attribute.unit.displayName)) + range_high = wx.StaticText(self, wx.ID_ANY, ItemParams.FormatValue(*m.attribute.unit.TranslateValue(better_range[0]))) range_high.SetForegroundColour(self.goodColor if better_range[2] else self.badColor) headingSizer.Add(range_low, 0, wx.ALL | wx.EXPAND, 0) - headingSizer.Add(wx.StaticText(self, wx.ID_ANY, " ── "), 0, wx.RIGHT | wx.LEFT | wx.EXPAND, 5) + headingSizer.Add(wx.StaticText(self, wx.ID_ANY, " ─ "), 0, wx.RIGHT | wx.LEFT | wx.EXPAND, 5) headingSizer.Add(range_high, 0, wx.RIGHT | wx.EXPAND, 10) mainSizer.Add(headingSizer, 0, wx.ALL | wx.EXPAND, 5)