Merge branch 'mutaplasmids'
# Conflicts: # eve.db
This commit is contained in:
@@ -391,6 +391,10 @@ def directAttributeRequest(itemIDs, attrIDs):
|
||||
return result
|
||||
|
||||
|
||||
def getAbyssalTypes():
|
||||
return set([r.resultingTypeID for r in gamedata_session.query(DynamicItem.resultingTypeID).distinct()])
|
||||
|
||||
|
||||
def getRequiredFor(itemID, attrMapping):
|
||||
Attribute1 = aliased(Attribute)
|
||||
Attribute2 = aliased(Attribute)
|
||||
|
||||
109
eos/gamedata.py
109
eos/gamedata.py
@@ -208,6 +208,8 @@ class Item(EqBase):
|
||||
|
||||
MOVE_ATTR_INFO = None
|
||||
|
||||
ABYSSAL_TYPES = None
|
||||
|
||||
@classmethod
|
||||
def getMoveAttrInfo(cls):
|
||||
info = getattr(cls, "MOVE_ATTR_INFO", None)
|
||||
@@ -463,6 +465,17 @@ class Item(EqBase):
|
||||
|
||||
return self.__price
|
||||
|
||||
@property
|
||||
def isAbyssal(self):
|
||||
if Item.ABYSSAL_TYPES is None:
|
||||
Item.getAbyssalYypes()
|
||||
|
||||
return self.ID in Item.ABYSSAL_TYPES
|
||||
|
||||
@classmethod
|
||||
def getAbyssalYypes(cls):
|
||||
cls.ABYSSAL_TYPES = eos.db.getAbyssalTypes()
|
||||
|
||||
def __repr__(self):
|
||||
return "Item(ID={}, name={}) at {}".format(
|
||||
self.ID, self.name, hex(id(self))
|
||||
@@ -539,7 +552,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):
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
# ===============================================================================
|
||||
|
||||
from logbook import Logger
|
||||
from copy import deepcopy
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
from math import floor
|
||||
@@ -110,6 +111,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.__item = None
|
||||
self.__baseItem = None
|
||||
self.__charge = None
|
||||
self.__mutaplasmid = None
|
||||
|
||||
# we need this early if module is invalid and returns early
|
||||
self.__slot = self.dummySlot
|
||||
@@ -206,7 +208,8 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return False
|
||||
return self.__item is None or \
|
||||
(self.__item.category.name not in ("Module", "Subsystem", "Structure Module") and
|
||||
self.__item.group.name not in self.SYSTEM_GROUPS)
|
||||
self.__item.group.name not in self.SYSTEM_GROUPS) or \
|
||||
(self.item.isAbyssal and (not self.baseItemID or not self.mutaplasmidID) )
|
||||
|
||||
@property
|
||||
def isMutated(self):
|
||||
@@ -352,11 +355,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
@property
|
||||
def baseItem(self):
|
||||
return self.__baseItem if self.__baseItem != 0 else None # what?
|
||||
return self.__baseItem
|
||||
|
||||
@property
|
||||
def mutaplasmid(self):
|
||||
return self.__mutaplasmid if self.__mutaplasmid != 0 else None
|
||||
return self.__mutaplasmid
|
||||
|
||||
@property
|
||||
def charge(self):
|
||||
@@ -835,9 +838,13 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if item is None:
|
||||
copy = Module.buildEmpty(self.slot)
|
||||
else:
|
||||
copy = Module(self.item)
|
||||
copy = Module(self.item, self.baseItem, self.mutaplasmid)
|
||||
copy.charge = self.charge
|
||||
copy.state = self.state
|
||||
|
||||
for x in self.mutators.values():
|
||||
Mutator(copy, x.attribute, x.value)
|
||||
|
||||
return copy
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
@@ -81,12 +81,15 @@ class Mutator(EqBase):
|
||||
""" Validates values as properly falling within the range of the modules' Mutaplasmid """
|
||||
mod = val/self.baseValue
|
||||
|
||||
if self.minMod < mod < self.maxMod:
|
||||
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(self.maxValue, max(self.minValue, val))
|
||||
if val >= 0:
|
||||
returnVal = min(self.maxValue, max(self.minValue, val))
|
||||
else:
|
||||
returnVal = max(self.maxValue, min(self.minValue, val))
|
||||
|
||||
return returnVal
|
||||
|
||||
@@ -105,11 +108,11 @@ class Mutator(EqBase):
|
||||
|
||||
@property
|
||||
def minMod(self):
|
||||
return self.dynamicAttribute.min
|
||||
return round(self.dynamicAttribute.min, 3)
|
||||
|
||||
@property
|
||||
def maxMod(self):
|
||||
return self.dynamicAttribute.max
|
||||
return round(self.dynamicAttribute.max, 3)
|
||||
|
||||
@property
|
||||
def baseValue(self):
|
||||
|
||||
Reference in New Issue
Block a user