Start implementing support for mutaplasmids.
* There's a new table `mutators` that has an FK back to a module, and links to an attribute ID with it's new value * Fixes an issue in the item state where the "base" value showed the literal base value for the attribute, regardless of override / mutators * If there is an override and a mutated attribute, mutated value takes effect
This commit is contained in:
@@ -77,7 +77,7 @@ sd_lock = threading.RLock()
|
|||||||
from eos.db.gamedata import alphaClones, attribute, category, effect, group, icon, item, marketGroup, metaData, metaGroup, queries, traits, unit
|
from eos.db.gamedata import alphaClones, attribute, category, effect, group, icon, item, marketGroup, metaData, metaGroup, queries, traits, unit
|
||||||
# noinspection PyPep8
|
# noinspection PyPep8
|
||||||
from eos.db.saveddata import booster, cargo, character, damagePattern, databaseRepair, drone, fighter, fit, implant, implantSet, loadDefaultDatabaseValues, \
|
from eos.db.saveddata import booster, cargo, character, damagePattern, databaseRepair, drone, fighter, fit, implant, implantSet, loadDefaultDatabaseValues, \
|
||||||
miscData, module, override, price, queries, skill, targetResists, user
|
miscData, mutator, module, override, price, queries, skill, targetResists, user
|
||||||
|
|
||||||
# Import queries
|
# Import queries
|
||||||
# noinspection PyPep8
|
# noinspection PyPep8
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
__all__ = [
|
__all__ = [
|
||||||
"character",
|
"character",
|
||||||
"fit",
|
"fit",
|
||||||
|
"mutator",
|
||||||
"module",
|
"module",
|
||||||
"user",
|
"user",
|
||||||
"skill",
|
"skill",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import datetime
|
|||||||
|
|
||||||
from eos.db import saveddata_meta
|
from eos.db import saveddata_meta
|
||||||
from eos.saveddata.module import Module
|
from eos.saveddata.module import Module
|
||||||
|
from eos.saveddata.mutator import Mutator
|
||||||
from eos.saveddata.fit import Fit
|
from eos.saveddata.fit import Fit
|
||||||
|
|
||||||
modules_table = Table("modules", saveddata_meta,
|
modules_table = Table("modules", saveddata_meta,
|
||||||
@@ -39,4 +40,11 @@ modules_table = Table("modules", saveddata_meta,
|
|||||||
CheckConstraint('("dummySlot" = NULL OR "itemID" = NULL) AND "dummySlot" != "itemID"'))
|
CheckConstraint('("dummySlot" = NULL OR "itemID" = NULL) AND "dummySlot" != "itemID"'))
|
||||||
|
|
||||||
mapper(Module, modules_table,
|
mapper(Module, modules_table,
|
||||||
properties={"owner": relation(Fit)})
|
properties={
|
||||||
|
"owner": relation(Fit),
|
||||||
|
"mutators": relation(
|
||||||
|
Mutator,
|
||||||
|
backref="module",
|
||||||
|
cascade="all,delete-orphan"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|||||||
35
eos/db/saveddata/mutator.py
Normal file
35
eos/db/saveddata/mutator.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# ===============================================================================
|
||||||
|
# Copyright (C) 2010 Diego Duclos
|
||||||
|
#
|
||||||
|
# This file is part of eos.
|
||||||
|
#
|
||||||
|
# eos is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# eos is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
# ===============================================================================
|
||||||
|
|
||||||
|
from sqlalchemy import Table, Column, Integer, ForeignKey, Boolean, DateTime, Float
|
||||||
|
from sqlalchemy.orm import mapper
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from eos.db import saveddata_meta
|
||||||
|
from eos.saveddata.mutator import Mutator
|
||||||
|
|
||||||
|
mutator_table = Table("mutators", saveddata_meta,
|
||||||
|
Column("moduleID", Integer, ForeignKey("modules.ID"), nullable=False, index=True),
|
||||||
|
Column("attrID", Integer, primary_key=True, index=True),
|
||||||
|
Column("value", Float, nullable=False),
|
||||||
|
Column("created", DateTime, nullable=True, default=datetime.datetime.now),
|
||||||
|
Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now)
|
||||||
|
)
|
||||||
|
|
||||||
|
mapper(Mutator, mutator_table)
|
||||||
@@ -33,6 +33,14 @@ class ItemAttrShortcut(object):
|
|||||||
|
|
||||||
return return_value or default
|
return return_value or default
|
||||||
|
|
||||||
|
def getBaseAttrValue(self, key, default=0):
|
||||||
|
'''
|
||||||
|
Gets base value in this order:
|
||||||
|
Mutated value > override value > attribute value
|
||||||
|
'''
|
||||||
|
return_value = self.itemModifiedAttributes.getOriginal(key)
|
||||||
|
|
||||||
|
return return_value or default
|
||||||
|
|
||||||
class ChargeAttrShortcut(object):
|
class ChargeAttrShortcut(object):
|
||||||
def getModifiedChargeAttr(self, key, default=0):
|
def getModifiedChargeAttr(self, key, default=0):
|
||||||
@@ -59,8 +67,10 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
|||||||
self.__modified = {}
|
self.__modified = {}
|
||||||
# Affected by entities
|
# Affected by entities
|
||||||
self.__affectedBy = {}
|
self.__affectedBy = {}
|
||||||
# Overrides
|
# Overrides (per item)
|
||||||
self.__overrides = {}
|
self.__overrides = {}
|
||||||
|
# Mutators (per module)
|
||||||
|
self.__mutators = {}
|
||||||
# Dictionaries for various value modification types
|
# Dictionaries for various value modification types
|
||||||
self.__forced = {}
|
self.__forced = {}
|
||||||
self.__preAssigns = {}
|
self.__preAssigns = {}
|
||||||
@@ -100,6 +110,14 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
|||||||
def overrides(self, val):
|
def overrides(self, val):
|
||||||
self.__overrides = val
|
self.__overrides = val
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mutators(self):
|
||||||
|
return {x.attr.name: x for x in self.__mutators}
|
||||||
|
|
||||||
|
@mutators.setter
|
||||||
|
def mutators(self, val):
|
||||||
|
self.__mutators = val
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
# Check if we have final calculated value
|
# Check if we have final calculated value
|
||||||
key_value = self.__modified.get(key)
|
key_value = self.__modified.get(key)
|
||||||
@@ -128,14 +146,16 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
|||||||
del self.__intermediary[key]
|
del self.__intermediary[key]
|
||||||
|
|
||||||
def getOriginal(self, key, default=None):
|
def getOriginal(self, key, default=None):
|
||||||
|
val = None
|
||||||
if self.overrides_enabled and self.overrides:
|
if self.overrides_enabled and self.overrides:
|
||||||
val = self.overrides.get(key, None)
|
val = self.overrides.get(key, val)
|
||||||
else:
|
|
||||||
val = None
|
# mutators are overriden by overrides. x_x
|
||||||
|
val = self.mutators.get(key, val)
|
||||||
|
|
||||||
if val is None:
|
if val is None:
|
||||||
if self.original:
|
if self.original:
|
||||||
val = self.original.get(key, None)
|
val = self.original.get(key, val)
|
||||||
|
|
||||||
if val is None and val != default:
|
if val is None and val != default:
|
||||||
val = default
|
val = default
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
|||||||
self.__charge = eos.db.getItem(self.chargeID)
|
self.__charge = eos.db.getItem(self.chargeID)
|
||||||
|
|
||||||
self.build()
|
self.build()
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
""" Builds internal module variables from both init's """
|
""" Builds internal module variables from both init's """
|
||||||
|
|
||||||
@@ -129,6 +128,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
|||||||
|
|
||||||
if self.__item:
|
if self.__item:
|
||||||
self.__itemModifiedAttributes.original = self.__item.attributes
|
self.__itemModifiedAttributes.original = self.__item.attributes
|
||||||
|
self.__itemModifiedAttributes.mutators = self.mutators
|
||||||
self.__itemModifiedAttributes.overrides = self.__item.overrides
|
self.__itemModifiedAttributes.overrides = self.__item.overrides
|
||||||
self.__hardpoint = self.__calculateHardpoint(self.__item)
|
self.__hardpoint = self.__calculateHardpoint(self.__item)
|
||||||
self.__slot = self.__calculateSlot(self.__item)
|
self.__slot = self.__calculateSlot(self.__item)
|
||||||
|
|||||||
54
eos/saveddata/mutator.py
Normal file
54
eos/saveddata/mutator.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# ===============================================================================
|
||||||
|
# Copyright (C) 2015 Ryan Holmes
|
||||||
|
#
|
||||||
|
# This file is part of eos.
|
||||||
|
#
|
||||||
|
# eos is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# eos is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
# ===============================================================================
|
||||||
|
|
||||||
|
from logbook import Logger
|
||||||
|
|
||||||
|
from sqlalchemy.orm import reconstructor
|
||||||
|
|
||||||
|
import eos.db
|
||||||
|
from eos.eqBase import EqBase
|
||||||
|
|
||||||
|
pyfalog = Logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Mutator(EqBase):
|
||||||
|
def __init__(self, stuff, attr, value):
|
||||||
|
self.moduleID = stuff.ID
|
||||||
|
self.attrID = attr.ID
|
||||||
|
self.__attr = attr
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
@reconstructor
|
||||||
|
def init(self):
|
||||||
|
self.__attr = None
|
||||||
|
self.__item = None
|
||||||
|
|
||||||
|
if self.attrID:
|
||||||
|
self.__attr = eos.db.getAttributeInfo(self.attrID)
|
||||||
|
if self.__attr is None:
|
||||||
|
pyfalog.error("Attribute (id: {0}) does not exist", self.attrID)
|
||||||
|
return
|
||||||
|
|
||||||
|
@property
|
||||||
|
def attr(self):
|
||||||
|
return self.__attr
|
||||||
|
|
||||||
|
@property
|
||||||
|
def item(self):
|
||||||
|
return self.__item
|
||||||
@@ -174,7 +174,12 @@ class ItemParams(wx.Panel):
|
|||||||
info = self.attrInfo.get(name)
|
info = self.attrInfo.get(name)
|
||||||
att = self.attrValues[name]
|
att = self.attrValues[name]
|
||||||
|
|
||||||
valDefault = getattr(info, "value", None)
|
# If we're working with a stuff object, we should get the original value from our getBaseAttrValue function,
|
||||||
|
# which will return the value with respect to the effective base (with mutators / overrides in place)
|
||||||
|
valDefault = getattr(info, "value", None) # Get default value from attribute
|
||||||
|
if self.stuff is not None:
|
||||||
|
# if it's a stuff, overwrite default (with fallback to current value)
|
||||||
|
valDefault = self.stuff.getBaseAttrValue(name, valDefault)
|
||||||
valueDefault = valDefault if valDefault is not None else att
|
valueDefault = valDefault if valDefault is not None else att
|
||||||
|
|
||||||
val = getattr(att, "value", None)
|
val = getattr(att, "value", None)
|
||||||
|
|||||||
Reference in New Issue
Block a user