Reformatting eos.saveddata
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,16 +15,19 @@
|
||||
#
|
||||
# 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.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from sqlalchemy.orm import reconstructor, validates
|
||||
import eos.db
|
||||
import logging
|
||||
|
||||
from sqlalchemy.orm import reconstructor, validates
|
||||
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Booster(HandledItem, ItemAttrShortcut):
|
||||
def __init__(self, item):
|
||||
self.__item = item
|
||||
@@ -103,7 +106,7 @@ class Booster(HandledItem, ItemAttrShortcut):
|
||||
def clear(self):
|
||||
self.itemModifiedAttributes.clear()
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected=False):
|
||||
if forceProjected: return
|
||||
if not self.active: return
|
||||
for effect in self.item.effects.itervalues():
|
||||
@@ -117,13 +120,15 @@ class Booster(HandledItem, ItemAttrShortcut):
|
||||
@validates("ID", "itemID", "ammoID", "active")
|
||||
def validator(self, key, val):
|
||||
map = {"ID": lambda val: isinstance(val, int),
|
||||
"itemID" : lambda val: isinstance(val, int),
|
||||
"ammoID" : lambda val: isinstance(val, int),
|
||||
"active" : lambda val: isinstance(val, bool),
|
||||
"slot" : lambda val: isinstance(val, int) and 1 <= val <= 3}
|
||||
"itemID": lambda val: isinstance(val, int),
|
||||
"ammoID": lambda val: isinstance(val, int),
|
||||
"active": lambda val: isinstance(val, bool),
|
||||
"slot": lambda val: isinstance(val, int) and 1 <= val <= 3}
|
||||
|
||||
if not map[key](val): raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else:
|
||||
return val
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Booster(self.item)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,18 +15,20 @@
|
||||
#
|
||||
# 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.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledCharge
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
import eos.db
|
||||
import logging
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Cargo(HandledItem, ItemAttrShortcut):
|
||||
|
||||
class Cargo(HandledItem, ItemAttrShortcut):
|
||||
def __init__(self, item):
|
||||
"""Initialize cargo from the program"""
|
||||
self.__item = item
|
||||
@@ -69,10 +71,12 @@ class Cargo(HandledItem, ItemAttrShortcut):
|
||||
@validates("fitID", "itemID")
|
||||
def validator(self, key, val):
|
||||
map = {"fitID": lambda val: isinstance(val, int),
|
||||
"itemID" : lambda val: isinstance(val, int)}
|
||||
"itemID": lambda val: isinstance(val, int)}
|
||||
|
||||
if not map[key](val): raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else:
|
||||
return val
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Cargo(self.item)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,20 +15,22 @@
|
||||
#
|
||||
# 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.orm import validates, reconstructor
|
||||
import logging
|
||||
from itertools import chain
|
||||
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledImplantBoosterList
|
||||
import eos.db
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
import eos
|
||||
import eos.db
|
||||
import eos.types
|
||||
import logging
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledImplantBoosterList
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Character(object):
|
||||
__itemList = None
|
||||
__itemIDMap = None
|
||||
@@ -211,7 +213,7 @@ class Character(object):
|
||||
if filter(element):
|
||||
element.boostItemAttr(*args, **kwargs)
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected=False):
|
||||
if forceProjected: return
|
||||
for skill in self.skills:
|
||||
fit.register(skill)
|
||||
@@ -239,18 +241,21 @@ class Character(object):
|
||||
@validates("ID", "name", "apiKey", "ownerID")
|
||||
def validator(self, key, val):
|
||||
map = {"ID": lambda val: isinstance(val, int),
|
||||
"name" : lambda val: True,
|
||||
"apiKey" : lambda val: val is None or (isinstance(val, basestring) and len(val) > 0),
|
||||
"ownerID" : lambda val: isinstance(val, int) or val is None}
|
||||
"name": lambda val: True,
|
||||
"apiKey": lambda val: val is None or (isinstance(val, basestring) and len(val) > 0),
|
||||
"ownerID": lambda val: isinstance(val, int) or val is None}
|
||||
|
||||
if not map[key](val): raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
if not map[key](val):
|
||||
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
|
||||
@@ -304,13 +309,12 @@ class Skill(HandledItem):
|
||||
if self.activeLevel == self.__level and self in self.character.dirtySkills:
|
||||
self.character.dirtySkills.remove(self)
|
||||
|
||||
|
||||
@property
|
||||
def item(self):
|
||||
if self.__item is None:
|
||||
self.__item = item = Character.getSkillIDMap().get(self.itemID)
|
||||
if item is None:
|
||||
#This skill is no longer in the database and thus invalid it, get rid of it.
|
||||
# This skill is no longer in the database and thus invalid it, get rid of it.
|
||||
self.character.removeSkill(self)
|
||||
|
||||
return self.__item
|
||||
@@ -322,7 +326,7 @@ class Skill(HandledItem):
|
||||
return None
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime):
|
||||
if self.__suppressed: # or not self.learned - removed for GH issue 101
|
||||
if self.__suppressed: # or not self.learned - removed for GH issue 101
|
||||
return
|
||||
|
||||
item = self.item
|
||||
@@ -330,7 +334,8 @@ class Skill(HandledItem):
|
||||
return
|
||||
|
||||
for effect in item.effects.itervalues():
|
||||
if effect.runTime == runTime and effect.isType("passive") and (not fit.isStructure or effect.isType("structure")):
|
||||
if effect.runTime == runTime and effect.isType("passive") and (
|
||||
not fit.isStructure or effect.isType("structure")):
|
||||
try:
|
||||
effect.handler(fit, self, ("skill",))
|
||||
except AttributeError:
|
||||
@@ -352,10 +357,12 @@ class Skill(HandledItem):
|
||||
raise ReadOnlyException()
|
||||
|
||||
map = {"characterID": lambda val: isinstance(val, int),
|
||||
"skillID" : lambda val: isinstance(val, int)}
|
||||
"skillID": lambda val: isinstance(val, int)}
|
||||
|
||||
if not map[key](val): raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else:
|
||||
return val
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Skill(self.item, self.level, self.__ro)
|
||||
@@ -366,5 +373,6 @@ class Skill(HandledItem):
|
||||
self.item.ID, self.item.name, hex(id(self))
|
||||
)
|
||||
|
||||
|
||||
class ReadOnlyException(Exception):
|
||||
pass
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,22 +15,20 @@
|
||||
#
|
||||
# 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.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from eos.saveddata.mode import Mode
|
||||
import eos.db
|
||||
from eos.types import Ship
|
||||
import logging
|
||||
|
||||
from eos.types import Ship
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Citadel(Ship):
|
||||
|
||||
class Citadel(Ship):
|
||||
def validate(self, item):
|
||||
if item.category.name != "Structure":
|
||||
raise ValueError('Passed item "%s" (category: (%s)) is not under Structure category'%(item.name, item.category.name))
|
||||
raise ValueError(
|
||||
'Passed item "%s" (category: (%s)) is not under Structure category' % (item.name, item.category.name))
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Citadel(self.item)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,17 +15,15 @@
|
||||
#
|
||||
# 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
|
||||
|
||||
|
||||
# from tomorrow import threads
|
||||
|
||||
|
||||
class CrestChar(object):
|
||||
|
||||
def __init__(self, id, name, refresh_token=None):
|
||||
self.ID = id
|
||||
self.name = name
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,14 +15,15 @@
|
||||
#
|
||||
# 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 re
|
||||
|
||||
|
||||
class DamagePattern(object):
|
||||
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
|
||||
|
||||
def __init__(self, emAmount = 25, thermalAmount = 25, kineticAmount = 25, explosiveAmount = 25):
|
||||
def __init__(self, emAmount=25, thermalAmount=25, kineticAmount=25, explosiveAmount=25):
|
||||
self.emAmount = emAmount
|
||||
self.thermalAmount = thermalAmount
|
||||
self.kineticAmount = kineticAmount
|
||||
@@ -50,7 +51,7 @@ class DamagePattern(object):
|
||||
totalDamage = sum((self.emAmount, self.thermalAmount, self.kineticAmount, self.explosiveAmount))
|
||||
specificDivider = 0
|
||||
for damageType in self.DAMAGE_TYPES:
|
||||
#Compose an attribute name, then make sure the first letter is NOT capitalized
|
||||
# Compose an attribute name, then make sure the first letter is NOT capitalized
|
||||
attrName = "%s%sDamageResonance" % (type, damageType.capitalize())
|
||||
attrName = attrName[0].lower() + attrName[1:]
|
||||
|
||||
@@ -65,6 +66,7 @@ class DamagePattern(object):
|
||||
"therm": "thermal",
|
||||
"kin": "kinetic",
|
||||
"exp": "explosive"}
|
||||
|
||||
@classmethod
|
||||
def importPatterns(cls, text):
|
||||
lines = re.split('[\n\r]+', text)
|
||||
@@ -74,8 +76,8 @@ class DamagePattern(object):
|
||||
try:
|
||||
if line.strip()[0] == "#": # comments
|
||||
continue
|
||||
line = line.split('#',1)[0] # allows for comments
|
||||
type, data = line.rsplit('=',1)
|
||||
line = line.split('#', 1)[0] # allows for comments
|
||||
type, data = line.rsplit('=', 1)
|
||||
type, data = type.strip(), data.split(',')
|
||||
except:
|
||||
# Data isn't in correct format, continue to next line
|
||||
@@ -94,7 +96,7 @@ class DamagePattern(object):
|
||||
except:
|
||||
continue
|
||||
|
||||
if len(fields) == 4: # Avoid possible blank lines
|
||||
if len(fields) == 4: # Avoid possible blank lines
|
||||
pattern = DamagePattern(**fields)
|
||||
pattern.name = name.strip()
|
||||
patterns.append(pattern)
|
||||
@@ -102,9 +104,10 @@ class DamagePattern(object):
|
||||
return patterns, numPatterns
|
||||
|
||||
EXPORT_FORMAT = "DamageProfile = %s,%d,%d,%d,%d\n"
|
||||
|
||||
@classmethod
|
||||
def exportPatterns(cls, *patterns):
|
||||
out = "# Exported from pyfa\n#\n"
|
||||
out = "# Exported from pyfa\n#\n"
|
||||
out += "# Values are in following format:\n"
|
||||
out += "# DamageProfile = [name],[EM amount],[Thermal amount],[Kinetic amount],[Explosive amount]\n\n"
|
||||
for dp in patterns:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,16 +15,19 @@
|
||||
#
|
||||
# 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.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledCharge
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
import eos.db
|
||||
import logging
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledCharge
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
DAMAGE_TYPES = ("em", "kinetic", "explosive", "thermal")
|
||||
MINING_ATTRIBUTES = ("miningAmount",)
|
||||
@@ -116,7 +119,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
def dps(self):
|
||||
return self.damageStats()
|
||||
|
||||
def damageStats(self, targetResists = None):
|
||||
def damageStats(self, targetResists=None):
|
||||
if self.__dps is None:
|
||||
self.__volley = 0
|
||||
self.__dps = 0
|
||||
@@ -125,12 +128,14 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
attr = "missileLaunchDuration"
|
||||
getter = self.getModifiedChargeAttr
|
||||
else:
|
||||
attr = "speed"
|
||||
attr = "speed"
|
||||
getter = self.getModifiedItemAttr
|
||||
|
||||
cycleTime = self.getModifiedItemAttr(attr)
|
||||
|
||||
volley = sum(map(lambda d: (getter("%sDamage"%d) or 0) * (1-getattr(targetResists, "%sAmount"%d, 0)), self.DAMAGE_TYPES))
|
||||
volley = sum(
|
||||
map(lambda d: (getter("%sDamage" % d) or 0) * (1 - getattr(targetResists, "%sAmount" % d, 0)),
|
||||
self.DAMAGE_TYPES))
|
||||
volley *= self.amountActive
|
||||
volley *= self.getModifiedItemAttr("damageMultiplier") or 1
|
||||
self.__volley = volley
|
||||
@@ -180,13 +185,15 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
@validates("ID", "itemID", "chargeID", "amount", "amountActive")
|
||||
def validator(self, key, val):
|
||||
map = {"ID": lambda val: isinstance(val, int),
|
||||
"itemID" : lambda val: isinstance(val, int),
|
||||
"chargeID" : lambda val: isinstance(val, int),
|
||||
"amount" : lambda val: isinstance(val, int) and val >= 0,
|
||||
"amountActive" : lambda val: isinstance(val, int) and self.amount >= val >= 0}
|
||||
"itemID": lambda val: isinstance(val, int),
|
||||
"chargeID": lambda val: isinstance(val, int),
|
||||
"amount": lambda val: isinstance(val, int) and val >= 0,
|
||||
"amountActive": lambda val: isinstance(val, int) and self.amount >= val >= 0}
|
||||
|
||||
if not map[key](val): raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else:
|
||||
return val
|
||||
|
||||
def clear(self):
|
||||
self.__dps = None
|
||||
@@ -213,7 +220,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
else:
|
||||
return True
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected=False):
|
||||
if self.projected or forceProjected:
|
||||
context = "projected", "drone"
|
||||
projected = True
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,14 +15,15 @@
|
||||
#
|
||||
# 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.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledCharge, HandledDroneCargoList
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
import eos.db
|
||||
from eos.enum import Enum
|
||||
import logging
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledCharge
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
|
||||
from eos.types import FighterAbility, Slot
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -155,7 +156,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
def dps(self):
|
||||
return self.damageStats()
|
||||
|
||||
def damageStats(self, targetResists = None):
|
||||
def damageStats(self, targetResists=None):
|
||||
if self.__dps is None:
|
||||
self.__volley = 0
|
||||
self.__dps = 0
|
||||
@@ -164,7 +165,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
dps, volley = ability.damageStats(targetResists)
|
||||
self.__dps += dps
|
||||
self.__volley += volley
|
||||
|
||||
|
||||
# For forward compatability this assumes a fighter can have more than 2 damaging abilities and/or multiple that use charges.
|
||||
if self.owner.factorReload:
|
||||
activeTimes = []
|
||||
@@ -179,7 +180,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
continue
|
||||
activeTimes.append(ability.numShots * ability.cycleTime)
|
||||
reloadTimes.append(ability.reloadTime)
|
||||
|
||||
|
||||
if len(activeTimes) > 0:
|
||||
shortestActive = sorted(activeTimes)[0]
|
||||
longestReload = sorted(reloadTimes, reverse=True)[0]
|
||||
@@ -214,13 +215,15 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
@validates("ID", "itemID", "chargeID", "amount", "amountActive")
|
||||
def validator(self, key, val):
|
||||
map = {"ID": lambda val: isinstance(val, int),
|
||||
"itemID" : lambda val: isinstance(val, int),
|
||||
"chargeID" : lambda val: isinstance(val, int),
|
||||
"amount" : lambda val: isinstance(val, int) and val >= -1,
|
||||
"itemID": lambda val: isinstance(val, int),
|
||||
"chargeID": lambda val: isinstance(val, int),
|
||||
"amount": lambda val: isinstance(val, int) and val >= -1,
|
||||
}
|
||||
|
||||
if not map[key](val): raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else:
|
||||
return val
|
||||
|
||||
def clear(self):
|
||||
self.__dps = None
|
||||
@@ -248,7 +251,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
else:
|
||||
return True
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected=False):
|
||||
if not self.active:
|
||||
return
|
||||
|
||||
@@ -263,7 +266,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if ability.active:
|
||||
effect = ability.effect
|
||||
if effect.runTime == runTime and \
|
||||
((projected and effect.isType("projected")) or not projected):
|
||||
((projected and effect.isType("projected")) or not projected):
|
||||
if ability.grouped:
|
||||
effect.handler(fit, self, context)
|
||||
else:
|
||||
@@ -283,4 +286,3 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,13 +15,15 @@
|
||||
#
|
||||
# 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.orm import validates, reconstructor
|
||||
import logging
|
||||
|
||||
from sqlalchemy.orm import reconstructor
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FighterAbility(object):
|
||||
DAMAGE_TYPES = ("em", "kinetic", "explosive", "thermal")
|
||||
DAMAGE_TYPES2 = ("EM", "Kin", "Exp", "Therm")
|
||||
@@ -30,18 +32,17 @@ class FighterAbility(object):
|
||||
# with the fighter squadron role
|
||||
NUM_SHOTS_MAPPING = {
|
||||
1: 0, # Superiority fighter / Attack
|
||||
2: 12, # Light fighter / Attack
|
||||
2: 12, # Light fighter / Attack
|
||||
4: 6, # Heavy fighter / Heavy attack
|
||||
5: 3, # Heavy fighter / Long range attack
|
||||
}
|
||||
# Same as above
|
||||
REARM_TIME_MAPPING = {
|
||||
1: 0, # Superiority fighter / Attack
|
||||
1: 0, # Superiority fighter / Attack
|
||||
2: 4000, # Light fighter / Attack
|
||||
4: 6000, # Heavy fighter / Heavy attack
|
||||
5: 20000, # Heavy fighter / Long range attack
|
||||
5: 20000, # Heavy fighter / Long range attack
|
||||
}
|
||||
|
||||
|
||||
def __init__(self, effect):
|
||||
"""Initialize from the program"""
|
||||
@@ -94,11 +95,14 @@ class FighterAbility(object):
|
||||
|
||||
@property
|
||||
def reloadTime(self):
|
||||
return self.fighter.getModifiedItemAttr("fighterRefuelingTime") + (self.REARM_TIME_MAPPING[self.fighter.getModifiedItemAttr("fighterSquadronRole")] or 0 if self.hasCharges else 0) * self.numShots
|
||||
return self.fighter.getModifiedItemAttr("fighterRefuelingTime") + (self.REARM_TIME_MAPPING[
|
||||
self.fighter.getModifiedItemAttr(
|
||||
"fighterSquadronRole")] or 0 if self.hasCharges else 0) * self.numShots
|
||||
|
||||
@property
|
||||
def numShots(self):
|
||||
return self.NUM_SHOTS_MAPPING[self.fighter.getModifiedItemAttr("fighterSquadronRole")] or 0 if self.hasCharges else 0
|
||||
return self.NUM_SHOTS_MAPPING[
|
||||
self.fighter.getModifiedItemAttr("fighterSquadronRole")] or 0 if self.hasCharges else 0
|
||||
|
||||
@property
|
||||
def cycleTime(self):
|
||||
@@ -126,7 +130,7 @@ class FighterAbility(object):
|
||||
if self.attrPrefix == "fighterAbilityLaunchBomb":
|
||||
# bomb calcs
|
||||
volley = sum(map(lambda attr: (self.fighter.getModifiedChargeAttr("%sDamage" % attr) or 0) * (
|
||||
1 - getattr(targetResists, "%sAmount" % attr, 0)), self.DAMAGE_TYPES))
|
||||
1 - getattr(targetResists, "%sAmount" % attr, 0)), self.DAMAGE_TYPES))
|
||||
else:
|
||||
volley = sum(map(lambda d2, d:
|
||||
(self.fighter.getModifiedItemAttr(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,26 +15,24 @@
|
||||
#
|
||||
# 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.effectHandlerHelpers import *
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
from itertools import chain
|
||||
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, Citadel
|
||||
from eos.saveddata.module import State, Hardpoint
|
||||
from eos.saveddata.mode import Mode
|
||||
import eos.db
|
||||
import time
|
||||
import copy
|
||||
from utils.timer import Timer
|
||||
from eos.enum import Enum
|
||||
|
||||
|
||||
import logging
|
||||
import time
|
||||
from copy import deepcopy
|
||||
from itertools import chain
|
||||
from math import sqrt, log, asinh
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
import eos.db
|
||||
from eos import capSim
|
||||
from eos.effectHandlerHelpers import *
|
||||
from eos.enum import Enum
|
||||
from eos.saveddata.module import State, Hardpoint
|
||||
from eos.types import Ship, Character, Slot, Module, Citadel
|
||||
from utils.timer import Timer
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -43,6 +41,7 @@ try:
|
||||
except ImportError:
|
||||
from utils.compat import OrderedDict
|
||||
|
||||
|
||||
class ImplantLocation(Enum):
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -50,6 +49,7 @@ class ImplantLocation(Enum):
|
||||
FIT = 0
|
||||
CHARACTER = 1
|
||||
|
||||
|
||||
class Fit(object):
|
||||
"""Represents a fitting, with modules, ship, implants, etc."""
|
||||
|
||||
@@ -68,7 +68,7 @@ class Fit(object):
|
||||
self.__cargo = HandledDroneCargoList()
|
||||
self.__implants = HandledImplantBoosterList()
|
||||
self.__boosters = HandledImplantBoosterList()
|
||||
#self.__projectedFits = {}
|
||||
# self.__projectedFits = {}
|
||||
self.__projectedModules = HandledProjectedModList()
|
||||
self.__projectedDrones = HandledProjectedDroneList()
|
||||
self.__projectedFighters = HandledProjectedDroneList()
|
||||
@@ -302,7 +302,8 @@ class Fit(object):
|
||||
|
||||
@property
|
||||
def maxTargets(self):
|
||||
return min(self.extraAttributes["maxTargetsLockedFromSkills"], self.ship.getModifiedItemAttr("maxLockedTargets"))
|
||||
return min(self.extraAttributes["maxTargetsLockedFromSkills"],
|
||||
self.ship.getModifiedItemAttr("maxLockedTargets"))
|
||||
|
||||
@property
|
||||
def maxTargetRange(self):
|
||||
@@ -329,7 +330,7 @@ class Fit(object):
|
||||
|
||||
@property
|
||||
def jamChance(self):
|
||||
return (1-self.ecmProjectedStr)*100
|
||||
return (1 - self.ecmProjectedStr) * 100
|
||||
|
||||
@property
|
||||
def maxSpeed(self):
|
||||
@@ -364,11 +365,13 @@ class Fit(object):
|
||||
@validates("ID", "ownerID", "shipID")
|
||||
def validator(self, key, val):
|
||||
map = {"ID": lambda val: isinstance(val, int),
|
||||
"ownerID" : lambda val: isinstance(val, int) or val is None,
|
||||
"shipID" : lambda val: isinstance(val, int) or val is None}
|
||||
"ownerID": lambda val: isinstance(val, int) or val is None,
|
||||
"shipID": lambda val: isinstance(val, int) or val is None}
|
||||
|
||||
if not map[key](val): raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else:
|
||||
return val
|
||||
|
||||
def clear(self, projected=False):
|
||||
self.__effectiveTank = None
|
||||
@@ -417,8 +420,8 @@ class Fit(object):
|
||||
if stuff is not None and stuff != self:
|
||||
stuff.clear(projected=True)
|
||||
|
||||
#Methods to register and get the thing currently affecting the fit,
|
||||
#so we can correctly map "Affected By"
|
||||
# Methods to register and get the thing currently affecting the fit,
|
||||
# so we can correctly map "Affected By"
|
||||
def register(self, currModifier, origin=None):
|
||||
self.__modifier = currModifier
|
||||
self.__origin = origin
|
||||
@@ -442,7 +445,7 @@ class Fit(object):
|
||||
context = ("gang", thing.__class__.__name__.lower())
|
||||
if isinstance(thing, Module):
|
||||
if effect.isType("offline") or (effect.isType("passive") and thing.state >= State.ONLINE) or \
|
||||
(effect.isType("active") and thing.state >= State.ACTIVE):
|
||||
(effect.isType("active") and thing.state >= State.ACTIVE):
|
||||
# Run effect, and get proper bonuses applied
|
||||
try:
|
||||
self.register(thing)
|
||||
@@ -486,7 +489,7 @@ class Fit(object):
|
||||
logger.debug("Fleet is set, gathering gang boosts")
|
||||
self.gangBoosts = self.fleet.recalculateLinear(withBoosters=withBoosters)
|
||||
|
||||
timer.checkpoint("Done calculating gang boosts for %r"%self)
|
||||
timer.checkpoint("Done calculating gang boosts for %r" % self)
|
||||
elif self.fleet is None:
|
||||
self.gangBoosts = None
|
||||
|
||||
@@ -537,7 +540,7 @@ class Fit(object):
|
||||
r = [(self.mode,), self.projectedDrones, self.projectedFighters, self.projectedModules]
|
||||
|
||||
# chain unrestricted and restricted into one iterable
|
||||
c = chain.from_iterable(u+r)
|
||||
c = chain.from_iterable(u + r)
|
||||
|
||||
# We calculate gang bonuses first so that projected fits get them
|
||||
if self.gangBoosts is not None:
|
||||
@@ -558,7 +561,7 @@ class Fit(object):
|
||||
targetFit.register(item, origin=self)
|
||||
item.calculateModifiedAttributes(targetFit, runTime, True)
|
||||
|
||||
timer.checkpoint('Done with runtime: %s'%runTime)
|
||||
timer.checkpoint('Done with runtime: %s' % runTime)
|
||||
|
||||
# Mark fit as calculated
|
||||
self.__calculated = True
|
||||
@@ -591,7 +594,7 @@ class Fit(object):
|
||||
self.modules.append(Module.buildEmpty(slotType))
|
||||
|
||||
if amount < 0:
|
||||
#Look for any dummies of that type to remove
|
||||
# Look for any dummies of that type to remove
|
||||
toRemove = []
|
||||
for mod in self.modules:
|
||||
if mod.isEmpty and mod.slot == slotType:
|
||||
@@ -610,7 +613,7 @@ class Fit(object):
|
||||
|
||||
@property
|
||||
def modCount(self):
|
||||
x=0
|
||||
x = 0
|
||||
for i in xrange(len(self.modules) - 1, -1, -1):
|
||||
mod = self.modules[i]
|
||||
if not mod.isEmpty:
|
||||
@@ -733,7 +736,7 @@ class Fit(object):
|
||||
def activeDrones(self):
|
||||
amount = 0
|
||||
for d in self.drones:
|
||||
amount +=d.amountActive
|
||||
amount += d.amountActive
|
||||
|
||||
return amount
|
||||
|
||||
@@ -802,7 +805,6 @@ class Fit(object):
|
||||
|
||||
return self.__capRecharge
|
||||
|
||||
|
||||
@property
|
||||
def sustainableTank(self):
|
||||
if self.__sustainableTank is None:
|
||||
@@ -820,22 +822,22 @@ class Fit(object):
|
||||
sustainable = {}
|
||||
|
||||
repairers = []
|
||||
#Map a repairer type to the attribute it uses
|
||||
# Map a repairer type to the attribute it uses
|
||||
groupAttrMap = {"Armor Repair Unit": "armorDamageAmount",
|
||||
"Ancillary Armor Repairer": "armorDamageAmount",
|
||||
"Hull Repair Unit": "structureDamageAmount",
|
||||
"Shield Booster": "shieldBonus",
|
||||
"Ancillary Shield Booster": "shieldBonus",
|
||||
"Remote Armor Repairer": "armorDamageAmount",
|
||||
"Remote Shield Booster": "shieldBonus"}
|
||||
#Map repairer type to attribute
|
||||
"Ancillary Armor Repairer": "armorDamageAmount",
|
||||
"Hull Repair Unit": "structureDamageAmount",
|
||||
"Shield Booster": "shieldBonus",
|
||||
"Ancillary Shield Booster": "shieldBonus",
|
||||
"Remote Armor Repairer": "armorDamageAmount",
|
||||
"Remote Shield Booster": "shieldBonus"}
|
||||
# Map repairer type to attribute
|
||||
groupStoreMap = {"Armor Repair Unit": "armorRepair",
|
||||
"Hull Repair Unit": "hullRepair",
|
||||
"Shield Booster": "shieldRepair",
|
||||
"Ancillary Shield Booster": "shieldRepair",
|
||||
"Remote Armor Repairer": "armorRepair",
|
||||
"Remote Shield Booster": "shieldRepair",
|
||||
"Ancillary Armor Repairer": "armorRepair",}
|
||||
"Ancillary Armor Repairer": "armorRepair", }
|
||||
|
||||
capUsed = self.capUsed
|
||||
for attr in ("shieldRepair", "armorRepair", "hullRepair"):
|
||||
@@ -861,25 +863,26 @@ class Fit(object):
|
||||
sustainable[attr] -= amount / (cycleTime / 1000.0)
|
||||
repairers.append(mod)
|
||||
|
||||
# Sort repairers by efficiency. We want to use the most efficient repairers first
|
||||
repairers.sort(key=lambda mod: mod.getModifiedItemAttr(
|
||||
groupAttrMap[mod.item.group.name]) / mod.getModifiedItemAttr("capacitorNeed"), reverse=True)
|
||||
|
||||
#Sort repairers by efficiency. We want to use the most efficient repairers first
|
||||
repairers.sort(key=lambda mod: mod.getModifiedItemAttr(groupAttrMap[mod.item.group.name]) / mod.getModifiedItemAttr("capacitorNeed"), reverse = True)
|
||||
|
||||
#Loop through every module until we're above peak recharge
|
||||
#Most efficient first, as we sorted earlier.
|
||||
#calculate how much the repper can rep stability & add to total
|
||||
# Loop through every module until we're above peak recharge
|
||||
# Most efficient first, as we sorted earlier.
|
||||
# calculate how much the repper can rep stability & add to total
|
||||
totalPeakRecharge = self.capRecharge
|
||||
for mod in repairers:
|
||||
if capUsed > totalPeakRecharge: break
|
||||
cycleTime = mod.cycleTime
|
||||
capPerSec = mod.capUse
|
||||
if capPerSec is not None and cycleTime is not None:
|
||||
#Check how much this repper can work
|
||||
# Check how much this repper can work
|
||||
sustainability = min(1, (totalPeakRecharge - capUsed) / capPerSec)
|
||||
|
||||
#Add the sustainable amount
|
||||
# Add the sustainable amount
|
||||
amount = mod.getModifiedItemAttr(groupAttrMap[mod.item.group.name])
|
||||
sustainable[groupStoreMap[mod.item.group.name]] += sustainability * (amount / (cycleTime / 1000.0))
|
||||
sustainable[groupStoreMap[mod.item.group.name]] += sustainability * (
|
||||
amount / (cycleTime / 1000.0))
|
||||
capUsed += capPerSec
|
||||
|
||||
sustainable["passiveShield"] = self.calculateShieldRecharge()
|
||||
@@ -887,12 +890,12 @@ class Fit(object):
|
||||
|
||||
return self.__sustainableTank
|
||||
|
||||
def calculateCapRecharge(self, percent = PEAK_RECHARGE):
|
||||
def calculateCapRecharge(self, percent=PEAK_RECHARGE):
|
||||
capacity = self.ship.getModifiedItemAttr("capacitorCapacity")
|
||||
rechargeRate = self.ship.getModifiedItemAttr("rechargeRate") / 1000.0
|
||||
return 10 / rechargeRate * sqrt(percent) * (1 - sqrt(percent)) * capacity
|
||||
|
||||
def calculateShieldRecharge(self, percent = PEAK_RECHARGE):
|
||||
def calculateShieldRecharge(self, percent=PEAK_RECHARGE):
|
||||
capacity = self.ship.getModifiedItemAttr("shieldCapacity")
|
||||
rechargeRate = self.ship.getModifiedItemAttr("shieldRechargeRate") / 1000.0
|
||||
return 10 / rechargeRate * sqrt(percent) * (1 - sqrt(percent)) * capacity
|
||||
@@ -903,9 +906,9 @@ class Fit(object):
|
||||
energyNeutralizerSignatureResolution = src.getModifiedItemAttr("energyNeutralizerSignatureResolution")
|
||||
signatureRadius = self.ship.getModifiedItemAttr("signatureRadius")
|
||||
|
||||
#Signature reduction, uses the bomb formula as per CCP Larrikin
|
||||
# Signature reduction, uses the bomb formula as per CCP Larrikin
|
||||
if energyNeutralizerSignatureResolution:
|
||||
capNeed = capNeed*min(1, signatureRadius/energyNeutralizerSignatureResolution)
|
||||
capNeed = capNeed * min(1, signatureRadius / energyNeutralizerSignatureResolution)
|
||||
|
||||
resistance = self.ship.getModifiedItemAttr("energyWarfareResistance") or 1 if capNeed > 0 else 1
|
||||
self.__extraDrains.append((cycleTime, capNeed * resistance, clipSize))
|
||||
@@ -936,7 +939,8 @@ class Fit(object):
|
||||
# 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))
|
||||
drains.append((int(fullCycleTime), mod.getModifiedItemAttr("capacitorNeed") or 0,
|
||||
mod.numShots or 0, disableStagger))
|
||||
|
||||
for fullCycleTime, capNeed, clipSize in self.iterDrains():
|
||||
# Stagger incoming effects for cap simulation
|
||||
@@ -990,7 +994,7 @@ class Fit(object):
|
||||
|
||||
@property
|
||||
def tank(self):
|
||||
hps = {"passiveShield" : self.calculateShieldRecharge()}
|
||||
hps = {"passiveShield": self.calculateShieldRecharge()}
|
||||
for type in ("shield", "armor", "hull"):
|
||||
hps["%sRepair" % type] = self.extraAttributes["%sRepair" % type]
|
||||
|
||||
@@ -1020,13 +1024,12 @@ class Fit(object):
|
||||
|
||||
return self.__effectiveSustainableTank
|
||||
|
||||
|
||||
def calculateLockTime(self, radius):
|
||||
scanRes = self.ship.getModifiedItemAttr("scanResolution")
|
||||
if scanRes is not None and scanRes > 0:
|
||||
# Yes, this function returns time in seconds, not miliseconds.
|
||||
# 40,000 is indeed the correct constant here.
|
||||
return min(40000 / scanRes / asinh(radius)**2, 30*60)
|
||||
return min(40000 / scanRes / asinh(radius) ** 2, 30 * 60)
|
||||
else:
|
||||
return self.ship.getModifiedItemAttr("scanSpeed") / 1000.0
|
||||
|
||||
@@ -1079,7 +1082,7 @@ class Fit(object):
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Fit()
|
||||
#Character and owner are not copied
|
||||
# Character and owner are not copied
|
||||
copy.character = self.__character
|
||||
copy.owner = self.owner
|
||||
copy.ship = deepcopy(self.ship, memo)
|
||||
@@ -1087,7 +1090,9 @@ class Fit(object):
|
||||
copy.damagePattern = self.damagePattern
|
||||
copy.targetResists = self.targetResists
|
||||
|
||||
toCopy = ("modules", "drones", "fighters", "cargo", "implants", "boosters", "projectedModules", "projectedDrones", "projectedFighters")
|
||||
toCopy = (
|
||||
"modules", "drones", "fighters", "cargo", "implants", "boosters", "projectedModules", "projectedDrones",
|
||||
"projectedFighters")
|
||||
for name in toCopy:
|
||||
orig = getattr(self, name)
|
||||
c = getattr(copy, name)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,15 +15,17 @@
|
||||
#
|
||||
# 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 itertools import chain
|
||||
from eos.types import Skill, Module, Ship
|
||||
from copy import deepcopy
|
||||
from itertools import chain
|
||||
|
||||
from eos.types import Skill, Module, Ship
|
||||
|
||||
|
||||
class Fleet(object):
|
||||
def calculateModifiedAttributes(self):
|
||||
#Make sure ALL fits in the gang have been calculated
|
||||
# Make sure ALL fits in the gang have been calculated
|
||||
for c in chain(self.wings, (self.leader,)):
|
||||
if c is not None: c.calculateModifiedAttributes()
|
||||
|
||||
@@ -32,24 +34,26 @@ class Fleet(object):
|
||||
self.broken = False
|
||||
self.store = store = Store()
|
||||
store.set(booster, "fleet")
|
||||
#Go all the way down for each subtree we have.
|
||||
# Go all the way down for each subtree we have.
|
||||
for wing in self.wings:
|
||||
wing.calculateGangBonusses(store)
|
||||
|
||||
# Check skill requirements and wing amount to see if we break or not
|
||||
if len(self.wings) == 0 or leader is None or leader.character is None or leader.character.getSkill("Fleet Command").level < len(self.wings):
|
||||
if len(self.wings) == 0 or leader is None or leader.character is None or leader.character.getSkill(
|
||||
"Fleet Command").level < len(self.wings):
|
||||
self.broken = True
|
||||
|
||||
#Now calculate our own if we aren't broken
|
||||
# Now calculate our own if we aren't broken
|
||||
if not self.broken:
|
||||
#We only get our own bonuses *Sadface*
|
||||
# We only get our own bonuses *Sadface*
|
||||
store.apply(leader, "fleet")
|
||||
|
||||
def recalculateLinear(self, withBoosters=True, dirtyStorage=None):
|
||||
self.store = Store()
|
||||
self.linearBoosts = {}
|
||||
if withBoosters is True:
|
||||
if self.leader is not None and self.leader.character is not None and self.leader.character.getSkill("Fleet Command").level >= 1:
|
||||
if self.leader is not None and self.leader.character is not None and self.leader.character.getSkill(
|
||||
"Fleet Command").level >= 1:
|
||||
self.leader.boostsFits.add(self.wings[0].squads[0].members[0].ID)
|
||||
self.leader.calculateModifiedAttributes()
|
||||
self.store.set(self.leader, "squad", clearingUpdate=True)
|
||||
@@ -83,6 +87,7 @@ class Fleet(object):
|
||||
|
||||
return copy
|
||||
|
||||
|
||||
class Wing(object):
|
||||
def calculateModifiedAttributes(self):
|
||||
for c in chain(self.squads, (self.leader,)):
|
||||
@@ -95,24 +100,26 @@ class Wing(object):
|
||||
|
||||
store.set(booster, "wing")
|
||||
|
||||
#ALWAYS move down
|
||||
# ALWAYS move down
|
||||
for squad in self.squads:
|
||||
squad.calculateGangBonusses(store)
|
||||
|
||||
# Check skill requirements and squad amount to see if we break or not
|
||||
if len(self.squads) == 0 or leader is None or leader.character is None or leader.character.getSkill("Wing Command").level < len(self.squads):
|
||||
if len(self.squads) == 0 or leader is None or leader.character is None or leader.character.getSkill(
|
||||
"Wing Command").level < len(self.squads):
|
||||
self.broken = True
|
||||
|
||||
#Check if we aren't broken, if we aren't, boost
|
||||
# Check if we aren't broken, if we aren't, boost
|
||||
if not self.broken:
|
||||
store.apply(leader, "wing")
|
||||
else:
|
||||
#We broke, don't go up
|
||||
# We broke, don't go up
|
||||
self.gang.broken = True
|
||||
|
||||
def recalculateLinear(self, store, withBoosters=True, dirtyStorage=None):
|
||||
if withBoosters is True:
|
||||
if self.leader is not None and self.leader.character is not None and self.leader.character.getSkill("Wing Command").level >= 1:
|
||||
if self.leader is not None and self.leader.character is not None and self.leader.character.getSkill(
|
||||
"Wing Command").level >= 1:
|
||||
self.leader.boostsFits.add(self.squads[0].members[0].ID)
|
||||
self.leader.calculateModifiedAttributes()
|
||||
store.set(self.leader, "squad", clearingUpdate=False)
|
||||
@@ -162,7 +169,8 @@ class Squad(object):
|
||||
store.set(booster, "squad")
|
||||
|
||||
# Check skill requirements and squad size to see if we break or not
|
||||
if len(self.members) <= 0 or leader is None or leader.character is None or leader.character.getSkill("Leadership").level * 2 < len(self.members):
|
||||
if len(self.members) <= 0 or leader is None or leader.character is None or leader.character.getSkill(
|
||||
"Leadership").level * 2 < len(self.members):
|
||||
self.broken = True
|
||||
|
||||
if not self.broken:
|
||||
@@ -173,7 +181,8 @@ class Squad(object):
|
||||
|
||||
def recalculateLinear(self, store, withBoosters=True, dirtyStorage=None):
|
||||
if withBoosters is True:
|
||||
if self.leader is not None and self.leader.character is not None and self.leader.character.getSkill("Leadership").level >= 1:
|
||||
if self.leader is not None and self.leader.character is not None and self.leader.character.getSkill(
|
||||
"Leadership").level >= 1:
|
||||
self.leader.boostsFits.add(self.members[0].ID)
|
||||
self.leader.calculateModifiedAttributes(dirtyStorage=dirtyStorage)
|
||||
store.set(self.leader, "squad", clearingUpdate=False)
|
||||
@@ -231,6 +240,7 @@ class Squad(object):
|
||||
|
||||
return copy
|
||||
|
||||
|
||||
class Store(object):
|
||||
def __init__(self):
|
||||
# Container for gang boosters and their respective bonuses, three-layered
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,16 +15,19 @@
|
||||
#
|
||||
# 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.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
import eos.db
|
||||
import logging
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Implant(HandledItem, ItemAttrShortcut):
|
||||
def __init__(self, item):
|
||||
self.__item = item
|
||||
@@ -84,7 +87,7 @@ class Implant(HandledItem, ItemAttrShortcut):
|
||||
def clear(self):
|
||||
self.itemModifiedAttributes.clear()
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected=False):
|
||||
if forceProjected: return
|
||||
if not self.active: return
|
||||
for effect in self.item.effects.itervalues():
|
||||
@@ -94,11 +97,13 @@ class Implant(HandledItem, ItemAttrShortcut):
|
||||
@validates("fitID", "itemID", "active")
|
||||
def validator(self, key, val):
|
||||
map = {"fitID": lambda val: isinstance(val, int),
|
||||
"itemID" : lambda val: isinstance(val, int),
|
||||
"itemID": lambda val: isinstance(val, int),
|
||||
"active": lambda val: isinstance(val, bool)}
|
||||
|
||||
if not map[key](val): raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else:
|
||||
return val
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Implant(self.item)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2016 Ryan Holmes
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,10 +15,12 @@
|
||||
#
|
||||
# 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 copy import deepcopy
|
||||
|
||||
from eos.effectHandlerHelpers import HandledImplantBoosterList
|
||||
from copy import deepcopy
|
||||
|
||||
|
||||
class ImplantSet(object):
|
||||
def __init__(self, name=None):
|
||||
@@ -31,12 +33,12 @@ class ImplantSet(object):
|
||||
|
||||
@classmethod
|
||||
def exportSets(cls, *sets):
|
||||
out = "# Exported from pyfa\n#\n" \
|
||||
"# Values are in following format:\n" \
|
||||
"# [Implant Set name]\n" \
|
||||
"# [Implant name]\n" \
|
||||
"# [Implant name]\n" \
|
||||
"# ...\n\n"
|
||||
out = "# Exported from pyfa\n#\n" \
|
||||
"# Values are in following format:\n" \
|
||||
"# [Implant Set name]\n" \
|
||||
"# [Implant name]\n" \
|
||||
"# [Implant name]\n" \
|
||||
"# ...\n\n"
|
||||
|
||||
for set in sets:
|
||||
out += "[{}]\n".format(set.name)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2011 Anton Vorobyov
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,10 +15,11 @@
|
||||
#
|
||||
# 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
|
||||
|
||||
|
||||
class MiscData(EqBase):
|
||||
def __init__(self, name, val=None):
|
||||
self.fieldName = name
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,17 +15,18 @@
|
||||
#
|
||||
# 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.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
import eos.db
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
|
||||
|
||||
|
||||
class Mode(ItemAttrShortcut, HandledItem):
|
||||
def __init__(self, item):
|
||||
|
||||
if item.group.name != "Ship Modifiers":
|
||||
raise ValueError('Passed item "%s" (category: (%s)) is not a Ship Modifier'%(item.name, item.category.name))
|
||||
raise ValueError(
|
||||
'Passed item "%s" (category: (%s)) is not a Ship Modifier' % (item.name, item.category.name))
|
||||
|
||||
self.__item = item
|
||||
self.__itemModifiedAttributes = ModifiedAttributeDict()
|
||||
@@ -47,8 +48,8 @@ class Mode(ItemAttrShortcut, HandledItem):
|
||||
def clear(self):
|
||||
self.itemModifiedAttributes.clear()
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected=False):
|
||||
if self.item:
|
||||
for effect in self.item.effects.itervalues():
|
||||
if effect.runTime == runTime:
|
||||
effect.handler(fit, self, context = ("module",))
|
||||
effect.handler(fit, self, context=("module",))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,20 +15,22 @@
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from sqlalchemy.orm import validates, reconstructor
|
||||
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem, HandledCharge
|
||||
from eos.enum import Enum
|
||||
from eos.mathUtils import floorFloat
|
||||
import eos.db
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, ChargeAttrShortcut
|
||||
from eos.types import Citadel
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class State(Enum):
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -38,6 +40,7 @@ class State(Enum):
|
||||
ACTIVE = 1
|
||||
OVERHEATED = 2
|
||||
|
||||
|
||||
class Slot(Enum):
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -60,6 +63,7 @@ class Slot(Enum):
|
||||
F_SUPPORT = 11
|
||||
F_HEAVY = 12
|
||||
|
||||
|
||||
class Hardpoint(Enum):
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -68,10 +72,11 @@ class Hardpoint(Enum):
|
||||
MISSILE = 1
|
||||
TURRET = 2
|
||||
|
||||
|
||||
class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
"""An instance of this class represents a module together with its charge and modified attributes"""
|
||||
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
|
||||
MINING_ATTRIBUTES = ("miningAmount", )
|
||||
MINING_ATTRIBUTES = ("miningAmount",)
|
||||
|
||||
def __init__(self, item):
|
||||
"""Initialize a module from the program"""
|
||||
@@ -136,7 +141,6 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.__chargeModifiedAttributes.original = self.__charge.attributes
|
||||
self.__chargeModifiedAttributes.overrides = self.__charge.overrides
|
||||
|
||||
|
||||
@classmethod
|
||||
def buildEmpty(cls, slot):
|
||||
empty = Module(None)
|
||||
@@ -163,7 +167,8 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
def isInvalid(self):
|
||||
if self.isEmpty:
|
||||
return False
|
||||
return self.__item is None or (self.__item.category.name not in ("Module", "Subsystem", "Structure Module") and self.__item.group.name != "Effect Beacon")
|
||||
return self.__item is None or (self.__item.category.name not in (
|
||||
"Module", "Subsystem", "Structure Module") and self.__item.group.name != "Effect Beacon")
|
||||
|
||||
@property
|
||||
def numCharges(self):
|
||||
@@ -261,7 +266,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
mass = self.getModifiedChargeAttr("mass")
|
||||
agility = self.getModifiedChargeAttr("agility")
|
||||
if maxVelocity and flightTime and mass and agility:
|
||||
accelTime = min(flightTime, mass*agility/1000000)
|
||||
accelTime = min(flightTime, mass * agility / 1000000)
|
||||
# Average distance done during acceleration
|
||||
duringAcceleration = maxVelocity / 2 * accelTime
|
||||
# Distance done after being at full speed
|
||||
@@ -279,7 +284,6 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
def slot(self):
|
||||
return self.__slot
|
||||
|
||||
|
||||
@property
|
||||
def itemModifiedAttributes(self):
|
||||
return self.__itemModifiedAttributes
|
||||
@@ -321,7 +325,9 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
else:
|
||||
func = self.getModifiedItemAttr
|
||||
|
||||
volley = sum(map(lambda attr: (func("%sDamage"%attr) or 0) * (1-getattr(targetResists, "%sAmount"%attr, 0)), self.DAMAGE_TYPES))
|
||||
volley = sum(map(
|
||||
lambda attr: (func("%sDamage" % attr) or 0) * (1 - getattr(targetResists, "%sAmount" % attr, 0)),
|
||||
self.DAMAGE_TYPES))
|
||||
volley *= self.getModifiedItemAttr("damageMultiplier") or 1
|
||||
if volley:
|
||||
cycleTime = self.cycleTime
|
||||
@@ -337,7 +343,8 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.__miningyield = 0
|
||||
else:
|
||||
if self.state >= State.ACTIVE:
|
||||
volley = self.getModifiedItemAttr("specialtyMiningAmount") or self.getModifiedItemAttr("miningAmount") or 0
|
||||
volley = self.getModifiedItemAttr("specialtyMiningAmount") or self.getModifiedItemAttr(
|
||||
"miningAmount") or 0
|
||||
if volley:
|
||||
cycleTime = self.cycleTime
|
||||
self.__miningyield = volley / (cycleTime / 1000.0)
|
||||
@@ -402,7 +409,8 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if shipGroup is not None:
|
||||
fitsOnGroup.add(shipGroup)
|
||||
|
||||
if (len(fitsOnGroup) > 0 or len(fitsOnType) > 0) and fit.ship.item.group.ID not in fitsOnGroup and fit.ship.item.ID not in fitsOnType:
|
||||
if (len(fitsOnGroup) > 0 or len(
|
||||
fitsOnType) > 0) and fit.ship.item.group.ID not in fitsOnGroup and fit.ship.item.ID not in fitsOnType:
|
||||
return False
|
||||
|
||||
# AFAIK Citadel modules will always be restricted based on canFitShipType/Group. If we are fitting to a Citadel
|
||||
@@ -439,7 +447,8 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if (fit.ship.getModifiedItemAttr('turretSlotsLeft') or 0) - fit.getHardpointsUsed(Hardpoint.TURRET) < 1:
|
||||
return False
|
||||
elif self.hardpoint == Hardpoint.MISSILE:
|
||||
if (fit.ship.getModifiedItemAttr('launcherSlotsLeft')or 0) - fit.getHardpointsUsed(Hardpoint.MISSILE) < 1:
|
||||
if (fit.ship.getModifiedItemAttr('launcherSlotsLeft') or 0) - fit.getHardpointsUsed(
|
||||
Hardpoint.MISSILE) < 1:
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -448,7 +457,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
"""
|
||||
Check if the state is valid for this module, without considering other modules at all
|
||||
"""
|
||||
#Check if we're within bounds
|
||||
# Check if we're within bounds
|
||||
if state < -1 or state > 2:
|
||||
return False
|
||||
elif state >= State.ACTIVE and not self.item.isType("active"):
|
||||
@@ -501,7 +510,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return True
|
||||
|
||||
def isValidCharge(self, charge):
|
||||
#Check sizes, if 'charge size > module volume' it won't fit
|
||||
# Check sizes, if 'charge size > module volume' it won't fit
|
||||
if charge is None: return True
|
||||
chargeVolume = charge.volume
|
||||
moduleCapacity = self.item.capacity
|
||||
@@ -534,11 +543,10 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if singleItem.published and self.isValidCharge(singleItem):
|
||||
validCharges.add(singleItem)
|
||||
|
||||
|
||||
return validCharges
|
||||
|
||||
def __calculateHardpoint(self, item):
|
||||
effectHardpointMap = {"turretFitted" : Hardpoint.TURRET,
|
||||
effectHardpointMap = {"turretFitted": Hardpoint.TURRET,
|
||||
"launcherFitted": Hardpoint.MISSILE}
|
||||
|
||||
if item is None:
|
||||
@@ -551,11 +559,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return Hardpoint.NONE
|
||||
|
||||
def __calculateSlot(self, item):
|
||||
effectSlotMap = {"rigSlot" : Slot.RIG,
|
||||
"loPower" : Slot.LOW,
|
||||
"medPower" : Slot.MED,
|
||||
"hiPower" : Slot.HIGH,
|
||||
"subSystem" : Slot.SUBSYSTEM,
|
||||
effectSlotMap = {"rigSlot": Slot.RIG,
|
||||
"loPower": Slot.LOW,
|
||||
"medPower": Slot.MED,
|
||||
"hiPower": Slot.HIGH,
|
||||
"subSystem": Slot.SUBSYSTEM,
|
||||
"serviceSlot": Slot.SERVICE}
|
||||
if item is None:
|
||||
return None
|
||||
@@ -570,11 +578,13 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
@validates("ID", "itemID", "ammoID")
|
||||
def validator(self, key, val):
|
||||
map = {"ID": lambda val: isinstance(val, int),
|
||||
"itemID" : lambda val: val is None or isinstance(val, int),
|
||||
"ammoID" : lambda val: isinstance(val, int)}
|
||||
"itemID": lambda val: val is None or isinstance(val, int),
|
||||
"ammoID": lambda val: isinstance(val, int)}
|
||||
|
||||
if not map[key](val): raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else:
|
||||
return val
|
||||
|
||||
def clear(self):
|
||||
self.__dps = None
|
||||
@@ -586,15 +596,15 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.itemModifiedAttributes.clear()
|
||||
self.chargeModifiedAttributes.clear()
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
|
||||
#We will run the effect when two conditions are met:
|
||||
#1: It makes sense to run the effect
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected=False):
|
||||
# We will run the effect when two conditions are met:
|
||||
# 1: It makes sense to run the effect
|
||||
# The effect is either offline
|
||||
# or the effect is passive and the module is in the online state (or higher)
|
||||
|
||||
# or the effect is active and the module is in the active state (or higher)
|
||||
# or the effect is overheat and the module is in the overheated state (or higher)
|
||||
#2: the runtimes match
|
||||
# 2: the runtimes match
|
||||
|
||||
if self.projected or forceProjected:
|
||||
context = "projected", "module"
|
||||
@@ -614,8 +624,8 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if self.state >= State.OVERHEATED:
|
||||
for effect in self.item.effects.itervalues():
|
||||
if effect.runTime == runTime and \
|
||||
effect.isType("overheat") and \
|
||||
not forceProjected:
|
||||
effect.isType("overheat") and \
|
||||
not forceProjected:
|
||||
effect.handler(fit, self, context)
|
||||
|
||||
for effect in self.item.effects.itervalues():
|
||||
@@ -682,6 +692,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
else:
|
||||
return "EmptyModule() at {}".format(hex(id(self)))
|
||||
|
||||
|
||||
class Rack(Module):
|
||||
"""
|
||||
This is simply the Module class named something else to differentiate
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2015 Ryan Holmes
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,17 +15,19 @@
|
||||
#
|
||||
# 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
|
||||
|
||||
from sqlalchemy.orm import reconstructor
|
||||
|
||||
import eos.db
|
||||
from eos.eqBase import EqBase
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Override(EqBase):
|
||||
|
||||
class Override(EqBase):
|
||||
def __init__(self, item, attr, value):
|
||||
self.itemID = item.ID
|
||||
self.__item = item
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
# Copyright (C) 2011 Anton Vorobyov
|
||||
#
|
||||
@@ -16,13 +16,14 @@
|
||||
#
|
||||
# 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 time
|
||||
|
||||
from sqlalchemy.orm import reconstructor
|
||||
|
||||
class Price(object):
|
||||
|
||||
class Price(object):
|
||||
def __init__(self, typeID):
|
||||
self.typeID = typeID
|
||||
self.time = 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,16 +15,18 @@
|
||||
#
|
||||
# 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.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, cappingAttrKeyCache
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from eos.saveddata.mode import Mode
|
||||
import eos.db
|
||||
import logging
|
||||
|
||||
import eos.db
|
||||
from eos.effectHandlerHelpers import HandledItem
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, cappingAttrKeyCache
|
||||
from eos.saveddata.mode import Mode
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Ship(ItemAttrShortcut, HandledItem):
|
||||
EXTRA_ATTRIBUTES = {
|
||||
"armorRepair": 0,
|
||||
@@ -50,7 +52,7 @@ class Ship(ItemAttrShortcut, HandledItem):
|
||||
self.__itemModifiedAttributes.original = dict(self.item.attributes)
|
||||
self.__itemModifiedAttributes.original.update(self.EXTRA_ATTRIBUTES)
|
||||
self.__itemModifiedAttributes.overrides = self.item.overrides
|
||||
|
||||
|
||||
if "maximumRangeCap" in self.__itemModifiedAttributes.original:
|
||||
cappingAttrKeyCache["maxTargetRange"] = "maximumRangeCap"
|
||||
|
||||
@@ -61,7 +63,8 @@ class Ship(ItemAttrShortcut, HandledItem):
|
||||
|
||||
def validate(self, item):
|
||||
if item.category.name != "Ship":
|
||||
raise ValueError('Passed item "%s" (category: (%s)) is not under Ship category'%(item.name, item.category.name))
|
||||
raise ValueError(
|
||||
'Passed item "%s" (category: (%s)) is not under Ship category' % (item.name, item.category.name))
|
||||
|
||||
@property
|
||||
def item(self):
|
||||
@@ -75,7 +78,7 @@ class Ship(ItemAttrShortcut, HandledItem):
|
||||
self.itemModifiedAttributes.clear()
|
||||
self.commandBonus = 0
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected=False):
|
||||
if forceProjected: return
|
||||
for effect in self.item.effects.itervalues():
|
||||
if effect.runTime == runTime and effect.isType("passive"):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2014 Ryan Holmes
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,15 +15,16 @@
|
||||
#
|
||||
# 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 re
|
||||
|
||||
|
||||
class TargetResists(object):
|
||||
# also determined import/export order - VERY IMPORTANT
|
||||
DAMAGE_TYPES = ("em", "thermal", "kinetic", "explosive")
|
||||
|
||||
def __init__(self, emAmount = 0, thermalAmount = 0, kineticAmount = 0, explosiveAmount = 0):
|
||||
def __init__(self, emAmount=0, thermalAmount=0, kineticAmount=0, explosiveAmount=0):
|
||||
self.emAmount = emAmount
|
||||
self.thermalAmount = thermalAmount
|
||||
self.kineticAmount = kineticAmount
|
||||
@@ -38,8 +39,8 @@ class TargetResists(object):
|
||||
try:
|
||||
if line.strip()[0] == "#": # comments
|
||||
continue
|
||||
line = line.split('#',1)[0] # allows for comments
|
||||
type, data = line.rsplit('=',1)
|
||||
line = line.split('#', 1)[0] # allows for comments
|
||||
type, data = line.rsplit('=', 1)
|
||||
type, data = type.strip(), data.split(',')
|
||||
except:
|
||||
# Data isn't in correct format, continue to next line
|
||||
@@ -56,11 +57,11 @@ class TargetResists(object):
|
||||
val = float(val)
|
||||
try:
|
||||
assert 0 <= val <= 100
|
||||
fields["%sAmount" % cls.DAMAGE_TYPES[index]] = val/100
|
||||
fields["%sAmount" % cls.DAMAGE_TYPES[index]] = val / 100
|
||||
except:
|
||||
continue
|
||||
|
||||
if len(fields) == 4: # Avoid possible blank lines
|
||||
if len(fields) == 4: # Avoid possible blank lines
|
||||
pattern = TargetResists(**fields)
|
||||
pattern.name = name.strip()
|
||||
patterns.append(pattern)
|
||||
@@ -68,13 +69,15 @@ class TargetResists(object):
|
||||
return patterns, numPatterns
|
||||
|
||||
EXPORT_FORMAT = "TargetResists = %s,%.1f,%.1f,%.1f,%.1f\n"
|
||||
|
||||
@classmethod
|
||||
def exportPatterns(cls, *patterns):
|
||||
out = "# Exported from pyfa\n#\n"
|
||||
out = "# Exported from pyfa\n#\n"
|
||||
out += "# Values are in following format:\n"
|
||||
out += "# TargetResists = [name],[EM %],[Thermal %],[Kinetic %],[Explosive %]\n\n"
|
||||
for dp in patterns:
|
||||
out += cls.EXPORT_FORMAT % (dp.name, dp.emAmount*100, dp.thermalAmount*100, dp.kineticAmount*100, dp.explosiveAmount*100)
|
||||
out += cls.EXPORT_FORMAT % (
|
||||
dp.name, dp.emAmount * 100, dp.thermalAmount * 100, dp.kineticAmount * 100, dp.explosiveAmount * 100)
|
||||
|
||||
return out.strip()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#===============================================================================
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
@@ -15,15 +15,17 @@
|
||||
#
|
||||
# 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 hashlib
|
||||
import random
|
||||
import string
|
||||
|
||||
from sqlalchemy.orm import validates
|
||||
import hashlib
|
||||
import string
|
||||
import random
|
||||
|
||||
|
||||
class User(object):
|
||||
def __init__(self, username, password = None, admin = False):
|
||||
def __init__(self, username, password=None, admin=False):
|
||||
self.username = username
|
||||
if password is not None: self.encodeAndSetPassword(password)
|
||||
self.admin = admin
|
||||
@@ -46,9 +48,11 @@ class User(object):
|
||||
@validates("ID", "username", "password", "admin")
|
||||
def validator(self, key, val):
|
||||
map = {"ID": lambda val: isinstance(val, int),
|
||||
"username" : lambda val: isinstance(val, basestring),
|
||||
"password" : lambda val: isinstance(val, basestring) and len(val) == 96,
|
||||
"admin" : lambda val: isinstance(val, bool)}
|
||||
"username": lambda val: isinstance(val, basestring),
|
||||
"password": lambda val: isinstance(val, basestring) and len(val) == 96,
|
||||
"admin": lambda val: isinstance(val, bool)}
|
||||
|
||||
if not map[key](val): raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else:
|
||||
return val
|
||||
|
||||
Reference in New Issue
Block a user