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
|
||||
# noinspection PyPep8
|
||||
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
|
||||
# noinspection PyPep8
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
__all__ = [
|
||||
"character",
|
||||
"fit",
|
||||
"mutator",
|
||||
"module",
|
||||
"user",
|
||||
"skill",
|
||||
|
||||
@@ -23,6 +23,7 @@ import datetime
|
||||
|
||||
from eos.db import saveddata_meta
|
||||
from eos.saveddata.module import Module
|
||||
from eos.saveddata.mutator import Mutator
|
||||
from eos.saveddata.fit import Fit
|
||||
|
||||
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"'))
|
||||
|
||||
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
|
||||
|
||||
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):
|
||||
def getModifiedChargeAttr(self, key, default=0):
|
||||
@@ -59,8 +67,10 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
self.__modified = {}
|
||||
# Affected by entities
|
||||
self.__affectedBy = {}
|
||||
# Overrides
|
||||
# Overrides (per item)
|
||||
self.__overrides = {}
|
||||
# Mutators (per module)
|
||||
self.__mutators = {}
|
||||
# Dictionaries for various value modification types
|
||||
self.__forced = {}
|
||||
self.__preAssigns = {}
|
||||
@@ -100,6 +110,14 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
def overrides(self, 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):
|
||||
# Check if we have final calculated value
|
||||
key_value = self.__modified.get(key)
|
||||
@@ -128,14 +146,16 @@ class ModifiedAttributeDict(collections.MutableMapping):
|
||||
del self.__intermediary[key]
|
||||
|
||||
def getOriginal(self, key, default=None):
|
||||
val = None
|
||||
if self.overrides_enabled and self.overrides:
|
||||
val = self.overrides.get(key, None)
|
||||
else:
|
||||
val = None
|
||||
val = self.overrides.get(key, val)
|
||||
|
||||
# mutators are overriden by overrides. x_x
|
||||
val = self.mutators.get(key, val)
|
||||
|
||||
if val is None:
|
||||
if self.original:
|
||||
val = self.original.get(key, None)
|
||||
val = self.original.get(key, val)
|
||||
|
||||
if val is None and val != default:
|
||||
val = default
|
||||
|
||||
@@ -109,7 +109,6 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.__charge = eos.db.getItem(self.chargeID)
|
||||
|
||||
self.build()
|
||||
|
||||
def build(self):
|
||||
""" Builds internal module variables from both init's """
|
||||
|
||||
@@ -129,6 +128,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
if self.__item:
|
||||
self.__itemModifiedAttributes.original = self.__item.attributes
|
||||
self.__itemModifiedAttributes.mutators = self.mutators
|
||||
self.__itemModifiedAttributes.overrides = self.__item.overrides
|
||||
self.__hardpoint = self.__calculateHardpoint(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)
|
||||
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
|
||||
|
||||
val = getattr(att, "value", None)
|
||||
|
||||
Reference in New Issue
Block a user