# =============================================================================== # 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 . # =============================================================================== from logbook import Logger import eos.db from eos.effectHandlerHelpers import HandledItem from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut, cappingAttrKeyCache from eos.saveddata.mode import Mode pyfalog = Logger(__name__) class Ship(ItemAttrShortcut, HandledItem): EXTRA_ATTRIBUTES = { "armorRepair": 0, "armorRepairPreSpool": 0, "armorRepairFullSpool": 0, "hullRepair": 0, "shieldRepair": 0, "maxActiveDrones": 0, "maxTargetsLockedFromSkills": 2, "droneControlRange": 20000, "cloaked": False, # We also have speedLimit for Entosis Link, but there seems to be an # issue with naming it exactly "speedLimit" due to unknown reasons. # Regardless, we don't have to put it here anyways - it will come up # as None unless the Entosis effect sets it. } def __init__(self, item, owner=None): self.validate(item) self.__item = item self.__modeItems = self.__getModeItems() self.__itemModifiedAttributes = ModifiedAttributeDict(parent=self) 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" self.owner = owner self.commandBonus = 0 def validate(self, item): if item.category.name != "Ship": pyfalog.error("Passed item '{0}' (category: {1}) 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): return self.__item @property def name(self): # NOTE: add name property return self.__item.name @property def itemModifiedAttributes(self): return self.__itemModifiedAttributes def clear(self): self.itemModifiedAttributes.clear() self.commandBonus = 0 def calculateModifiedAttributes(self, fit, runTime, forceProjected=False): if forceProjected: return for effect in self.item.effects.values(): if effect.runTime == runTime and \ effect.isType("passive") and \ effect.activeByDefault: # Ships have effects that utilize the level of a skill as an # additional operator to the modifier. These are defined in # the effect itself, and these skillbooks are registered when # they are provided. However, we must re-register the ship # before each effect, otherwise effects that do not have # skillbook modifiers will use the stale modifier value # GH issue #351 fit.register(self) effect.handler(fit, self, ("ship",), None, effect=effect) def validateModeItem(self, item, owner=None): """ Checks if provided item is a valid mode """ items = self.__modeItems if items is not None: # if we have items, then we are in a tactical destroyer and must have a mode if item is None or item not in items: # If provided item is invalid mode, force new one return Mode(items[0], owner=owner) return Mode(item) return None @property def modeItems(self): return self.__modeItems @property def modes(self): return [Mode(item) for item in self.__modeItems] if self.__modeItems else None def __getModeItems(self): """ Returns a list of valid mode items for ship. Note that this returns the valid Item objects, not the Mode objects. Returns None if not a t3 dessy """ if self.item.group.name != "Tactical Destroyer" and self.item.name != "Anhinga": return None items = [] g = eos.db.getGroup("Ship Modifiers", eager="items.attributes") for item in g.items: # Rely on name detection because race is not reliable if item.name.lower().startswith(self.item.name.lower()): items.append(item) return items 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)) )