Merge branch 'master' into charImplants

Conflicts:
	gui/characterEditor.py
This commit is contained in:
blitzmann
2015-11-08 21:19:04 -05:00
1885 changed files with 3742 additions and 928 deletions

View File

@@ -59,26 +59,20 @@ class CapSimulator(object):
return duration, capNeed
def init(self, modules):
"""prepare modules. a list of (duration, capNeed, clipSize) tuples is
"""prepare modules. a list of (duration, capNeed, clipSize, disableStagger) tuples is
expected, with clipSize 0 if the module has infinite ammo.
"""
mods = {}
for module in modules:
if module in mods:
mods[module] += 1
else:
mods[module] = 1
self.modules = mods
self.modules = modules
def reset(self):
"""Reset the simulator state"""
self.state = []
mods = {}
period = 1
disable_period = False
for (duration, capNeed, clipSize), amount in self.modules.iteritems():
# Loop over modules, clearing clipSize if applicable, and group modules based on attributes
for (duration, capNeed, clipSize, disableStagger) in self.modules:
if self.scale:
duration, capNeed = self.scale_activation(duration, capNeed)
@@ -87,7 +81,15 @@ class CapSimulator(object):
if not self.reload and capNeed > 0:
clipSize = 0
if self.stagger:
# Group modules based on their properties
if (duration, capNeed, clipSize, disableStagger) in mods:
mods[(duration, capNeed, clipSize, disableStagger)] += 1
else:
mods[(duration, capNeed, clipSize, disableStagger)] = 1
# Loop over grouped modules, configure staggering and push to the simulation state
for (duration, capNeed, clipSize, disableStagger), amount in mods.iteritems():
if self.stagger and not disableStagger:
if clipSize == 0:
duration = int(duration/amount)
else:
@@ -167,13 +169,13 @@ class CapSimulator(object):
iterations += 1
t_last = t_now
if cap < cap_lowest:
if cap < 0.0:
break
cap_lowest = cap
t_last = t_now
# queue the next activation of this module
t_now += duration
shot += 1

View File

@@ -4,7 +4,7 @@ import sys
debug = False
gamedataCache = True
saveddataCache = True
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "staticdata", "eve.db")), sys.getfilesystemencoding())
gamedata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "eve.db")), sys.getfilesystemencoding())
saveddata_connectionstring = 'sqlite:///' + unicode(realpath(join(dirname(abspath(__file__)), "..", "saveddata", "saveddata.db")), sys.getfilesystemencoding())
#Autodetect path, only change if the autodetection bugs out.

View File

@@ -68,14 +68,8 @@ from eos.db.gamedata import *
from eos.db.saveddata import *
#Import queries
from eos.db.gamedata.queries import getItem, searchItems, getVariations, getItemsByCategory, directAttributeRequest, \
getMarketGroup, getGroup, getCategory, getAttributeInfo, getMetaData, getMetaGroup
from eos.db.saveddata.queries import getUser, getCharacter, getFit, getFitsWithShip, countFitsWithShip, searchFits, \
getCharacterList, getPrice, getDamagePatternList, getDamagePattern, \
getFitList, getFleetList, getFleet, save, remove, commit, add, \
getCharactersForUser, getMiscData, getSquadsIDsWithFitID, getWing, \
getSquad, getBoosterFits, getProjectedFits, getTargetResistsList, getTargetResists,\
clearPrices, countAllFits
from eos.db.gamedata.queries import *
from eos.db.saveddata.queries import *
#If using in memory saveddata, you'll want to reflect it so the data structure is good.
if config.saveddata_connectionstring == "sqlite:///:memory:":

View File

@@ -3,22 +3,15 @@ import shutil
import time
import re
import os
def getAppVersion():
# calculate app version based on upgrade files we have
appVersion = 0
for fname in os.listdir(os.path.join(os.path.dirname(__file__), "migrations")):
m = re.match("^upgrade(?P<index>\d+)\.py$", fname)
if not m:
continue
index = int(m.group("index"))
appVersion = max(appVersion, index)
return appVersion
import migrations
def getVersion(db):
cursor = db.execute('PRAGMA user_version')
return cursor.fetchone()[0]
def getAppVersion():
return migrations.appVersion
def update(saveddata_engine):
dbVersion = getVersion(saveddata_engine)
appVersion = getAppVersion()
@@ -37,10 +30,11 @@ def update(saveddata_engine):
shutil.copyfile(config.saveDB, toFile)
for version in xrange(dbVersion, appVersion):
module = __import__("eos.db.migrations.upgrade{}".format(version + 1), fromlist=True)
upgrade = getattr(module, "upgrade", False)
if upgrade:
upgrade(saveddata_engine)
func = migrations.updates[version+1]
if func:
print "applying update",version+1
func(saveddata_engine)
# when all is said and done, set version to current
saveddata_engine.execute("PRAGMA user_version = {}".format(appVersion))

View File

@@ -7,3 +7,25 @@ define an upgrade() function with the logic. Please note that there must be as
many upgrade files as there are database versions (version 5 would include
upgrade files 1-5)
"""
import pkgutil
import re
updates = {}
appVersion = 0
prefix = __name__ + "."
for importer, modname, ispkg in pkgutil.iter_modules(__path__, prefix):
# loop through python files, extracting update number and function, and
# adding it to a list
modname_tail = modname.rsplit('.', 1)[-1]
module = __import__(modname, fromlist=True)
m = re.match("^upgrade(?P<index>\d+)$", modname_tail)
if not m:
continue
index = int(m.group("index"))
appVersion = max(appVersion, index)
upgrade = getattr(module, "upgrade", False)
if upgrade:
updates[index] = upgrade

View File

@@ -1,3 +1,18 @@
__all__ = ["character", "fit", "module", "user", "skill", "price",
"booster", "drone", "implant", "fleet", "damagePattern",
"miscData", "targetResists"]
__all__ = [
"character",
"fit",
"module",
"user",
"skill",
"price",
"booster",
"drone",
"implant",
"fleet",
"damagePattern",
"miscData",
"targetResists",
"override",
"crest"
]

31
eos/db/saveddata/crest.py Normal file
View File

@@ -0,0 +1,31 @@
#===============================================================================
# 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, String, Boolean
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.types import CrestChar
crest_table = Table("crest", saveddata_meta,
Column("ID", Integer, primary_key = True),
Column("name", String, nullable = False, unique = True),
Column("refresh_token", String, nullable = False))
mapper(CrestChar, crest_table)

View File

@@ -0,0 +1,31 @@
#===============================================================================
# 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, Float
from sqlalchemy.orm import mapper
from eos.db import saveddata_meta
from eos.types import Override
overrides_table = Table("overrides", saveddata_meta,
Column("itemID", Integer, primary_key=True, index = True),
Column("attrID", Integer, primary_key=True, index = True),
Column("value", Float, nullable = False))
mapper(Override, overrides_table)

View File

@@ -19,7 +19,8 @@
from eos.db.util import processEager, processWhere
from eos.db import saveddata_session, sd_lock
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists
from eos.types import User, Character, Fit, Price, DamagePattern, Fleet, MiscData, Wing, Squad, TargetResists, Override, CrestChar
from eos.db.saveddata.fleet import squadmembers_table
from eos.db.saveddata.fit import projectedFits_table
from sqlalchemy.sql import and_
@@ -182,7 +183,7 @@ def getFit(lookfor, eager=None):
else:
eager = processEager(eager)
with sd_lock:
fit = saveddata_session.query(Fit).options(*eager).filter(Fit.ID == fitID).first()
fit = saveddata_session.query(Fit).options(*eager).filter(Fit.ID == lookfor).first()
else:
raise TypeError("Need integer as argument")
@@ -416,6 +417,45 @@ def getProjectedFits(fitID):
else:
raise TypeError("Need integer as argument")
def getCrestCharacters(eager=None):
eager = processEager(eager)
with sd_lock:
characters = saveddata_session.query(CrestChar).options(*eager).all()
return characters
@cachedQuery(CrestChar, 1, "lookfor")
def getCrestCharacter(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
with sd_lock:
character = saveddata_session.query(CrestChar).get(lookfor)
else:
eager = processEager(eager)
with sd_lock:
character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.ID == lookfor).first()
elif isinstance(lookfor, basestring):
eager = processEager(eager)
with sd_lock:
character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.name == lookfor).first()
else:
raise TypeError("Need integer or string as argument")
return character
def getOverrides(itemID, eager=None):
if isinstance(itemID, int):
return saveddata_session.query(Override).filter(Override.itemID == itemID).all()
else:
raise TypeError("Need integer as argument")
def clearOverrides():
with sd_lock:
deleted_rows = saveddata_session.query(Override).delete()
commit()
return deleted_rows
def getAllOverrides(eager=None):
return saveddata_session.query(Override).all()
def removeInvalid(fits):
invalids = [f for f in fits if f.isInvalid]

View File

@@ -1,4 +1,4 @@
# armorTankingGang2
# armorWarfareArmorHpReplacer
#
# Used by:
# Implant: Armored Warfare Mindlink

View File

@@ -0,0 +1,9 @@
# battlecruiserDroneSpeed
#
# Used by:
# Ship: Myrmidon
# Ship: Prophecy
type = "passive"
def handler(fit, ship, context):
fit.drones.filteredItemBoost(lambda drone: drone.item.requiresSkill("Drones"),
"maxVelocity", ship.getModifiedItemAttr("roleBonusCBC"))

View File

@@ -0,0 +1,10 @@
# battlecruiserMETRange
#
# Used by:
# Ships named like: Harbinger (2 of 2)
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Energy Turret"),
"maxRange", ship.getModifiedItemAttr("roleBonusCBC"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Energy Turret"),
"falloff", ship.getModifiedItemAttr("roleBonusCBC"))

View File

@@ -0,0 +1,11 @@
# battlecruiserMHTRange
#
# Used by:
# Ships named like: Brutix (2 of 2)
# Ship: Ferox
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
"maxRange", ship.getModifiedItemAttr("roleBonusCBC"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
"falloff", ship.getModifiedItemAttr("roleBonusCBC"))

View File

@@ -0,0 +1,9 @@
# battlecruiserMissileRange
#
# Used by:
# Ships named like: Drake (2 of 2)
# Ship: Cyclone
type = "passive"
def handler(fit, skill, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"),
"maxVelocity", skill.getModifiedItemAttr("roleBonusCBC"))

View File

@@ -0,0 +1,10 @@
# battlecruiserMPTRange
#
# Used by:
# Ships named like: Hurricane (2 of 2)
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"),
"maxRange", ship.getModifiedItemAttr("roleBonusCBC"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"),
"falloff", ship.getModifiedItemAttr("roleBonusCBC"))

View File

@@ -0,0 +1,7 @@
# crystalMiningamountInfo2
#
# Used by:
# Modules from group: Frequency Mining Laser (3 of 3)
type = "passive"
def handler(fit, module, context):
module.preAssignItemAttr("specialtyMiningAmount", module.getModifiedItemAttr("miningAmount"))

View File

@@ -0,0 +1,8 @@
# entosisCPUAddition
#
# Used by:
# Modules from group: Entosis Link (2 of 2)
type = "passive"
def handler(fit, module, context):
module.increaseItemAttr("cpu", module.getModifiedItemAttr("entosisCPUAdd"))

View File

@@ -0,0 +1,8 @@
# entosisCPUPenalty
#
# Used by:
# Ships from group: Interceptor (10 of 10)
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemIncrease(lambda mod: mod.item.requiresSkill("Infomorph Psychology"),
"entosisCPUAdd", ship.getModifiedItemAttr("entosisCPUPenalty"))

View File

@@ -0,0 +1,11 @@
# informationWarfareMaxTargetRangeBonus
#
# Used by:
# Implant: Caldari Navy Warfare Mindlink
# Implant: Imperial Navy Warfare Mindlink
# Implant: Information Warfare Mindlink
type = "gang"
gangBoost = "maxTargetRange"
gangBonus = "maxTargetRangeBonus"
def handler(fit, container, context):
fit.ship.boostItemAttr(gangBoost, container.getModifiedItemAttr(gangBonus))

View File

@@ -2,7 +2,6 @@
#
# Used by:
# Implant: Caldari Navy Warfare Mindlink
# Implant: Imperial Navy Warfare Mindlink
# Implant: Information Warfare Mindlink
type = "passive"
def handler(fit, implant, context):

View File

@@ -3,6 +3,7 @@
# Used by:
# Module: Medium Mercoxit Mining Crystal Optimization I
type = "passive"
runTime="early"
def handler(fit, module, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Mercoxit Processing"),
"specialisationAsteroidYieldMultiplier", module.getModifiedItemAttr("miningAmountBonus"))

View File

@@ -0,0 +1,10 @@
# miningForemanMindLinkMiningAmountBonusReplacer
#
# Used by:
# Implant: Mining Foreman Mindlink
type = "gang"
gangBoost = "miningAmount"
gangBonus = "miningAmountBonus"
def handler(fit, container, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining"),
gangBoost, container.getModifiedItemAttr(gangBonus) * level)

View File

@@ -5,4 +5,4 @@
# Charges named like: Mining Crystal (32 of 32)
type = "passive"
def handler(fit, module, context):
module.multiplyItemAttr("miningAmount", module.getModifiedChargeAttr("specialisationAsteroidYieldMultiplier"))
module.multiplyItemAttr("specialtyMiningAmount", module.getModifiedChargeAttr("specialisationAsteroidYieldMultiplier"))

View File

@@ -1,7 +1,6 @@
# miningYieldGangBonusFixed
#
# Used by:
# Implant: Mining Foreman Mindlink
# Skill: Mining Foreman
type = "gang"
gangBoost = "miningAmount"

View File

@@ -1,9 +1,9 @@
# overloadSelfThermalHardeningBonus
#
# Used by:
# Variations of module: Armor Thermic Hardener I (39 of 39)
# Variations of module: Thermic Dissipation Field I (19 of 19)
# Module: Civilian Thermic Dissipation Field
# Variations of module: Armor Thermal Hardener I (39 of 39)
# Variations of module: Thermal Dissipation Field I (19 of 19)
# Module: Civilian Thermal Dissipation Field
type = "overheat"
def handler(fit, module, context):
module.boostItemAttr("thermalDamageResistanceBonus", module.getModifiedItemAttr("overloadHardeningBonus"))

View File

@@ -1,9 +1,6 @@
# reconOperationsMaxTargetRangeBonusPostPercentMaxTargetRangeGangShips
#
# Used by:
# Implant: Caldari Navy Warfare Mindlink
# Implant: Imperial Navy Warfare Mindlink
# Implant: Information Warfare Mindlink
# Skill: Information Warfare
type = "gang"
gangBoost = "maxTargetRange"

View File

@@ -1,9 +1,6 @@
# shieldDefensiveOperationsShieldCapacityBonusPostPercentShieldCapacityGangShips
#
# Used by:
# Implant: Caldari Navy Warfare Mindlink
# Implant: Republic Fleet Warfare Mindlink
# Implant: Siege Warfare Mindlink
# Skill: Siege Warfare
type = "gang"
gangBoost = "shieldCapacity"

View File

@@ -2,8 +2,10 @@
#
# Used by:
# Ship: Devoter
# Ship: Gold Magnate
# Ship: Impairor
# Ship: Phobos
# Ship: Silver Magnate
type = "passive"
def handler(fit, ship, context):
fit.ship.boostItemAttr("armorEmDamageResonance", ship.getModifiedItemAttr("rookieArmorResistanceBonus"))

View File

@@ -2,8 +2,10 @@
#
# Used by:
# Ship: Devoter
# Ship: Gold Magnate
# Ship: Impairor
# Ship: Phobos
# Ship: Silver Magnate
type = "passive"
def handler(fit, ship, context):
fit.ship.boostItemAttr("armorExplosiveDamageResonance", ship.getModifiedItemAttr("rookieArmorResistanceBonus"))

View File

@@ -2,8 +2,10 @@
#
# Used by:
# Ship: Devoter
# Ship: Gold Magnate
# Ship: Impairor
# Ship: Phobos
# Ship: Silver Magnate
type = "passive"
def handler(fit, ship, context):
fit.ship.boostItemAttr("armorKineticDamageResonance", ship.getModifiedItemAttr("rookieArmorResistanceBonus"))

View File

@@ -2,8 +2,10 @@
#
# Used by:
# Ship: Devoter
# Ship: Gold Magnate
# Ship: Impairor
# Ship: Phobos
# Ship: Silver Magnate
type = "passive"
def handler(fit, ship, context):
fit.ship.boostItemAttr("armorThermalDamageResonance", ship.getModifiedItemAttr("rookieArmorResistanceBonus"))

View File

@@ -0,0 +1,8 @@
# shipBonusProjectileTrackingMBC2
#
# Used by:
# Ship: Hurricane Fleet Issue
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"),
"trackingSpeed", ship.getModifiedItemAttr("shipBonusMBC2"), skill="Minmatar Battlecruiser")

View File

@@ -1,4 +1,4 @@
# shipBonusWDFGnullSpeedEffects
# shipBonusWDFGnullPenalties
#
# Used by:
# Ship: Fiend

View File

@@ -1,8 +0,0 @@
# shipHeavyAssaultMissileVelocityCBC2
#
# Used by:
# Ship: Drake Navy Issue
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Assault Missiles"),
"maxVelocity", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")

View File

@@ -1,8 +0,0 @@
# shipHeavyMissileVelocityCBC2
#
# Used by:
# Ship: Drake Navy Issue
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Heavy Missiles"),
"maxVelocity", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")

View File

@@ -0,0 +1,8 @@
# shipHybridDmg1CBC2
#
# Used by:
# Ship: Ferox
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Hybrid Turret"),
"damageMultiplier", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")

View File

@@ -1,7 +1,7 @@
# shipProjectileRof1MBC2
#
# Used by:
# Ships named like: Hurricane (2 of 2)
# Ship: Hurricane
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Medium Projectile Turret"),

View File

@@ -1,9 +1,8 @@
# shipShieldEmResistance1CBC2
#
# Used by:
# Variations of ship: Ferox (2 of 2)
# Ship: Drake
# Ship: Nighthawk
# Variations of ship: Drake (3 of 3)
# Ship: Vulture
type = "passive"
def handler(fit, ship, context):
fit.ship.boostItemAttr("shieldEmDamageResonance", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")

View File

@@ -1,9 +1,8 @@
# shipShieldExplosiveResistance1CBC2
#
# Used by:
# Variations of ship: Ferox (2 of 2)
# Ship: Drake
# Ship: Nighthawk
# Variations of ship: Drake (3 of 3)
# Ship: Vulture
type = "passive"
def handler(fit, ship, context):
fit.ship.boostItemAttr("shieldExplosiveDamageResonance", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")

View File

@@ -1,9 +1,8 @@
# shipShieldKineticResistance1CBC2
#
# Used by:
# Variations of ship: Ferox (2 of 2)
# Ship: Drake
# Ship: Nighthawk
# Variations of ship: Drake (3 of 3)
# Ship: Vulture
type = "passive"
def handler(fit, ship, context):
fit.ship.boostItemAttr("shieldKineticDamageResonance", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")

View File

@@ -1,9 +1,8 @@
# shipShieldThermalResistance1CBC2
#
# Used by:
# Variations of ship: Ferox (2 of 2)
# Ship: Drake
# Ship: Nighthawk
# Variations of ship: Drake (3 of 3)
# Ship: Vulture
type = "passive"
def handler(fit, ship, context):
fit.ship.boostItemAttr("shieldThermalDamageResonance", ship.getModifiedItemAttr("shipBonusCBC2"), skill="Caldari Battlecruiser")

View File

@@ -0,0 +1,11 @@
# siegeWarfareShieldCapacityBonusReplacer
#
# Used by:
# Implant: Caldari Navy Warfare Mindlink
# Implant: Republic Fleet Warfare Mindlink
# Implant: Siege Warfare Mindlink
type = "gang"
gangBoost = "shieldCapacity"
gangBonus = "shieldCapacityBonus"
def handler(fit, container, context):
fit.ship.boostItemAttr(gangBoost, container.getModifiedItemAttr(gangBonus) * level)

View File

@@ -1,9 +1,6 @@
# skirmishWarfareAgilityBonus
#
# Used by:
# Implant: Federation Navy Warfare Mindlink
# Implant: Republic Fleet Warfare Mindlink
# Implant: Skirmish Warfare Mindlink
# Skill: Skirmish Warfare
type = "gang"
gangBoost = "agility"

View File

@@ -0,0 +1,11 @@
# skirmishWarfareAgilityBonusReplacer
#
# Used by:
# Implant: Federation Navy Warfare Mindlink
# Implant: Republic Fleet Warfare Mindlink
# Implant: Skirmish Warfare Mindlink
type = "gang"
gangBoost = "agility"
gangBonus = "agilityBonus"
def handler(fit, container, context):
fit.ship.boostItemAttr(gangBoost, container.getModifiedItemAttr(gangBonus) * level)

View File

@@ -2,6 +2,8 @@
#
# Used by:
# Ship: Coercer
# Ship: Gold Magnate
# Ship: Silver Magnate
type = "passive"
def handler(fit, ship, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Small Energy Turret"),

View File

@@ -1,7 +1,7 @@
# thermalShieldCompensationHardeningBonusGroupShieldAmp
#
# Used by:
# Skill: Thermic Shield Compensation
# Skill: Thermal Shield Compensation
type = "passive"
def handler(fit, skill, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Shield Amplifier",

View File

@@ -1,7 +1,7 @@
# thermicArmorCompensationHardeningBonusGroupArmorCoating
#
# Used by:
# Skill: Thermic Armor Compensation
# Skill: Thermal Armor Compensation
type = "passive"
def handler(fit, skill, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Coating",

View File

@@ -1,7 +1,7 @@
# thermicArmorCompensationHardeningBonusGroupEnergized
#
# Used by:
# Skill: Thermic Armor Compensation
# Skill: Thermal Armor Compensation
type = "passive"
def handler(fit, skill, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Plating Energized",

View File

@@ -9,7 +9,8 @@ def handler(fit, module, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"duration", module.getModifiedItemAttr("remoteArmorDamageDurationBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"armorDamageAmount", module.getModifiedItemAttr("remoteArmorDamageAmountBonus"))
"armorDamageAmount", module.getModifiedItemAttr("remoteArmorDamageAmountBonus"),
stackingPenalties=True)
# Remote hull reppers
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Hull Repair Systems"),
@@ -19,7 +20,8 @@ def handler(fit, module, context):
# Shield Transporters
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
"shieldBonus", module.getModifiedItemAttr("shieldTransportAmountBonus"))
"shieldBonus", module.getModifiedItemAttr("shieldTransportAmountBonus"),
stackingPenalties=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
"duration", module.getModifiedItemAttr("shieldTransportDurationBonus"))
@@ -34,26 +36,29 @@ def handler(fit, module, context):
"shieldBonus", module.getModifiedItemAttr("shieldBoostMultiplier"),
stackingPenalties=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Operation"),
"duration", module.getModifiedItemAttr("shieldBonusDurationBonus"),
stackingPenalties=True)
"duration", module.getModifiedItemAttr("shieldBonusDurationBonus"))
# Armor reps
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Repair Unit",
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
"armorDamageAmount", module.getModifiedItemAttr("armorDamageAmountBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Repair Unit",
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
"duration", module.getModifiedItemAttr("armorDamageDurationBonus"))
# Speed bonus
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"))
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
stackingPenalties=True)
# Scan resolution multiplier
fit.ship.multiplyItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionMultiplier"))
fit.ship.multiplyItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionMultiplier"),
stackingPenalties=True)
# Mass multiplier
fit.ship.multiplyItemAttr("mass", module.getModifiedItemAttr("massMultiplier"))
fit.ship.multiplyItemAttr("mass", module.getModifiedItemAttr("massMultiplier"),
stackingPenalties=True)
# Lock range
fit.ship.multiplyItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeMultiplier"))
fit.ship.multiplyItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeMultiplier"),
stackingPenalties=True)
# Max locked targets
fit.ship.increaseItemAttr("maxLockedTargets", module.getModifiedItemAttr("maxLockedTargetsBonus"))
@@ -61,3 +66,16 @@ def handler(fit, module, context):
# Block EWAR & projected effects
fit.ship.forceItemAttr("disallowOffensiveModifiers", module.getModifiedItemAttr("disallowOffensiveModifiers"))
fit.ship.forceItemAttr("disallowAssistance", module.getModifiedItemAttr("disallowAssistance"))
# EW cap need increase
groups = [
'ECM Burst',
'Remote ECM Burst',
'Tracking Disruptor',
'ECM',
'Remote Sensor Damper',
'Target Painter']
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups or
mod.item.requiresSkill("Propulsion Jamming"),
"capacitorNeed", module.getModifiedItemAttr("ewCapacitorNeedBonus"))

View File

@@ -9,7 +9,8 @@ def handler(fit, module, context):
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"duration", module.getModifiedItemAttr("remoteArmorDamageDurationBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Armor Repair Systems"),
"armorDamageAmount", module.getModifiedItemAttr("remoteArmorDamageAmountBonus"))
"armorDamageAmount", module.getModifiedItemAttr("remoteArmorDamageAmountBonus"),
stackingPenalties=True)
# Remote hull reppers
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Remote Hull Repair Systems"),
@@ -19,7 +20,8 @@ def handler(fit, module, context):
# Shield Transporters
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
"shieldBonus", module.getModifiedItemAttr("shieldTransportAmountBonus"))
"shieldBonus", module.getModifiedItemAttr("shieldTransportAmountBonus"),
stackingPenalties=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
"duration", module.getModifiedItemAttr("shieldTransportDurationBonus"))
@@ -34,26 +36,29 @@ def handler(fit, module, context):
"shieldBonus", module.getModifiedItemAttr("shieldBoostMultiplier"),
stackingPenalties=True)
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Operation"),
"duration", module.getModifiedItemAttr("shieldBonusDurationBonus"),
stackingPenalties=True)
"duration", module.getModifiedItemAttr("shieldBonusDurationBonus"))
# Armor reps
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Repair Unit",
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
"armorDamageAmount", module.getModifiedItemAttr("armorDamageAmountBonus"))
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Repair Unit",
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Repair Systems"),
"duration", module.getModifiedItemAttr("armorDamageDurationBonus"))
# Speed bonus
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"))
fit.ship.boostItemAttr("maxVelocity", module.getModifiedItemAttr("speedFactor"),
stackingPenalties=True)
# Scan resolution multiplier
fit.ship.multiplyItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionMultiplier"))
fit.ship.multiplyItemAttr("scanResolution", module.getModifiedItemAttr("scanResolutionMultiplier"),
stackingPenalties=True)
# Mass multiplier
fit.ship.multiplyItemAttr("mass", module.getModifiedItemAttr("massMultiplier"))
fit.ship.multiplyItemAttr("mass", module.getModifiedItemAttr("massMultiplier"),
stackingPenalties=True)
# Lock range
fit.ship.multiplyItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeMultiplier"))
fit.ship.multiplyItemAttr("maxTargetRange", module.getModifiedItemAttr("maxTargetRangeMultiplier"),
stackingPenalties=True)
# Max locked targets
fit.ship.increaseItemAttr("maxLockedTargets", module.getModifiedItemAttr("maxLockedTargetsBonus"))
@@ -69,3 +74,18 @@ def handler(fit, module, context):
"capacitorNeed", module.getModifiedItemAttr("triageRemoteModuleCapNeed"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Shield Emission Systems"),
"capacitorNeed", module.getModifiedItemAttr("triageRemoteModuleCapNeed"))
fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Capital Capacitor Emission Systems"),
"capacitorNeed", module.getModifiedItemAttr("triageRemoteModuleCapNeed"))
# EW cap need increase
groups = [
'ECM Burst',
'Remote ECM Burst',
'Tracking Disruptor',
'ECM',
'Remote Sensor Damper',
'Target Painter']
fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups or
mod.item.requiresSkill("Propulsion Jamming"),
"capacitorNeed", module.getModifiedItemAttr("ewCapacitorNeedBonus"))

View File

@@ -24,6 +24,7 @@ from sqlalchemy.orm import reconstructor
from eqBase import EqBase
import traceback
import eos.db
try:
from collections import OrderedDict
@@ -168,7 +169,6 @@ class Item(EqBase):
info = getattr(cls, "MOVE_ATTR_INFO", None)
if info is None:
cls.MOVE_ATTR_INFO = info = []
import eos.db
for id in cls.MOVE_ATTRS:
info.append(eos.db.getAttributeInfo(id))
@@ -191,6 +191,7 @@ class Item(EqBase):
self.__moved = False
self.__offensive = None
self.__assistive = None
self.__overrides = None
@property
def attributes(self):
@@ -210,6 +211,32 @@ class Item(EqBase):
return False
@property
def overrides(self):
if self.__overrides is None:
self.__overrides = {}
overrides = eos.db.getOverrides(self.ID)
for x in overrides:
if x.attr.name in self.__attributes:
self.__overrides[x.attr.name] = x
return self.__overrides
def setOverride(self, attr, value):
from eos.saveddata.override import Override
if attr.name in self.__overrides:
override = self.__overrides.get(attr.name)
override.value = value
else:
override = Override(self, attr, value)
self.__overrides[attr.name] = override
eos.db.save(override)
def deleteOverride(self, attr):
override = self.__overrides.pop(attr.name, None)
eos.db.saveddata_session.delete(override)
eos.db.commit()
@property
def requiredSkills(self):
if self.__requiredSkills is None:
@@ -345,6 +372,12 @@ class Item(EqBase):
return False
def __repr__(self):
return "Item(ID={}, name={}) at {}".format(
self.ID, self.name, hex(id(self))
)
class MetaData(EqBase):
pass

View File

@@ -43,7 +43,8 @@ class FitDpsGraph(Graph):
if "ewTargetPaint" in mod.item.effects:
ew['signatureRadius'].append(1+(mod.getModifiedItemAttr("signatureRadiusBonus") / 100))
if "decreaseTargetSpeed" in mod.item.effects:
ew['velocity'].append(1+(mod.getModifiedItemAttr("speedFactor") / 100))
if distance <= mod.getModifiedItemAttr("maxRange"):
ew['velocity'].append(1+(mod.getModifiedItemAttr("speedFactor") / 100))
ew['signatureRadius'].sort(key=abssort)
ew['velocity'].sort(key=abssort)

View File

@@ -38,6 +38,9 @@ class ChargeAttrShortcut(object):
return None
class ModifiedAttributeDict(collections.MutableMapping):
OVERRIDES = False
class CalculationPlaceholder():
pass
@@ -51,6 +54,8 @@ class ModifiedAttributeDict(collections.MutableMapping):
self.__modified = {}
# Affected by entities
self.__affectedBy = {}
# Overrides
self.__overrides = {}
# Dictionaries for various value modification types
self.__forced = {}
self.__preAssigns = {}
@@ -79,6 +84,14 @@ class ModifiedAttributeDict(collections.MutableMapping):
self.__original = val
self.__modified.clear()
@property
def overrides(self):
return self.__overrides
@overrides.setter
def overrides(self, val):
self.__overrides = val
def __getitem__(self, key):
# Check if we have final calculated value
if key in self.__modified:
@@ -99,6 +112,8 @@ class ModifiedAttributeDict(collections.MutableMapping):
del self.__intermediary[key]
def getOriginal(self, key):
if self.OVERRIDES and key in self.__overrides:
return self.__overrides.get(key).value
val = self.__original.get(key)
if val is None:
return None
@@ -285,7 +300,7 @@ class ModifiedAttributeDict(collections.MutableMapping):
else:
if not attributeName in self.__multipliers:
self.__multipliers[attributeName] = 1
self.__multipliers[attributeName] *= multiplier
self.__multipliers[attributeName] *= multiplier if multiplier is not None else 1
self.__placehold(attributeName)
self.__afflict(attributeName, "%s*" % ("s" if stackingPenalties else ""), multiplier, multiplier != 1)

View File

@@ -58,6 +58,7 @@ class Booster(HandledItem, ItemAttrShortcut):
self.__sideEffects = []
self.__itemModifiedAttributes = ModifiedAttributeDict()
self.__itemModifiedAttributes.original = self.__item.attributes
self.__itemModifiedAttributes.overrides = self.__item.overrides
self.__slot = self.__calculateSlot(self.__item)
for effect in self.__item.effects.itervalues():

View File

@@ -34,6 +34,7 @@ class Cargo(HandledItem, ItemAttrShortcut):
self.amount = 0
self.__itemModifiedAttributes = ModifiedAttributeDict()
self.__itemModifiedAttributes.original = item.attributes
self.__itemModifiedAttributes.overrides = item.overrides
@reconstructor
def init(self):
@@ -48,6 +49,7 @@ class Cargo(HandledItem, ItemAttrShortcut):
self.__itemModifiedAttributes = ModifiedAttributeDict()
self.__itemModifiedAttributes.original = self.__item.attributes
self.__itemModifiedAttributes.overrides = self.__item.overrides
@property
def itemModifiedAttributes(self):

View File

@@ -23,7 +23,9 @@ from sqlalchemy.orm import validates, reconstructor
from eos.effectHandlerHelpers import HandledItem, HandledImplantBoosterList
import eos.db
import eos
import logging
logger = logging.getLogger(__name__)
class Character(object):
__itemList = None
@@ -221,6 +223,11 @@ class Character(object):
if map[key](val) == False: raise ValueError(str(val) + " is not a valid value for " + key)
else: return val
def __repr__(self):
return "Character(ID={}, name={}) at {}".format(
self.ID, self.name, hex(id(self))
)
class Skill(HandledItem):
def __init__(self, item, level=0, ro=False, learned=True):
self.__item = item if not isinstance(item, int) else None

View File

@@ -0,0 +1,46 @@
#===============================================================================
# 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/>.
#===============================================================================
import urllib
from cStringIO import StringIO
from sqlalchemy.orm import reconstructor
#from tomorrow import threads
class CrestChar(object):
def __init__(self, id, name, refresh_token=None):
self.ID = id
self.name = name
self.refresh_token = refresh_token
@reconstructor
def init(self):
pass
'''
@threads(1)
def fetchImage(self):
url = 'https://image.eveonline.com/character/%d_128.jpg'%self.ID
fp = urllib.urlopen(url)
data = fp.read()
fp.close()
self.img = StringIO(data)
'''

View File

@@ -67,6 +67,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
self.__miningyield = None
self.__itemModifiedAttributes = ModifiedAttributeDict()
self.__itemModifiedAttributes.original = self.__item.attributes
self.__itemModifiedAttributes.overrides = self.__item.overrides
self.__chargeModifiedAttributes = ModifiedAttributeDict()
chargeID = self.getModifiedItemAttr("entityMissileTypeID")
@@ -74,6 +75,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
charge = eos.db.getItem(int(chargeID))
self.__charge = charge
self.__chargeModifiedAttributes.original = charge.attributes
self.__chargeModifiedAttributes.overrides = charge.overrides
@property
def itemModifiedAttributes(self):

View File

@@ -25,7 +25,7 @@ from eos import capSim
from copy import deepcopy
from math import sqrt, log, asinh
from eos.types import Drone, Cargo, Ship, Character, State, Slot, Module, Implant, Booster, Skill
from eos.saveddata.module import State
from eos.saveddata.module import State, Hardpoint
from eos.saveddata.mode import Mode
import eos.db
import time
@@ -390,9 +390,9 @@ class Fit(object):
self.__modifier = currModifier
self.__origin = origin
if hasattr(currModifier, "itemModifiedAttributes"):
currModifier.itemModifiedAttributes.fit = self
currModifier.itemModifiedAttributes.fit = origin or self
if hasattr(currModifier, "chargeModifiedAttributes"):
currModifier.chargeModifiedAttributes.fit = self
currModifier.chargeModifiedAttributes.fit = origin or self
def getModifier(self):
return self.__modifier
@@ -480,17 +480,22 @@ class Fit(object):
self.__calculated = True
for runTime in ("early", "normal", "late"):
c = chain(
# Items that are unrestricted. These items are run on the local fit
# first and then projected onto the target fit it one is designated
u = [
(self.character, self.ship),
self.drones,
self.boosters,
self.appliedImplants,
self.modules
)
]
if not projected:
# if not a projected fit, add a couple of more things
c = chain(c, (self.mode,), self.projectedDrones, self.projectedModules)
# Items that are restricted. These items are only run on the local
# fit. They are NOT projected onto the target fit. # See issue 354
r = [(self.mode,), self.projectedDrones, self.projectedModules]
# chain unrestricted and restricted into one iterable
c = chain.from_iterable(u+r)
# We calculate gang bonuses first so that projected fits get them
if self.gangBoosts is not None:
@@ -500,9 +505,12 @@ class Fit(object):
# Registering the item about to affect the fit allows us to
# track "Affected By" relations correctly
if item is not None:
# apply effects locally
self.register(item)
item.calculateModifiedAttributes(self, runTime, False)
if projected is True:
if projected is True and item not in chain.from_iterable(r):
# apply effects onto target fit
for _ in xrange(projectionInfo.amount):
targetFit.register(item, origin=self)
item.calculateModifiedAttributes(targetFit, runTime, True)
@@ -839,10 +847,14 @@ class Fit(object):
else:
capAdded -= capNeed
drains.append((int(fullCycleTime), mod.getModifiedItemAttr("capacitorNeed") or 0, mod.numShots or 0))
# If this is a turret, don't stagger activations
disableStagger = mod.hardpoint == Hardpoint.TURRET
drains.append((int(fullCycleTime), mod.getModifiedItemAttr("capacitorNeed") or 0, mod.numShots or 0, disableStagger))
for fullCycleTime, capNeed, clipSize in self.iterDrains():
drains.append((int(fullCycleTime), capNeed, clipSize))
# Stagger incoming effects for cap simulation
drains.append((int(fullCycleTime), capNeed, clipSize, False))
if capNeed > 0:
capUsed += capNeed / (fullCycleTime / 1000.0)
else:

View File

@@ -56,6 +56,7 @@ class Implant(HandledItem, ItemAttrShortcut):
""" Build object. Assumes proper and valid item already set """
self.__itemModifiedAttributes = ModifiedAttributeDict()
self.__itemModifiedAttributes.original = self.__item.attributes
self.__itemModifiedAttributes.overrides = self.__item.overrides
self.__slot = self.__calculateSlot(self.__item)
@property

View File

@@ -30,6 +30,7 @@ class Mode(ItemAttrShortcut, HandledItem):
self.__item = item
self.__itemModifiedAttributes = ModifiedAttributeDict()
self.__itemModifiedAttributes.original = self.item.attributes
self.__itemModifiedAttributes.overrides = self.item.overrides
@property
def item(self):

View File

@@ -113,10 +113,13 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
if self.__item:
self.__itemModifiedAttributes.original = self.__item.attributes
self.__itemModifiedAttributes.overrides = self.__item.overrides
self.__hardpoint = self.__calculateHardpoint(self.__item)
self.__slot = self.__calculateSlot(self.__item)
if self.__charge:
self.__chargeModifiedAttributes.original = self.__charge.attributes
self.__chargeModifiedAttributes.overrides = self.__charge.overrides
@classmethod
def buildEmpty(cls, slot):
@@ -283,9 +286,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
if charge is not None:
self.chargeID = charge.ID
self.__chargeModifiedAttributes.original = charge.attributes
self.__chargeModifiedAttributes.overrides = charge.overrides
else:
self.chargeID = None
self.__chargeModifiedAttributes.original = None
self.__chargeModifiedAttributes.overrides = {}
self.__itemModifiedAttributes.clear()
@@ -316,7 +321,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
self.__miningyield = 0
else:
if self.state >= State.ACTIVE:
volley = sum(map(lambda attr: self.getModifiedItemAttr(attr) or 0, self.MINING_ATTRIBUTES))
volley = self.getModifiedItemAttr("specialtyMiningAmount") or self.getModifiedItemAttr("miningAmount") or 0
if volley:
cycleTime = self.cycleTime
self.__miningyield = volley / (cycleTime / 1000.0)

59
eos/saveddata/override.py Normal file
View File

@@ -0,0 +1,59 @@
#===============================================================================
# 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 eos.eqBase import EqBase
from sqlalchemy.orm import validates, reconstructor
import eos.db
import logging
logger = logging.getLogger(__name__)
class Override(EqBase):
def __init__(self, item, attr, value):
self.itemID = item.ID
self.__item = item
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:
logger.error("Attribute (id: %d) does not exist", self.attrID)
return
if self.itemID:
self.__item = eos.db.getItem(self.itemID)
if self.__item is None:
logger.error("Item (id: %d) does not exist", self.itemID)
return
@property
def attr(self):
return self.__attr
@property
def item(self):
return self.__item

View File

@@ -51,6 +51,7 @@ class Ship(ItemAttrShortcut, HandledItem):
self.__itemModifiedAttributes = ModifiedAttributeDict()
self.__itemModifiedAttributes.original = dict(self.item.attributes)
self.__itemModifiedAttributes.original.update(self.EXTRA_ATTRIBUTES)
self.__itemModifiedAttributes.overrides = self.item.overrides
self.commandBonus = 0
@@ -121,3 +122,8 @@ class Ship(ItemAttrShortcut, HandledItem):
def __deepcopy__(self, memo):
copy = Ship(self.item)
return copy
def __repr__(self):
return "Ship(ID={}, name={}) at {}".format(
self.item.ID, self.item.name, hex(id(self))
)

View File

@@ -21,6 +21,7 @@ from eos.gamedata import Attribute, Category, Effect, Group, Icon, Item, MarketG
MetaGroup, AttributeInfo, Unit, EffectInfo, MetaType, MetaData, Traits
from eos.saveddata.price import Price
from eos.saveddata.user import User
from eos.saveddata.crestchar import CrestChar
from eos.saveddata.damagePattern import DamagePattern
from eos.saveddata.targetResists import TargetResists
from eos.saveddata.character import Character, Skill
@@ -35,4 +36,5 @@ from eos.saveddata.fit import Fit
from eos.saveddata.mode import Mode
from eos.saveddata.fleet import Fleet, Wing, Squad
from eos.saveddata.miscData import MiscData
from eos.saveddata.override import Override
import eos.db