diff --git a/eos/db/saveddata/__init__.py b/eos/db/saveddata/__init__.py index d409e8ca7..7dbf2a45d 100644 --- a/eos/db/saveddata/__init__.py +++ b/eos/db/saveddata/__init__.py @@ -8,7 +8,6 @@ __all__ = [ "booster", "drone", "implant", - "fleet", "damagePattern", "miscData", "targetResists", diff --git a/eos/db/saveddata/fleet.py b/eos/db/saveddata/fleet.py deleted file mode 100644 index eb644b02e..000000000 --- a/eos/db/saveddata/fleet.py +++ /dev/null @@ -1,65 +0,0 @@ -# =============================================================================== -# 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 sqlalchemy import Table, Column, Integer, ForeignKey, String -from sqlalchemy.orm import mapper, relation - -from eos.db import saveddata_meta -from eos.db.saveddata.fit import fits_table -from eos.types import Fleet, Wing, Squad, Fit - -gangs_table = Table("gangs", saveddata_meta, - Column("ID", Integer, primary_key=True), - Column("leaderID", ForeignKey("fits.ID")), - Column("boosterID", ForeignKey("fits.ID")), - Column("name", String)) - -wings_table = Table("wings", saveddata_meta, - Column("ID", Integer, primary_key=True), - Column("gangID", ForeignKey("gangs.ID")), - Column("boosterID", ForeignKey("fits.ID")), - Column("leaderID", ForeignKey("fits.ID"))) - -squads_table = Table("squads", saveddata_meta, - Column("ID", Integer, primary_key=True), - Column("wingID", ForeignKey("wings.ID")), - Column("leaderID", ForeignKey("fits.ID")), - Column("boosterID", ForeignKey("fits.ID"))) - -squadmembers_table = Table("squadmembers", saveddata_meta, - Column("squadID", ForeignKey("squads.ID"), primary_key=True), - Column("memberID", ForeignKey("fits.ID"), primary_key=True)) - -mapper(Fleet, gangs_table, - properties={"wings": relation(Wing, backref="gang"), - "leader": relation(Fit, primaryjoin=gangs_table.c.leaderID == fits_table.c.ID), - "booster": relation(Fit, primaryjoin=gangs_table.c.boosterID == fits_table.c.ID)}) - -mapper(Wing, wings_table, - properties={"squads": relation(Squad, backref="wing"), - "leader": relation(Fit, primaryjoin=wings_table.c.leaderID == fits_table.c.ID), - "booster": relation(Fit, primaryjoin=wings_table.c.boosterID == fits_table.c.ID)}) - -mapper(Squad, squads_table, - properties={"leader": relation(Fit, primaryjoin=squads_table.c.leaderID == fits_table.c.ID), - "booster": relation(Fit, primaryjoin=squads_table.c.boosterID == fits_table.c.ID), - "members": relation(Fit, - primaryjoin=squads_table.c.ID == squadmembers_table.c.squadID, - secondaryjoin=squadmembers_table.c.memberID == fits_table.c.ID, - secondary=squadmembers_table)}) diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py index bcecb3b69..cb3033cc1 100644 --- a/eos/db/saveddata/queries.py +++ b/eos/db/saveddata/queries.py @@ -1,4 +1,4 @@ -# =============================================================================== +#=============================================================================== # Copyright (C) 2010 Diego Duclos # # This file is part of eos. @@ -15,33 +15,26 @@ # # You should have received a copy of the GNU Lesser General Public License # along with eos. If not, see . -# =============================================================================== +#=============================================================================== -from sqlalchemy.sql import and_ - -from eos.db import saveddata_session, sd_lock -from eos.db.saveddata.fit import projectedFits_table -from eos.db.saveddata.fleet import squadmembers_table from eos.db.util import processEager, processWhere -from eos.types import * +from eos.db import saveddata_session, sd_lock +from eos.types import * +from eos.db.saveddata.fit import projectedFits_table +from sqlalchemy.sql import and_ import eos.config configVal = getattr(eos.config, "saveddataCache", None) if configVal is True: import weakref - itemCache = {} queryCache = {} - - def cachedQuery(type, amount, *keywords): itemCache[type] = localItemCache = weakref.WeakValueDictionary() queryCache[type] = typeQueryCache = {} - def deco(function): localQueryCache = typeQueryCache[function] = {} - def setCache(cacheKey, args, kwargs): items = function(*args, **kwargs) IDs = set() @@ -50,7 +43,7 @@ if configVal is True: for item in stuff: ID = getattr(item, "ID", None) if ID is None: - # Some uncachable data, don't cache this query + #Some uncachable data, don't cache this query del localQueryCache[cacheKey] break localItemCache[ID] = item @@ -76,7 +69,7 @@ if configVal is True: for ID in IDs: data = localItemCache.get(ID) if data is None: - # Fuck, some of our stuff isn't cached it seems. + #Fuck, some of our stuff isn't cached it seems. items = setCache(cacheKey, args, kwargs) break items.append(data) @@ -88,14 +81,11 @@ if configVal is True: break return items - return checkAndReturn - return deco - def removeCachedEntry(type, ID): - if type not in queryCache: + if not type in queryCache: return functionCache = queryCache[type] for _, localCache in functionCache.iteritems(): @@ -120,14 +110,11 @@ else: return function(*args, **kwargs) return checkAndReturn - return deco - def removeCachedEntry(*args, **kwargs): return - def sqlizeString(line): # Escape backslashes first, as they will be as escape symbol in queries # Then escape percent and underscore signs @@ -135,7 +122,6 @@ def sqlizeString(line): line = line.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_").replace("*", "%") return line - @cachedQuery(User, 1, "lookfor") def getUser(lookfor, eager=None): if isinstance(lookfor, int): @@ -154,7 +140,6 @@ def getUser(lookfor, eager=None): raise TypeError("Need integer or string as argument") return user - @cachedQuery(Character, 1, "lookfor") def getCharacter(lookfor, eager=None): if isinstance(lookfor, int): @@ -168,20 +153,17 @@ def getCharacter(lookfor, eager=None): elif isinstance(lookfor, basestring): eager = processEager(eager) with sd_lock: - character = saveddata_session.query(Character).options(*eager).filter( - Character.savedName == lookfor).first() + character = saveddata_session.query(Character).options(*eager).filter(Character.savedName == lookfor).first() else: raise TypeError("Need integer or string as argument") return character - def getCharacterList(eager=None): eager = processEager(eager) with sd_lock: characters = saveddata_session.query(Character).options(*eager).all() return characters - def getCharactersForUser(lookfor, eager=None): if isinstance(lookfor, int): eager = processEager(eager) @@ -191,7 +173,6 @@ def getCharactersForUser(lookfor, eager=None): raise TypeError("Need integer as argument") return characters - @cachedQuery(Fit, 1, "lookfor") def getFit(lookfor, eager=None): if isinstance(lookfor, int): @@ -212,52 +193,6 @@ def getFit(lookfor, eager=None): return fit - -@cachedQuery(Fleet, 1, "fleetID") -def getFleet(fleetID, eager=None): - if isinstance(fleetID, int): - if eager is None: - with sd_lock: - fleet = saveddata_session.query(Fleet).get(fleetID) - else: - eager = processEager(eager) - with sd_lock: - fleet = saveddata_session.query(Fleet).options(*eager).filter(Fleet.ID == fleetID).first() - else: - raise TypeError("Need integer as argument") - return fleet - - -@cachedQuery(Wing, 1, "wingID") -def getWing(wingID, eager=None): - if isinstance(wingID, int): - if eager is None: - with sd_lock: - wing = saveddata_session.query(Wing).get(wingID) - else: - eager = processEager(eager) - with sd_lock: - wing = saveddata_session.query(Wing).options(*eager).filter(Wing.ID == wingID).first() - else: - raise TypeError("Need integer as argument") - return wing - - -@cachedQuery(Squad, 1, "squadID") -def getSquad(squadID, eager=None): - if isinstance(squadID, int): - if eager is None: - with sd_lock: - squad = saveddata_session.query(Squad).get(squadID) - else: - eager = processEager(eager) - with sd_lock: - squad = saveddata_session.query(Squad).options(*eager).filter(Fleet.ID == squadID).first() - else: - raise TypeError("Need integer as argument") - return squad - - def getFitsWithShip(shipID, ownerID=None, where=None, eager=None): """ Get all the fits using a certain ship. @@ -279,7 +214,6 @@ def getFitsWithShip(shipID, ownerID=None, where=None, eager=None): return fits - def getBoosterFits(ownerID=None, where=None, eager=None): """ Get all the fits that are flagged as a boosting ship @@ -299,13 +233,11 @@ def getBoosterFits(ownerID=None, where=None, eager=None): return fits - def countAllFits(): with sd_lock: count = saveddata_session.query(Fit).count() return count - def countFitsWithShip(shipID, ownerID=None, where=None, eager=None): """ Get all the fits using a certain ship. @@ -326,7 +258,6 @@ def countFitsWithShip(shipID, ownerID=None, where=None, eager=None): raise TypeError("ShipID must be integer") return count - def getFitList(eager=None): eager = processEager(eager) with sd_lock: @@ -334,14 +265,6 @@ def getFitList(eager=None): return fits - -def getFleetList(eager=None): - eager = processEager(eager) - with sd_lock: - fleets = saveddata_session.query(Fleet).options(*eager).all() - return fleets - - @cachedQuery(Price, 1, "typeID") def getPrice(typeID): if isinstance(typeID, int): @@ -351,14 +274,12 @@ def getPrice(typeID): raise TypeError("Need integer as argument") return price - def clearPrices(): with sd_lock: deleted_rows = saveddata_session.query(Price).delete() commit() return deleted_rows - def getMiscData(field): if isinstance(field, basestring): with sd_lock: @@ -367,28 +288,24 @@ def getMiscData(field): raise TypeError("Need string as argument") return data - def getDamagePatternList(eager=None): eager = processEager(eager) with sd_lock: patterns = saveddata_session.query(DamagePattern).options(*eager).all() return patterns - def getTargetResistsList(eager=None): eager = processEager(eager) with sd_lock: patterns = saveddata_session.query(TargetResists).options(*eager).all() return patterns - def getImplantSetList(eager=None): eager = processEager(eager) with sd_lock: sets = saveddata_session.query(ImplantSet).options(*eager).all() return sets - @cachedQuery(DamagePattern, 1, "lookfor") def getDamagePattern(lookfor, eager=None): if isinstance(lookfor, int): @@ -398,18 +315,15 @@ def getDamagePattern(lookfor, eager=None): else: eager = processEager(eager) with sd_lock: - pattern = saveddata_session.query(DamagePattern).options(*eager).filter( - DamagePattern.ID == lookfor).first() + pattern = saveddata_session.query(DamagePattern).options(*eager).filter(DamagePattern.ID == lookfor).first() elif isinstance(lookfor, basestring): eager = processEager(eager) with sd_lock: - pattern = saveddata_session.query(DamagePattern).options(*eager).filter( - DamagePattern.name == lookfor).first() + pattern = saveddata_session.query(DamagePattern).options(*eager).filter(DamagePattern.name == lookfor).first() else: raise TypeError("Need integer or string as argument") return pattern - @cachedQuery(TargetResists, 1, "lookfor") def getTargetResists(lookfor, eager=None): if isinstance(lookfor, int): @@ -419,18 +333,15 @@ def getTargetResists(lookfor, eager=None): else: eager = processEager(eager) with sd_lock: - pattern = saveddata_session.query(TargetResists).options(*eager).filter( - TargetResists.ID == lookfor).first() + pattern = saveddata_session.query(TargetResists).options(*eager).filter(TargetResists.ID == lookfor).first() elif isinstance(lookfor, basestring): eager = processEager(eager) with sd_lock: - pattern = saveddata_session.query(TargetResists).options(*eager).filter( - TargetResists.name == lookfor).first() + pattern = saveddata_session.query(TargetResists).options(*eager).filter(TargetResists.name == lookfor).first() else: raise TypeError("Need integer or string as argument") return pattern - @cachedQuery(ImplantSet, 1, "lookfor") def getImplantSet(lookfor, eager=None): if isinstance(lookfor, int): @@ -440,8 +351,7 @@ def getImplantSet(lookfor, eager=None): else: eager = processEager(eager) with sd_lock: - pattern = saveddata_session.query(ImplantSet).options(*eager).filter( - TargetResists.ID == lookfor).first() + pattern = saveddata_session.query(ImplantSet).options(*eager).filter(TargetResists.ID == lookfor).first() elif isinstance(lookfor, basestring): eager = processEager(eager) with sd_lock: @@ -450,14 +360,13 @@ def getImplantSet(lookfor, eager=None): raise TypeError("Improper argument") return pattern - def searchFits(nameLike, where=None, eager=None): if not isinstance(nameLike, basestring): raise TypeError("Need string as argument") # Prepare our string for request nameLike = u"%{0}%".format(sqlizeString(nameLike)) - # Add any extra components to the search to our where clause + #Add any extra components to the search to our where clause filter = processWhere(Fit.name.like(nameLike, escape="\\"), where) eager = processEager(eager) with sd_lock: @@ -465,18 +374,6 @@ def searchFits(nameLike, where=None, eager=None): return fits - -def getSquadsIDsWithFitID(fitID): - if isinstance(fitID, int): - with sd_lock: - squads = saveddata_session.query(squadmembers_table.c.squadID).filter( - squadmembers_table.c.memberID == fitID).all() - squads = tuple(entry[0] for entry in squads) - return squads - else: - raise TypeError("Need integer as argument") - - def getProjectedFits(fitID): if isinstance(fitID, int): with sd_lock: @@ -486,14 +383,12 @@ 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): @@ -512,25 +407,21 @@ def getCrestCharacter(lookfor, eager=None): 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] @@ -541,17 +432,14 @@ def removeInvalid(fits): return fits - def add(stuff): with sd_lock: saveddata_session.add(stuff) - def save(stuff): add(stuff) commit() - def remove(stuff): removeCachedEntry(type(stuff), stuff.ID) with sd_lock: diff --git a/eos/effects/chargebonuswarfarecharge.py b/eos/effects/chargebonuswarfarecharge.py index 005101d45..83865a009 100644 --- a/eos/effects/chargebonuswarfarecharge.py +++ b/eos/effects/chargebonuswarfarecharge.py @@ -15,11 +15,7 @@ which warfareBuffID to run (shouldn't need this right now, but better safe than type = "active", "gang" def handler(fit, module, context, **kwargs): - print "In chargeBonusWarfareEffect, context: ", context - def runEffect(id, value): - print "RUN EFFECT: ", fit, - if id == 10: # Shield Burst: Shield Harmonizing: Shield Resistance for damageType in ("Em", "Explosive", "Thermal", "Kinetic"): fit.ship.boostItemAttr("shield%sDamageResonance" % damageType, value) @@ -101,12 +97,10 @@ def handler(fit, module, context, **kwargs): if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)): value = module.getModifiedChargeAttr("warfareBuff{}Multiplier".format(x)) id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x)) - print "Buff ID: ",id," value: ",value + if id: if 'commandRun' not in context: - print "Add buffID", id, " to ", fit fit.addCommandBonus(id, value, module, kwargs['effect']) elif kwargs['warfareBuffID'] is not None and kwargs['warfareBuffID'] == id: - print "Running buffID ", kwargs['warfareBuffID'], " on ", fit runEffect(kwargs['warfareBuffID'], value) diff --git a/eos/effects/moduletitaneffectgenerator.py b/eos/effects/moduletitaneffectgenerator.py index 2a5de4473..e5c2b3d2e 100644 --- a/eos/effects/moduletitaneffectgenerator.py +++ b/eos/effects/moduletitaneffectgenerator.py @@ -11,43 +11,44 @@ def handler(fit, module, context, **kwargs): if id == 40: # Avatar Effect Generator : Kinetic resistance bonus for attr in ("armorKineticDamageResonance", "shieldKineticDamageResonance", "hullKineticDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) - if id == 41: # Erebus Effect Generator : Armor HP bonus + if id == 41: # Avatar Effect Generator : EM resistance penalty + for attr in ("armorEmDamageResonance", "shieldEmDamageResonance", "hullEmDamageResonance"): + fit.ship.boostItemAttr(attr, value) + + if id == 42: # Erebus Effect Generator : Armor HP bonus fit.ship.boostItemAttr("armorHP", value, stackingPenalties=True) - if id == 42: # Leviathan Effect Generator : Shield HP bonus - fit.ship.boostItemAttr("shieldCapacity", value, stackingPenalties=True) - if id == 43: # Erebus Effect Generator : Explosive resistance bonus for attr in ("armorExplosiveDamageResonance", "shieldExplosiveDamageResonance", "hullExplosiveDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 44: # Erebus Effect Generator : Thermal resistance penalty for attr in ("armorThermalDamageResonance", "shieldThermalDamageResonance", "hullThermalDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 45: # Ragnarok Effect Generator : Signature Radius bonus fit.ship.boostItemAttr("signatureRadius", value, stackingPenalties=True) if id == 46: # Ragnarok Effect Generator : Thermal resistance bonus for attr in ("armorThermalDamageResonance", "shieldThermalDamageResonance", "hullThermalDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 47: # Ragnarok Effect Generator : Explosive resistance penaly for attr in ("armorExplosiveDamageResonance", "shieldExplosiveDamageResonance", "hullExplosiveDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 48: # Leviathan Effect Generator : Shield HP bonus fit.ship.boostItemAttr("shieldCapacity", value, stackingPenalties=True) if id == 49: # Leviathan Effect Generator : EM resistance bonus for attr in ("armorEmDamageResonance", "shieldEmDamageResonance", "hullEmDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 50: # Leviathan Effect Generator : Kinetic resistance penalty for attr in ("armorKineticDamageResonance", "shieldKineticDamageResonance", "hullKineticDamageResonance"): - fit.ship.boostItemAttr(attr, value, stackingPenalties=True) + fit.ship.boostItemAttr(attr, value) if id == 51: # Avatar Effect Generator : Velocity penalty fit.ship.boostItemAttr("maxVelocity", value, stackingPenalties=True) @@ -63,9 +64,9 @@ def handler(fit, module, context, **kwargs): fit.modules.filteredItemBoost(lambda mod: mod.item.group.name in groups, "maxRange", value, stackingPenalties=True) for x in xrange(1, 4): - if module.getModifiedChargeAttr("warfareBuff{}ID".format(x)): - value = module.getModifiedChargeAttr("warfareBuff{}Multiplier".format(x)) - id = module.getModifiedChargeAttr("warfareBuff{}ID".format(x)) + if module.getModifiedItemAttr("warfareBuff{}ID".format(x)): + value = module.getModifiedItemAttr("warfareBuff{}Value".format(x)) + id = module.getModifiedItemAttr("warfareBuff{}ID".format(x)) if id: if 'commandRun' not in context: diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 1fe345be0..01d0771ed 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -134,7 +134,6 @@ class Fit(object): self.__capRecharge = None self.__calculatedTargets = [] self.factorReload = False - self.fleet = None self.boostsFits = set() self.gangBoosts = None self.ecmProjectedStr = 1 @@ -449,8 +448,6 @@ class Fit(object): # oh fuck this is so janky # @todo should we pass in min/max to this function, or is abs okay? # (abs is old method, ccp now provides the aggregate function in their data) - print "Add command bonus: ", warfareBuffID, " - value: ", value - if warfareBuffID not in self.commandBonuses or abs(self.commandBonuses[warfareBuffID][1]) < abs(value): self.commandBonuses[warfareBuffID] = (runTime, value, module, effect) @@ -473,14 +470,6 @@ class Fit(object): self.register(thing) effect.handler(self, thing, context, warfareBuffID = warfareBuffID) - # if effect.isType("offline") or (effect.isType("passive") and thing.state >= State.ONLINE) or \ - # (effect.isType("active") and thing.state >= State.ACTIVE): - # # Run effect, and get proper bonuses applied - # try: - # self.register(thing) - # effect.handler(self, thing, context) - # except: - # pass else: # Run effect, and get proper bonuses applied try: @@ -506,7 +495,6 @@ class Fit(object): # Don't inspect this, we genuinely want to reassign self # noinspection PyMethodFirstArgAssignment self = copy.deepcopy(self) - self.fleet = copied.fleet logger.debug("Handling self projection - making shadow copy of fit. %r => %r", copied, self) # we delete the fit because when we copy a fit, flush() is # called to properly handle projection updates. However, we do @@ -514,31 +502,11 @@ class Fit(object): eos.db.saveddata_session.delete(self) if self.commandFits and not withBoosters: - print "Calculatate command fits and apply to fit" for fit in self.commandFits: if self == fit: - print "nope" continue - print "calculating ", fit + fit.calculateModifiedAttributes(self, True) - # - # for thing in chain(fit.modules, fit.implants, fit.character.skills, (fit.ship,)): - # if thing.item is None: - # continue - # for effect in thing.item.effects.itervalues(): - # # And check if it actually has gang boosting effects - # if effect.isType("gang"): - # effect.handler(self, thing, ("commandRun")) - - # if self.fleet is not None and withBoosters is True: - # logger.debug("Fleet is set, gathering gang boosts") - # - # self.gangBoosts = self.fleet.recalculateLinear(withBoosters=withBoosters) - # - # timer.checkpoint("Done calculating gang boosts for %r"%self) - - # elif self.fleet is None: - # self.gangBoosts = None # If we're not explicitly asked to project fit onto something, # set self as target fit diff --git a/eos/saveddata/fleet.py b/eos/saveddata/fleet.py deleted file mode 100644 index 6fc1b6330..000000000 --- a/eos/saveddata/fleet.py +++ /dev/null @@ -1,341 +0,0 @@ -# =============================================================================== -# 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 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 - for c in chain(self.wings, (self.leader,)): - if c is not None: - c.calculateModifiedAttributes() - - leader = self.leader - self.booster = booster = self.booster if self.booster is not None else leader - self.broken = False - self.store = store = Store() - store.set(booster, "fleet") - # 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): - self.broken = True - - # Now calculate our own if we aren't broken - if not self.broken: - # 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: - self.leader.boostsFits.add(self.wings[0].squads[0].members[0].ID) - self.leader.calculateModifiedAttributes() - self.store.set(self.leader, "squad", clearingUpdate=True) - else: - self.store = Store() - if self.leader is not None: - try: - self.leader.boostsFits.remove(self.wings[0].squads[0].members[0].ID) - except KeyError: - pass - self.wings[0].recalculateLinear(self.store, withBoosters=withBoosters, dirtyStorage=dirtyStorage) - return self.linearBoosts - - def count(self): - total = 0 - for wing in self.wings: - total += wing.count() - - return total - - def extend(self): - self.wings.append(Wing()) - - def __deepcopy__(self, memo): - copy = Fleet() - copy.name = self.name - copy.booster = deepcopy(self.booster) - copy.leader = deepcopy(self.leader) - for wing in self.wings: - copy.wings.append(deepcopy(wing)) - - return copy - - -class Wing(object): - def calculateModifiedAttributes(self): - for c in chain(self.squads, (self.leader,)): - if c is not None: - c.calculateModifiedAttributes() - - def calculateGangBonusses(self, store): - self.broken = False - leader = self.leader - self.booster = booster = self.booster if self.booster is not None else leader - - store.set(booster, "wing") - - # 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): - self.broken = True - - # 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 - 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: - self.leader.boostsFits.add(self.squads[0].members[0].ID) - self.leader.calculateModifiedAttributes() - store.set(self.leader, "squad", clearingUpdate=False) - else: - store = Store() - if self.gang.leader is not None: - try: - self.gang.leader.boostsFits.remove(self.squads[0].members[0].ID) - except KeyError: - pass - if self.leader is not None: - try: - self.leader.boostsFits.remove(self.squads[0].members[0].ID) - except KeyError: - pass - self.squads[0].recalculateLinear(store, withBoosters=withBoosters, dirtyStorage=dirtyStorage) - - def count(self): - total = 0 if self.leader is None else 1 - for squad in self.squads: - total += squad.count() - - return total - - def extend(self): - self.squads.append(Squad()) - - def __deepcopy__(self, memo): - copy = Wing() - copy.booster = deepcopy(self.booster) - copy.leader = deepcopy(self.leader) - for squad in self.squads: - copy.squads.append(deepcopy(squad)) - - return copy - - -class Squad(object): - def calculateModifiedAttributes(self): - for member in self.members: - member.calculateModifiedAttributes() - - def calculateGangBonusses(self, store): - self.broken = False - leader = self.leader - self.booster = booster = self.booster if self.booster is not None else leader - 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): - self.broken = True - - if not self.broken: - for member in self.members: - store.apply(member, "squad") - else: - self.wing.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( - "Leadership").level >= 1: - self.leader.boostsFits.add(self.members[0].ID) - self.leader.calculateModifiedAttributes(dirtyStorage=dirtyStorage) - store.set(self.leader, "squad", clearingUpdate=False) - else: - store = Store() - if self.leader is not None: - try: - self.leader.boostsFits.remove(self.members[0].ID) - except KeyError: - pass - if self.wing.leader is not None: - try: - self.wing.leader.boostsFits.remove(self.members[0].ID) - except KeyError: - pass - if self.wing.gang.leader is not None: - try: - self.wing.gang.leader.boostsFits.remove(self.members[0].ID) - except KeyError: - pass - if getattr(self.wing.gang, "linearBoosts", None) is None: - self.wing.gang.linearBoosts = {} - dict = store.bonuses["squad"] - for boostedAttr, boostInfoList in dict.iteritems(): - for boostInfo in boostInfoList: - effect, thing = boostInfo - # Get current boost value for given attribute, use 0 as fallback if - # no boosts applied yet - currBoostAmount = self.wing.gang.linearBoosts.get(boostedAttr, (0,))[0] - # Attribute name which is used to get boost value - newBoostAttr = effect.getattr("gangBonus") or "commandBonus" - # Get boost amount for current boost - newBoostAmount = thing.getModifiedItemAttr(newBoostAttr) or 0 - # Skill used to modify the gang bonus (for purposes of comparing old vs new) - newBoostSkill = effect.getattr("gangBonusSkill") - # If skill takes part in gang boosting, multiply by skill level - if type(thing) == Skill: - newBoostAmount *= thing.level - # boost the gang bonus based on skill noted in effect file - if newBoostSkill: - newBoostAmount *= thing.parent.character.getSkill(newBoostSkill).level - # If new boost is more powerful, replace older one with it - if abs(newBoostAmount) > abs(currBoostAmount): - self.wing.gang.linearBoosts[boostedAttr] = (newBoostAmount, boostInfo) - - def count(self): - return len(self.members) - - def __deepcopy__(self, memo): - copy = Squad() - copy.booster = deepcopy(self.booster) - copy.leader = deepcopy(self.leader) - for member in self.members: - copy.members.append(deepcopy(member)) - - return copy - - -class Store(object): - def __init__(self): - # Container for gang boosters and their respective bonuses, three-layered - self.bonuses = {} - for dictType in ("fleet", "wing", "squad"): - self.bonuses[dictType] = {} - # Container for boosted fits and corresponding boosts applied onto them - self.boosts = {} - - def set(self, fitBooster, layer, clearingUpdate=True): - """Add all gang boosts of given fit for given layer to boost store""" - if fitBooster is None: - return - - # This dict contains all bonuses for specified layer - dict = self.bonuses[layer] - if clearingUpdate is True: - # Clear existing bonuses - dict.clear() - - # Go through everything which can be used as gang booster - for thing in chain(fitBooster.modules, fitBooster.implants, fitBooster.character.skills, (fitBooster.ship,)): - if thing.item is None: - continue - for effect in thing.item.effects.itervalues(): - # And check if it actually has gang boosting effects - if effect.isType("gang"): - # Attribute which is boosted - boostedAttr = effect.getattr("gangBoost") - # List which contains all bonuses for given attribute for given layer - l = dict.get(boostedAttr) - # If there was no list, create it - if l is None: - l = dict[boostedAttr] = [] - # And append effect which is used to boost stuff and carrier of this effect - l.append((effect, thing)) - - contextMap = {Skill: "skill", - Ship: "ship", - Module: "module"} - - def apply(self, fitBoosted, layer): - """Applies all boosts onto given fit for given layer""" - if fitBoosted is None: - return - # Boosts dict contains all bonuses applied onto given fit - self.boosts[fitBoosted] = boosts = {} - # Go through all bonuses for given layer, and find highest one per boosted attribute - for currLayer in ("fleet", "wing", "squad"): - # Dictionary with boosts for given layer - dict = self.bonuses[currLayer] - for boostedAttr, boostInfoList in dict.iteritems(): - for boostInfo in boostInfoList: - effect, thing = boostInfo - # Get current boost value for given attribute, use 0 as fallback if - # no boosts applied yet - currBoostAmount = boosts.get(boostedAttr, (0,))[0] - # Attribute name which is used to get boost value - newBoostAttr = effect.getattr("gangBonus") or "commandBonus" - # Get boost amount for current boost - newBoostAmount = thing.getModifiedItemAttr(newBoostAttr) or 0 - # Skill used to modify the gang bonus (for purposes of comparing old vs new) - newBoostSkill = effect.getattr("gangBonusSkill") - # If skill takes part in gang boosting, multiply by skill level - if type(thing) == Skill: - newBoostAmount *= thing.level - # boost the gang bonus based on skill noted in effect file - if newBoostSkill: - newBoostAmount *= thing.parent.character.getSkill(newBoostSkill).level - # If new boost is more powerful, replace older one with it - if abs(newBoostAmount) > abs(currBoostAmount): - boosts[boostedAttr] = (newBoostAmount, boostInfo) - - # Don't look further down then current layer, wing commanders don't get squad bonuses and all that - if layer == currLayer: - break - - self.modify(fitBoosted) - - def getBoosts(self, fit): - """Return all boosts applied onto given fit""" - return self.boosts.get(fit) - - def modify(self, fitBoosted): - # Get all boosts which should be applied onto current fit - boosts = self.getBoosts(fitBoosted) - # Now we got it all figured out, actually do the useful part of all this - for name, info in boosts.iteritems(): - # Unpack all data required to run effect properly - effect, thing = info[1] - context = ("gang", self.contextMap[type(thing)]) - # Run effect, and get proper bonuses applied - try: - effect.handler(fitBoosted, thing, context) - except: - pass diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index 1a1c56de3..567be64d6 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -655,10 +655,14 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): effect.activeByDefault and \ (effect.isType("offline") or (effect.isType("passive") and self.state >= State.ONLINE) or + (effect.isType("active") and self.state >= State.ACTIVE))\ and ((projected and effect.isType("projected")) or not projected)\ and ((gang and effect.isType("gang")) or not gang): - effect.handler(fit, self, context) + try: + effect.handler(fit, self, context, effect=effect) + except: + effect.handler(fit, self, context) @property def cycleTime(self): diff --git a/eos/types.py b/eos/types.py index d42cd0fe8..1fbf2676b 100644 --- a/eos/types.py +++ b/eos/types.py @@ -39,7 +39,6 @@ from eos.saveddata.implantSet import ImplantSet from eos.saveddata.booster import Booster from eos.saveddata.fit import Fit, ImplantLocation 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 diff --git a/gui/builtinViews/__init__.py b/gui/builtinViews/__init__.py index 46a500f7b..d51fdbad6 100644 --- a/gui/builtinViews/__init__.py +++ b/gui/builtinViews/__init__.py @@ -1 +1 @@ -__all__ = ["fittingView", "fleetView", "implantEditor"] +__all__ = ["fittingView", "implantEditor"] diff --git a/gui/builtinViews/fleetView.py b/gui/builtinViews/fleetView.py deleted file mode 100644 index bc6eef9a2..000000000 --- a/gui/builtinViews/fleetView.py +++ /dev/null @@ -1,140 +0,0 @@ -import wx.gizmos -import gui.fleetBrowser -import service -from gui.bitmapLoader import BitmapLoader - -#Tab spawning handler -class FleetSpawner(gui.multiSwitch.TabSpawner): - def __init__(self, multiSwitch): - self.multiSwitch = multiSwitch - mainFrame = gui.mainFrame.MainFrame.getInstance() - mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_SELECTED, self.fleetSelected) - - def fleetSelected(self, event): - if self.multiSwitch.GetPageCount() == 0: - self.multiSwitch.AddPage(wx.Panel(self.multiSwitch, size = (0,0)), "Empty Tab") - - view = FleetView(self.multiSwitch) - self.multiSwitch.ReplaceActivePage(view) - view.populate(event.fleetID) - view.Show() - -FleetSpawner.register() - -class FleetView(wx.gizmos.TreeListCtrl): - def __init__(self, parent, size = (0,0)): - wx.gizmos.TreeListCtrl.__init__(self, parent, size = size) - - self.tabManager = parent - - self.fleetId = None - self.fleetImg = BitmapLoader.getImage("53_16", "icons") - - self.imageList = wx.ImageList(16, 16) - self.SetImageList(self.imageList) - - for col in ("", "Fit", "Shiptype", "Character", "Bonusses"): - self.AddColumn(col) - - self.SetMainColumn(1) - self.icons = {} - self.addImage = self.imageList.Add(BitmapLoader.getBitmap("add_small", "gui")) - for icon in ("fb", "fc", "sb", "sc", "wb", "wc"): - self.icons[icon] = self.imageList.Add(BitmapLoader.getBitmap("fleet_%s_small" % icon, "gui")) - - self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.checkNew) - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - - self.mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_RENAMED, self.fleetRenamed) - self.mainFrame.Bind(gui.fleetBrowser.EVT_FLEET_REMOVED, self.fleetRemoved) - - def Destroy(self): - self.mainFrame.Unbind(gui.fleetBrowser.EVT_FLEET_REMOVED, handler = self.fleetRemoved) - self.mainFrame.Unbind(gui.fleetBrowser.EVT_FLEET_RENAMED, handler = self.fleetRenamed) - wx.gizmos.TreeListCtrl.Destroy(self) - - def fleetRenamed(self, event): - if event.fleetID == self.fleetId: - sFleet = service.Fleet.getInstance() - f = sFleet.getFleetByID(event.fleetID) - self.UpdateTab(f.name, self.fleetImg) - - event.Skip() - - def fleetRemoved(self, event): - if event.fleetID == self.fleetId: - self.tabManager.DeletePage(self.tabManager.GetPageIndex(self)) - - event.Skip() - - def checkNew(self, event): - data = self.GetPyData(event.Item) - if data and isinstance(data, tuple) and data[0] == "add": - layer = data[1] - - - def UpdateTab(self, name, img): - self.tabManager.SetPageTextIcon(self.tabManager.GetSelection(), name, img) - - def populate(self, fleetID): - sFleet = service.Fleet.getInstance() - f = sFleet.getFleetByID(fleetID) - self.fleetId = fleetID - - self.UpdateTab( f.name, self.fleetImg) - self.fleet = f - self.DeleteAllItems() - root = self.AddRoot("") - - self.setEntry(root, f.leader, "fleet", f) - for wing in f.wings: - wingId = self.AppendItem(root, "") - self.setEntry(wingId, wing.leader, "wing", wing) - for squad in wing.squads: - for member in squad.members: - memberId = self.AppendItem(wingId, "") - self.setEntry(memberId, member, "squad", squad) - - self.addAdder(wingId, "squad") - - self.addAdder(root, "wing") - - self.ExpandAll(root) - self.SetColumnWidth(0, 16) - for i in xrange(1, 5): - self.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) - headerWidth = self.GetColumnWidth(i) + 5 - self.SetColumnWidth(i, wx.LIST_AUTOSIZE) - baseWidth = self.GetColumnWidth(i) - if baseWidth < headerWidth: - self.SetColumnWidth(i, headerWidth) - else: - self.SetColumnWidth(i, baseWidth) - - - def addAdder(self, treeItemId, layer): - id = self.AppendItem(treeItemId, "Add new %s" % layer.capitalize()) - self.SetPyData(id, ("add", layer)) - self.SetItemImage(id, self.addImage, 1) - - def setEntry(self, treeItemId, fit, layer, info): - self.SetPyData(treeItemId, info) - if fit is None: - self.SetItemText(treeItemId, "%s Commander" % layer.capitalize(), 1) - else: - fleet = self.fleet - if fit == info.booster: - self.SetItemImage(treeItemId, self.icons["%sb" % layer[0]], 0) - elif fit == info.leader: - self.SetItemImage(treeItemId, self.icons["%sc" % layer[0]], 1) - - self.SetItemText(treeItemId, fit.name, 1) - self.SetItemText(treeItemId, fit.ship.item.name, 2) - self.SetItemText(treeItemId, fit.character.name, 3) - boosts = fleet.store.getBoosts(fit) - if boosts: - bonusses = [] - for name, info in boosts.iteritems(): - bonusses.append("%s: %.2g" % (name, info[0])) - - self.SetItemText(treeItemId, ", ".join(bonusses), 3) diff --git a/gui/fleetBrowser.py b/gui/fleetBrowser.py deleted file mode 100644 index 7476d7d7f..000000000 --- a/gui/fleetBrowser.py +++ /dev/null @@ -1,456 +0,0 @@ -import wx -import copy -from gui.bitmapLoader import BitmapLoader -import gui.mainFrame -from gui.PFListPane import PFListPane -import service.fleet -from gui.utils.drawUtils import GetPartialText - -from wx.lib.buttons import GenBitmapButton - -import gui.utils.colorUtils as colorUtils -import gui.utils.drawUtils as drawUtils - -import gui.sfBrowserItem as SFItem - -FleetSelected, EVT_FLEET_SELECTED = wx.lib.newevent.NewEvent() -FleetRenamed, EVT_FLEET_RENAMED = wx.lib.newevent.NewEvent() -FleetRemoved, EVT_FLEET_REMOVED = wx.lib.newevent.NewEvent() - - -FleetItemSelect, EVT_FLEET_ITEM_SELECT = wx.lib.newevent.NewEvent() -FleetItemDelete, EVT_FLEET_ITEM_DELETE = wx.lib.newevent.NewEvent() -FleetItemNew, EVT_FLEET_ITEM_NEW = wx.lib.newevent.NewEvent() -FleetItemCopy, EVT_FLEET_ITEM_COPY = wx.lib.newevent.NewEvent() -FleetItemRename, EVT_FLEET_ITEM_RENAME = wx.lib.newevent.NewEvent() - - - -class FleetBrowser(wx.Panel): - def __init__(self, parent): - wx.Panel.__init__(self, parent) - - self.sFleet = service.fleet.Fleet.getInstance() - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - - mainSizer = wx.BoxSizer(wx.VERTICAL) - - self.hpane = FleetBrowserHeader(self) - mainSizer.Add(self.hpane, 0, wx.EXPAND) - - self.m_sl2 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - mainSizer.Add( self.m_sl2, 0, wx.EXPAND, 0 ) - - self.fleetItemContainer = PFFleetItemContainer(self) - - mainSizer.Add(self.fleetItemContainer, 1, wx.EXPAND) - - self.SetSizer(mainSizer) - self.Layout() - - self.filter = "" - self.fleetIDMustEditName = -1 - - self.Bind(wx.EVT_SIZE, self.SizeRefreshList) - - self.Bind(EVT_FLEET_ITEM_NEW, self.AddNewFleetItem) - self.Bind(EVT_FLEET_ITEM_SELECT, self.SelectFleetItem) - self.Bind(EVT_FLEET_ITEM_DELETE, self.DeleteFleetItem) - self.Bind(EVT_FLEET_ITEM_COPY, self.CopyFleetItem) - self.Bind(EVT_FLEET_ITEM_RENAME, self.RenameFleetItem) - - self.PopulateFleetList() - - def AddNewFleetItem(self, event): - fleetName = event.fleetName - newFleet = self.sFleet.addFleet() - self.sFleet.renameFleet(newFleet, fleetName) - - self.fleetIDMustEditName = newFleet.ID - self.AddItem(newFleet.ID, newFleet.name, newFleet.count()) - - def SelectFleetItem(self, event): - fleetID = event.fleetID - self.fleetItemContainer.SelectWidgetByFleetID(fleetID) - wx.PostEvent(self.mainFrame, FleetSelected(fleetID=fleetID)) - - def CopyFleetItem(self, event): - fleetID = event.fleetID - fleet = self.sFleet.copyFleetByID(fleetID) - - fleetName = fleet.name + " Copy" - self.sFleet.renameFleet(fleet,fleetName) - - self.fleetIDMustEditName = fleet.ID - self.AddItem(fleet.ID, fleet.name, fleet.count()) - - self.fleetItemContainer.SelectWidgetByFleetID(fleet.ID) - wx.PostEvent(self.mainFrame, FleetSelected(fleetID=fleet.ID)) - - def RenameFleetItem(self, event): - fleetID = event.fleetID - fleet = self.sFleet.getFleetByID(fleetID) - - newFleetName = event.fleetName - - self.sFleet.renameFleet(fleet, newFleetName) - wx.PostEvent(self.mainFrame, FleetRenamed(fleetID = fleet.ID)) - - def DeleteFleetItem(self, event): - self.sFleet.deleteFleetByID(event.fleetID) - self.PopulateFleetList() - wx.PostEvent(self.mainFrame, FleetRemoved(fleetID = event.fleetID)) - - def AddItem (self, ID, name, count): - self.fleetItemContainer.AddWidget(FleetItem(self, ID, name, count)) - widget = self.fleetItemContainer.GetWidgetByFleetID(ID) - self.fleetItemContainer.RefreshList(True) - self.fleetItemContainer.ScrollChildIntoView(widget) - wx.PostEvent(self, FleetItemSelect(fleetID = ID)) - - def PopulateFleetList(self): - self.Freeze() - filter = self.filter - self.fleetItemContainer.RemoveAllChildren() - fleetList = self.sFleet.getFleetList() - for fleetID, fleetName, fleetCount in fleetList: - if fleetName.lower().find(filter.lower()) != -1: - self.fleetItemContainer.AddWidget(FleetItem(self, fleetID, fleetName, fleetCount)) - self.fleetItemContainer.RefreshList() - self.Thaw() - - def SetFilter(self, filter): - self.filter = filter - - def SizeRefreshList(self, event): - ewidth, eheight = event.GetSize() - self.Layout() - self.fleetItemContainer.Layout() - self.fleetItemContainer.RefreshList(True) - event.Skip() - - -class FleetBrowserHeader (wx.Panel): - def __init__(self, parent): - wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 24), style=wx.TAB_TRAVERSAL) - self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) ) - - self.newBmp = BitmapLoader.getBitmap("fit_add_small","gui") - bmpSize = (16,16) - - mainSizer = wx.BoxSizer(wx.HORIZONTAL) - - if 'wxMac' in wx.PlatformInfo: - bgcolour = wx.Colour(0, 0, 0, 0) - else: - bgcolour = wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) - - self.fbNewFleet = PFGenBitmapButton( self, wx.ID_ANY, self.newBmp, wx.DefaultPosition, bmpSize, wx.BORDER_NONE ) - mainSizer.Add(self.fbNewFleet, 0, wx.LEFT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL , 5) - self.fbNewFleet.SetBackgroundColour( bgcolour ) - - self.sl1 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_VERTICAL ) - mainSizer.Add( self.sl1, 0, wx.EXPAND |wx.LEFT, 5 ) - - self.tcFilter = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) - mainSizer.Add( self.tcFilter, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.stStatus = wx.StaticText( self, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stStatus.Wrap( -1 ) - mainSizer.Add( self.stStatus, 1, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.SetSizer(mainSizer) - self.Layout() - - self.fbNewFleet.Bind(wx.EVT_ENTER_WINDOW, self.fbNewEnterWindow) - self.fbNewFleet.Bind(wx.EVT_LEAVE_WINDOW, self.fbHItemLeaveWindow) - self.fbNewFleet.Bind(wx.EVT_BUTTON, self.OnNewFleetItem) - - self.tcFilter.Bind(wx.EVT_TEXT, self.OnFilterText) - - self.tcFilter.Bind(wx.EVT_ENTER_WINDOW, self.fbFilterEnterWindow) - self.tcFilter.Bind(wx.EVT_LEAVE_WINDOW, self.fbHItemLeaveWindow) - - def OnFilterText(self, event): - filter = self.tcFilter.GetValue() - self.Parent.SetFilter(filter) - self.Parent.PopulateFleetList() - event.Skip() - - def OnNewFleetItem(self, event): - wx.PostEvent(self.Parent, FleetItemNew(fleetName = "New Fleet")) - - def fbNewEnterWindow(self, event): - self.stStatus.SetLabel("New fleet") - self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) - event.Skip() - - def fbHItemLeaveWindow(self, event): - self.stStatus.SetLabel("") - self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) - event.Skip() - - def fbFilterEnterWindow(self, event): - self.stStatus.SetLabel("Filter list") - event.Skip() - - - -class PFFleetItemContainer(PFListPane): - def __init__(self,parent): - PFListPane.__init__(self,parent) - self.selectedWidget = -1 - self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) - - def IsWidgetSelectedByContext(self, widget): - if self.GetWidgetList()[widget].IsSelected(): - return True - return False - - def GetWidgetIndex(self, widgetWnd): - return self.GetWidgetList().index(widgetWnd) - - def GetWidgetByFleetID(self, fleetID): - for widget in self.GetWidgetList(): - if widget.fleetID == fleetID: - return widget - return None - - def SelectWidget(self, widgetWnd): - wlist = self.GetWidgetList() - if self.selectedWidget != -1: - wlist[self.selectedWidget].SetSelected(False) - wlist[self.selectedWidget].Refresh() - windex = self.GetWidgetIndex(widgetWnd) - wlist[windex].SetSelected(True) - wlist[windex].Refresh() - self.selectedWidget = windex - - def SelectWidgetByFleetID(self, fleetID): - widgetWnd = self.GetWidgetByFleetID(fleetID) - if widgetWnd: - self.SelectWidget(widgetWnd) - - def RemoveWidget(self, child): - child.Destroy() - self.selectedWidget = -1 - self._wList.remove(child) - - - def RemoveAllChildren(self): - for widget in self._wList: - widget.Destroy() - - self.selectedWidget = -1 - self._wList = [] - - def OnLeftUp(self, event): - event.Skip() - -class FleetItem(SFItem.SFBrowserItem): - def __init__(self, parent, fleetID, fleetName, fleetCount, - id=wx.ID_ANY, pos=wx.DefaultPosition, - size=(0,40), style=0): - SFItem.SFBrowserItem.__init__(self, parent, size = size) - - self.fleetBrowser = self.Parent - self.fleetID = fleetID - self.fleetName = fleetName - self.fleetCount = fleetCount - - self.padding = 4 - - self.fontBig = wx.FontFromPixelSize((0,15),wx.SWISS, wx.NORMAL, wx.BOLD, False) - self.fontNormal = wx.FontFromPixelSize((0,14),wx.SWISS, wx.NORMAL, wx.NORMAL, False) - self.fontSmall = wx.FontFromPixelSize((0,12),wx.SWISS, wx.NORMAL, wx.NORMAL, False) - - self.copyBmp = BitmapLoader.getBitmap("fit_add_small", "gui") - self.renameBmp = BitmapLoader.getBitmap("fit_rename_small", "gui") - self.deleteBmp = BitmapLoader.getBitmap("fit_delete_small","gui") - self.acceptBmp = BitmapLoader.getBitmap("faccept_small", "gui") - self.fleetBmp = BitmapLoader.getBitmap("fleet_item_big", "gui") - - fleetImg = self.fleetBmp.ConvertToImage() - fleetImg = fleetImg.Blur(2) - - if not fleetImg.HasAlpha(): - fleetImg.InitAlpha() - - fleetImg = fleetImg.AdjustChannels(1, 1, 1, 0.5) - self.fleetEffBmp = wx.BitmapFromImage(fleetImg) - - self.toolbar.AddButton(self.copyBmp, "Copy", self.CopyFleetCB) - self.renameBtn = self.toolbar.AddButton(self.renameBmp, "Rename", self.RenameFleetCB) - self.toolbar.AddButton(self.deleteBmp, "Delete", self.DeleteFleetCB) - - self.editWidth = 150 - self.tcFleetName = wx.TextCtrl(self, wx.ID_ANY, "%s" % self.fleetName, wx.DefaultPosition, (self.editWidth,-1), wx.TE_PROCESS_ENTER) - - if self.fleetBrowser.fleetIDMustEditName != self.fleetID: - self.tcFleetName.Show(False) - else: - self.tcFleetName.SetFocus() - self.tcFleetName.SelectAll() - self.fleetBrowser.fleetIDMustEditName = -1 - self.renameBtn.SetBitmap(self.acceptBmp) - self.selected = True - - self.tcFleetName.Bind(wx.EVT_KILL_FOCUS, self.OnEditLostFocus) - self.tcFleetName.Bind(wx.EVT_TEXT_ENTER, self.RenameFleet) - self.tcFleetName.Bind(wx.EVT_KEY_DOWN, self.EditCheckEsc) - - - self.animCount = 0 - - def MouseLeftUp(self, event): - if self.tcFleetName.IsShown(): - self.RestoreEditButton() - else: - wx.PostEvent(self.fleetBrowser, FleetItemSelect(fleetID = self.fleetID)) - - def CopyFleetCB(self): - if self.tcFleetName.IsShown(): - self.RestoreEditButton() - return - - wx.PostEvent(self.fleetBrowser, FleetItemCopy(fleetID = self.fleetID)) - - def RenameFleetCB(self): - - if self.tcFleetName.IsShown(): - - self.RenameFleet(None) - self.RestoreEditButton() - - else: - self.tcFleetName.SetValue(self.fleetName) - self.tcFleetName.Show() - - self.renameBtn.SetBitmap(self.acceptBmp) - self.Refresh() - - self.tcFleetName.SetFocus() - self.tcFleetName.SelectAll() - - self.Refresh() - - def RenameFleet(self, event): - - newFleetName = self.tcFleetName.GetValue() - self.fleetName = newFleetName - - self.tcFleetName.Show(False) - - wx.PostEvent(self.fleetBrowser, FleetItemRename(fleetID = self.fleetID, fleetName = self.fleetName)) - self.Refresh() - - def DeleteFleetCB(self): - if self.tcFleetName.IsShown(): - self.RestoreEditButton() - return - wx.PostEvent(self.fleetBrowser, FleetItemDelete(fleetID = self.fleetID)) - - def RestoreEditButton(self): - self.tcFleetName.Show(False) - self.renameBtn.SetBitmap(self.renameBmp) - self.Refresh() - - def OnEditLostFocus(self, event): - self.RestoreEditButton() - self.Refresh() - - def EditCheckEsc(self, event): - if event.GetKeyCode() == wx.WXK_ESCAPE: - self.RestoreEditButton() - else: - event.Skip() - - def IsSelected(self): - return self.selected - - def UpdateElementsPos(self, mdc): - rect = self.GetRect() - - self.toolbarx = rect.width - self.toolbar.GetWidth() - self.padding - self.toolbary = (rect.height - self.toolbar.GetHeight()) / 2 - - self.toolbarx = self.toolbarx + self.animCount - - self.fleetBmpx = self.padding + (rect.height - self.fleetBmp.GetWidth()) / 2 - self.fleetBmpy = (rect.height - self.fleetBmp.GetHeight()) / 2 - - self.fleetBmpx -= self.animCount - - self.textStartx = self.fleetBmpx + self.fleetBmp.GetWidth() + self.padding - - self.fleetNamey = (rect.height - self.fleetBmp.GetHeight()) / 2 - - mdc.SetFont(self.fontBig) - wtext, htext = mdc.GetTextExtent(self.fleetName) - - self.fleetCounty = self.fleetNamey + htext - - mdc.SetFont(self.fontSmall) - - wlabel,hlabel = mdc.GetTextExtent(self.toolbar.hoverLabel) - - self.thoverx = self.toolbarx - self.padding - wlabel - self.thovery = (rect.height - hlabel)/2 - self.thoverw = wlabel - - def DrawItem(self, mdc): - rect = self.GetRect() - - windowColor = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW) - textColor = colorUtils.GetSuitableColor(windowColor, 1) - - mdc.SetTextForeground(textColor) - - self.UpdateElementsPos(mdc) - - self.toolbar.SetPosition((self.toolbarx, self.toolbary)) - mdc.DrawBitmap(self.fleetEffBmp, self.fleetBmpx + 3, self.fleetBmpy + 2) - mdc.DrawBitmap(self.fleetBmp, self.fleetBmpx,self.fleetBmpy) - - mdc.SetFont(self.fontNormal) - - suffix = "%d ships" % self.fleetCount if self.fleetCount >1 else "%d ship" % self.fleetCount if self.fleetCount == 1 else "No ships" - fleetCount = "Fleet size: %s" % suffix - fleetCount = drawUtils.GetPartialText(mdc, fleetCount, self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw) - - mdc.DrawText(fleetCount, self.textStartx, self.fleetCounty) - - mdc.SetFont(self.fontSmall) - mdc.DrawText(self.toolbar.hoverLabel, self.thoverx, self.thovery) - - mdc.SetFont(self.fontBig) - - pfname = drawUtils.GetPartialText(mdc, self.fleetName, self.toolbarx - self.textStartx - self.padding * 2 - self.thoverw) - mdc.DrawText(pfname, self.textStartx, self.fleetNamey) - - if self.tcFleetName.IsShown(): - self.AdjustControlSizePos(self.tcFleetName, self.textStartx, self.toolbarx - self.editWidth - self.padding) - - def AdjustControlSizePos(self, editCtl, start, end): - fnEditSize = editCtl.GetSize() - wSize = self.GetSize() - fnEditPosX = end - fnEditPosY = (wSize.height - fnEditSize.height)/2 - if fnEditPosX < start: - editCtl.SetSize((self.editWidth + fnEditPosX - start,-1)) - editCtl.SetPosition((start,fnEditPosY)) - else: - editCtl.SetSize((self.editWidth,-1)) - editCtl.SetPosition((fnEditPosX,fnEditPosY)) - - -class PFGenBitmapButton(GenBitmapButton): - def __init__(self, parent, id, bitmap, pos, size, style): - GenBitmapButton.__init__(self, parent, id, bitmap, pos, size, style) - self.bgcolor = wx.Brush(wx.WHITE) - - def SetBackgroundColour(self, color): - self.bgcolor = wx.Brush(color) - - def GetBackgroundBrush(self, dc): - return self.bgcolor diff --git a/gui/gangView.py b/gui/gangView.py deleted file mode 100644 index 106f14f98..000000000 --- a/gui/gangView.py +++ /dev/null @@ -1,412 +0,0 @@ -#=============================================================================== -# Copyright (C) 2010 Diego Duclos -# -# This file is part of pyfa. -# -# pyfa is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# pyfa 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with pyfa. If not, see . -#=============================================================================== -import wx -from wx.lib.scrolledpanel import ScrolledPanel - -import service -import gui.mainFrame -import gui.shipBrowser -import gui.globalEvents as GE - -from gui import characterEditor as CharEditor - -class GangView ( ScrolledPanel ): - - def __init__( self, parent ): - ScrolledPanel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 100,20 ), style = wx.TAB_TRAVERSAL | wx.HSCROLL | wx.VSCROLL ) - mainSizer = wx.BoxSizer( wx.VERTICAL ) - - self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)) - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - - self.draggedFitID = None - - help = '''Set fit as booster to display in dropdown, or drag fitting from\nship browser to this window, or right click fit and select booster role.''' - helpSizer = wx.BoxSizer( wx.HORIZONTAL ) - self.helpText = wx.StaticText( self, wx.ID_ANY, help, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE ) - helpSizer.Add( self.helpText, 1, wx.ALL, 5 ) - - self.options = ["Fleet", "Wing", "Squad"] - - self.fleet = {} - for id, option in enumerate(self.options): - - # set content for each commander - self.fleet[id] = {} - self.fleet[id]['stLabel'] = wx.StaticText( self, wx.ID_ANY, self.options[id]+':', wx.DefaultPosition, wx.DefaultSize, 0 ) - self.fleet[id]['stText'] = wx.StaticText( self, wx.ID_ANY, 'None', wx.DefaultPosition, wx.DefaultSize, 0 ) - self.fleet[id]['chFit'] = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, [] ) - self.fleet[id]['chChar'] = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, [] ) - self.fleet[id]['fitSizer'] = wx.BoxSizer( wx.VERTICAL ) - - self.FitDNDPopupMenu = self.buildBoostermenu() - - contentFGSizer = wx.FlexGridSizer( 5, 3, 0, 0 ) - contentFGSizer.AddGrowableCol( 1 ) - contentFGSizer.SetFlexibleDirection( wx.BOTH ) - contentFGSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED ) - - ### Header - self.stBooster = wx.StaticText( self, wx.ID_ANY, u"Booster", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stBooster.Wrap( -1 ) - self.stBooster.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - contentFGSizer.Add( self.stBooster, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5 ) - - self.stFits = wx.StaticText( self, wx.ID_ANY, u"Fits", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stFits.Wrap( -1 ) - self.stFits.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - contentFGSizer.Add( self.stFits, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.stCharacters = wx.StaticText( self, wx.ID_ANY, u"Characters", wx.DefaultPosition, wx.DefaultSize, 0 ) - self.stCharacters.Wrap( -1 ) - self.stCharacters.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - contentFGSizer.Add( self.stCharacters, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.m_staticline2 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - contentFGSizer.Add( self.m_staticline2, 0, wx.EXPAND, 5 ) - - self.m_staticline3 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - contentFGSizer.Add( self.m_staticline3, 0, wx.EXPAND, 5 ) - - self.m_staticline4 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) - contentFGSizer.Add( self.m_staticline4, 0, wx.EXPAND, 5 ) - - ### Content - for id in self.fleet: - # set various properties - self.fleet[id]['stLabel'].Wrap( -1 ) - self.fleet[id]['stLabel'].SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) ) - self.fleet[id]['stText'].Wrap( -1 ) - - # bind text and choice events - self.fleet[id]['stText'].Bind(wx.EVT_LEFT_DCLICK, self.RemoveBooster) - self.fleet[id]['stText'].Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow) - self.fleet[id]['stText'].Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow) - self.fleet[id]['stText'].SetToolTip(wx.ToolTip("Double click to remove booster")) - self.fleet[id]['chChar'].Bind(wx.EVT_CHOICE, self.CharChanged) - self.fleet[id]['chFit'].Bind(wx.EVT_CHOICE, self.OnFitChoiceSelected) - - # add fit text and choice to the fit sizer - self.fleet[id]['fitSizer'].Add( self.fleet[id]['stText'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) - self.fleet[id]['fitSizer'].Add( self.fleet[id]['chFit'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND, 1 ) - - # add everything to the content sizer - contentFGSizer.Add( self.fleet[id]['stLabel'], 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) - contentFGSizer.Add( self.fleet[id]['fitSizer'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND, 5 ) - contentFGSizer.Add( self.fleet[id]['chChar'], 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 ) - - mainSizer.Add( contentFGSizer, 1, wx.EXPAND, 0 ) - mainSizer.Add( helpSizer, 0, wx.EXPAND, 0 ) - - self.SetSizer( mainSizer ) - self.SetAutoLayout(True) - self.SetupScrolling() - - self.mainFrame.Bind(GE.CHAR_LIST_UPDATED, self.RefreshCharacterList) - self.mainFrame.Bind(GE.FIT_CHANGED, self.fitSelected) - self.mainFrame.Bind(gui.shipBrowser.EVT_FIT_RENAMED, self.fitRenamed) - self.mainFrame.Bind(gui.shipBrowser.BOOSTER_LIST_UPDATED, self.RefreshBoosterFits) - - self.RefreshBoosterFits() - self.RefreshCharacterList() - - def buildBoostermenu(self): - menu = wx.Menu() - - for id, option in enumerate(self.options): - item = menu.Append(-1, option) - # We bind it to the mainFrame because it may be called from either this class or from FitItem via shipBrowser - self.mainFrame.Bind(wx.EVT_MENU, self.OnPopupItemSelected, item) - return menu - - def OnEnterWindow(self, event): - obj = event.GetEventObject() - obj.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) - event.Skip() - - def OnLeaveWindow(self, event): - obj = event.GetEventObject() - obj.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) - event.Skip() - - def CharChanged(self, event): - ''' Change booster character ''' - chBooster = event.GetEventObject() - - type = -1 - for id in self.fleet: - if chBooster == self.fleet[id]['chChar']: type = id - - if type == -1: - event.Skip() - return - - sFit = service.Fit.getInstance() - - fleetSrv = service.Fleet.getInstance() - - activeFitID = self.mainFrame.getActiveFit() - fit = sFit.getFit(activeFitID) - - sChar = service.Character.getInstance() - charList = sChar.getCharacterList() - - if activeFitID: - commanders = fleetSrv.loadLinearFleet(fit) - if commanders is None: - fleetCom, wingCom, squadCom = (None, None, None) - else: - fleetCom, wingCom, squadCom = commanders - - if type == 0: - if fleetCom: - charID = chBooster.GetClientData(chBooster.GetSelection()) - sFit.changeChar(fleetCom.ID, charID) - else: - chBooster.SetSelection(0) - - if type == 1: - if wingCom: - charID = chBooster.GetClientData(chBooster.GetSelection()) - sFit.changeChar(wingCom.ID, charID) - else: - chBooster.SetSelection(0) - - if type == 2: - if squadCom: - charID = chBooster.GetClientData(chBooster.GetSelection()) - sFit.changeChar(squadCom.ID, charID) - else: - chBooster.SetSelection(0) - - sFit.recalc(fit, withBoosters=True) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) - - else: - chBooster.SetSelection(0) - - def RemoveBooster(self, event): - activeFitID = self.mainFrame.getActiveFit() - if not activeFitID: - return - - location = event.GetEventObject() - - for id in self.fleet: - if location == self.fleet[id]['stText']: type = id - - sFit = service.Fit.getInstance() - boostee = sFit.getFit(activeFitID) - booster = None - - fleetSrv = service.Fleet.getInstance() - - if type == 0: fleetSrv.setLinearFleetCom(boostee, booster) - if type == 1: fleetSrv.setLinearWingCom(boostee, booster) - if type == 2: fleetSrv.setLinearSquadCom(boostee, booster) - - # Hide stText and, default fit selection, and enable it - location.Hide() - choice = self.fleet[type]['chFit'] - choice.SetSelection(0) - choice.Show() - - sFit.recalc(boostee, withBoosters=True) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) - - def fitRenamed(self, event): - fleetSrv = service.Fleet.getInstance() - activeFitID = self.mainFrame.getActiveFit() - - if activeFitID: - ev = event - ev.fitID = activeFitID - self.fitSelected(ev) - - def fitSelected(self, event): - ''' Fires when active fit is selected and when booster is saved to fit. Update the UI to reflect changes ''' - fleetSrv = service.Fleet.getInstance() - - activeFitID = self.mainFrame.getActiveFit() - sFit = service.Fit.getInstance() - fit = sFit.getFit(event.fitID or activeFitID) - - self.Parent.Parent.DisablePage(self, not fit or fit.isStructure) - - commanders = (None, None, None) - - if activeFitID: - commanders = fleetSrv.loadLinearFleet(fit) - - for id in self.fleet: - # try...except here as we're trying 2 different criteria and want to fall back on the same code - try: - commander = commanders[id] - - if not activeFitID or commander is None: - raise Exception() - - self.fleet[id]['stText'].SetLabel(commander.ship.item.name + ": " + commander.name) - self.fleet[id]['chChar'].SetStringSelection(commander.character.name if commander.character is not None else "All 0") - self.fleet[id]['chChar'].Enable() - self.fleet[id]['chFit'].Hide() - self.fleet[id]['stText'].Show() - except: - #set defaults, disable char selection, and enable fit selection - self.fleet[id]['stText'].SetLabel("None") - self.fleet[id]['chChar'].SetStringSelection("All 0") - self.fleet[id]['chChar'].Disable() - self.fleet[id]['chFit'].SetSelection(0) - self.fleet[id]['chFit'].Show() - self.fleet[id]['stText'].Hide() - - if activeFitID: - self.Enable() - else: - self.Disable() - - self.Layout() - self.SendSizeEvent() - - def AddCommander(self, fitID, type = None): - ''' Adds booster to a fit, then recalculates active fit ''' - if type is None: - return - - activeFitID = self.mainFrame.getActiveFit() - if activeFitID: - sFit = service.Fit.getInstance() - - boostee = sFit.getFit(activeFitID) - booster = sFit.getFit(fitID) - - fleetSrv = service.Fleet.getInstance() - - if type == 0: fleetSrv.setLinearFleetCom(boostee, booster) - if type == 1: fleetSrv.setLinearWingCom(boostee, booster) - if type == 2: fleetSrv.setLinearSquadCom(boostee, booster) - - sFit.recalc(boostee) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=activeFitID)) - - def RefreshBoosterFits(self, event = None): - sFit = service.Fit.getInstance() - sMkt = service.Market.getInstance() - fitList = sFit.getBoosterFits() - - for id in self.fleet: - choice = self.fleet[id]['chFit'] - chCurrSelection = choice.GetSelection() - chCurrData = -1 - if chCurrSelection != -1: - chCurrData = choice.GetClientData(chCurrSelection) - chCurrSelString = choice.GetString(chCurrSelection) - choice.Clear() - currSelFound = False - choice.Append("None", -1) - for fit in fitList: - id,name,type = fit - ship = sMkt.getItem(type) - choice.Append(ship.name+': '+name, id) - if chCurrData == id: - currSelFound = True - - if chCurrSelection == -1: - choice.SetSelection(0) - else: - if currSelFound: - choice.SetStringSelection(chCurrSelString) - else: - choice.SetSelection(0) - - def RefreshCharacterList(self, event = None): - sChar = service.Character.getInstance() - charList = sChar.getCharacterList() - for id in self.fleet: - choice = self.fleet[id]['chChar'] - chCurrSelection = choice.GetSelection() - chCurrData = -1 - if chCurrSelection != -1: - chCurrData = choice.GetClientData(chCurrSelection) - chCurrSelString = choice.GetString(chCurrSelection) - choice.Clear() - currSelFound = False - for char in charList: - choice.Append(char.name, char.ID) - if chCurrData == char.ID: - currSelFound = True - - if chCurrSelection == -1: - choice.SetSelection(1) - else: - if currSelFound: - choice.SetStringSelection(chCurrSelString) - else: - choice.SetSelection(1) - - def handleDrag(self, type, fitID): - ''' Handle dragging of fit to fleet interface ''' - #Those are drags coming from pyfa sources, NOT builtin wx drags - self.draggedFitID = None - if type == "fit": - sFit = service.Fit.getInstance() - fit = sFit.getFit(self.mainFrame.getActiveFit()) - - if fit and not fit.isStructure: - self.draggedFitID = fitID - - pos = wx.GetMousePosition() - pos = self.ScreenToClient(pos) - - self.PopupMenu(self.FitDNDPopupMenu, pos) - - - def OnPopupItemSelected(self, event): - ''' Fired when booster popup item is selected ''' - # Get menu selection ID via self.options - menuItem = event.EventObject.FindItemById(event.GetId()) - type = self.options.index(menuItem.GetText()) - - if self.draggedFitID: - sFit = service.Fit.getInstance() - draggedFit = sFit.getFit(self.draggedFitID) - - self.AddCommander(draggedFit.ID, type) - self.mainFrame.additionsPane.select("Fleet") - - def OnFitChoiceSelected(self, event): - ''' Fired when booster choice is selected ''' - sFit = service.Fit.getInstance() - - # set type via choice box used - chFit = event.GetEventObject() - fitID = chFit.GetClientData(chFit.GetSelection()) - - type = -1 - for id in self.fleet: - if chFit == self.fleet[id]['chFit']: type = id - - if type == -1 or fitID == -1: - event.Skip() - return - - fit = sFit.getFit(fitID) - - self.AddCommander(fit.ID, type) - self.mainFrame.additionsPane.select("Fleet") diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 49fb9385a..4c2b350a5 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -55,7 +55,6 @@ from gui.preferenceDialog import PreferenceDialog from gui.graphFrame import GraphFrame from gui.copySelectDialog import CopySelectDialog from gui.utils.clipboard import toClipboard, fromClipboard -from gui.fleetBrowser import FleetBrowser from gui.updateDialog import UpdateDialog from gui.builtinViews import * @@ -158,12 +157,6 @@ class MainFrame(wx.Frame): self.shipBrowser = ShipBrowser(self.notebookBrowsers) self.notebookBrowsers.AddPage(self.shipBrowser, "Fittings", tabImage = shipBrowserImg, showClose = False) - #======================================================================= - # DISABLED FOR RC2 RELEASE - #self.fleetBrowser = FleetBrowser(self.notebookBrowsers) - #self.notebookBrowsers.AddPage(self.fleetBrowser, "Fleets", showClose = False) - #======================================================================= - self.notebookBrowsers.SetSelection(1) self.browser_fitting_split.SplitVertically(self.notebookBrowsers, self.fitting_additions_split) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..f8e777507 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +matplotlib +PyYAML +python-dateutil +urllib3 +requests==2.11.1 +sqlalchemy diff --git a/requirements_test.txt b/requirements_test.txt new file mode 100644 index 000000000..1bbef8b92 --- /dev/null +++ b/requirements_test.txt @@ -0,0 +1,7 @@ +pytest==3.0.3 +pytest-mock==1.2 +pytest-cov==2.3.1 +pytest-capturelog==0.7 +coverage==4.2 +coveralls==1.1 +codecov diff --git a/service/__init__.py b/service/__init__.py index b19c6db17..91ed07d82 100644 --- a/service/__init__.py +++ b/service/__init__.py @@ -5,7 +5,6 @@ from service.character import Character from service.damagePattern import DamagePattern from service.targetResists import TargetResists from service.settings import SettingsProvider -from service.fleet import Fleet from service.update import Update from service.price import Price from service.network import Network diff --git a/service/fit.py b/service/fit.py index b2bb691ff..42eb60046 100644 --- a/service/fit.py +++ b/service/fit.py @@ -34,7 +34,6 @@ from eos.types import State, Slot from service.market import Market from service.damagePattern import DamagePattern from service.character import Character -from service.fleet import Fleet from service.settings import SettingsProvider from service.port import Port @@ -186,8 +185,6 @@ class Fit(object): def deleteFit(self, fitID): fit = eos.db.getFit(fitID) - sFleet = Fleet.getInstance() - sFleet.removeAssociatedFleetData(fit) eos.db.remove(fit) @@ -238,7 +235,8 @@ class Fit(object): self.recalc(fit, withBoosters=True) def getFit(self, fitID, projected=False, basic=False): - ''' Gets fit from database, and populates fleet data. + ''' Gets fit from database + Projected is a recursion flag that is set to reduce recursions into projected fits Basic is a flag to simply return the fit without any other processing ''' @@ -252,14 +250,6 @@ class Fit(object): inited = getattr(fit, "inited", None) if inited is None or inited is False: - sFleet = Fleet.getInstance() - f = sFleet.getLinearFleet(fit) - if f is None: - sFleet.removeAssociatedFleetData(fit) - fit.fleet = None - else: - fit.fleet = f - if not projected: for fitP in fit.projectedFits: self.getFit(fitP.ID, projected=True) diff --git a/service/fleet.py b/service/fleet.py deleted file mode 100644 index cfad7f04b..000000000 --- a/service/fleet.py +++ /dev/null @@ -1,215 +0,0 @@ -#=============================================================================== -# Copyright (C) 2010 Diego Duclos -# -# This file is part of pyfa. -# -# pyfa is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# pyfa 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with pyfa. If not, see . -#=============================================================================== - -import eos.db -from eos.types import Fleet as Fleet_, Wing, Squad -import copy - -class Fleet(object): - instance = None - @classmethod - def getInstance(cls): - if cls.instance is None: - cls.instance = Fleet() - - return cls.instance - - def __init__(self): - pass - - def getFleetList(self): - fleetList = [] - fleets = eos.db.getFleetList() - for fleet in fleets: - fleetList.append((fleet.ID, fleet.name, fleet.count())) - - return fleetList - - def getFleetByID(self, ID): - f = eos.db.getFleet(ID) - return f - - def addFleet(self): - f = Fleet_() - eos.db.save(f) - return f - - def renameFleet(self, fleet, newName): - fleet.name = newName - eos.db.commit() - - def copyFleet(self, fleet): - newFleet = copy.deepcopy(fleet) - eos.db.save(newFleet) - return newFleet - - def copyFleetByID(self, ID): - fleet = self.getFleetByID(ID) - return self.copyFleet(fleet) - - def deleteFleet(self, fleet): - eos.db.remove(fleet) - - def deleteFleetByID(self, ID): - fleet = self.getFleetByID(ID) - self.deleteFleet(fleet) - - def makeLinearFleet(self, fit): - f = Fleet_() - w = Wing() - f.wings.append(w) - s = Squad() - w.squads.append(s) - s.members.append(fit) - fit.fleet = f - eos.db.save(f) - - def setLinearFleetCom(self, boostee, booster): - #if boostee == booster: - # return - if self.getLinearFleet(boostee) is None: - self.removeAssociatedFleetData(boostee) - self.makeLinearFleet(boostee) - squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) - squad = eos.db.getSquad(squadIDs.pop()) - if squad.wing.gang.leader is not None and booster is None: - try: - squad.wing.gang.leader.boostsFits.remove(boostee.ID) - except KeyError: - pass - squad.wing.gang.leader = booster - if self.anyBoosters(squad) is False: - self.removeAssociatedFleetData(boostee) - from service.fit import Fit - sFit = Fit.getInstance() - sFit.recalc(boostee, withBoosters=True) - - def setLinearWingCom(self, boostee, booster): - #if boostee == booster: - # return - if self.getLinearFleet(boostee) is None: - self.removeAssociatedFleetData(boostee) - self.makeLinearFleet(boostee) - squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) - squad = eos.db.getSquad(squadIDs.pop()) - if squad.wing.leader is not None and booster is None: - try: - squad.wing.leader.boostsFits.remove(boostee.ID) - except KeyError: - pass - squad.wing.leader = booster - if self.anyBoosters(squad) is False: - self.removeAssociatedFleetData(boostee) - from service.fit import Fit - sFit = Fit.getInstance() - sFit.recalc(boostee, withBoosters=True) - - def setLinearSquadCom(self, boostee, booster): - #if boostee == booster: - # return - if self.getLinearFleet(boostee) is None: - self.removeAssociatedFleetData(boostee) - self.makeLinearFleet(boostee) - squadIDs = set(eos.db.getSquadsIDsWithFitID(boostee.ID)) - squad = eos.db.getSquad(squadIDs.pop()) - if squad.leader is not None and booster is None: - try: - squad.leader.boostsFits.remove(boostee.ID) - except KeyError: - pass - squad.leader = booster - if self.anyBoosters(squad) is False: - self.removeAssociatedFleetData(boostee) - from service.fit import Fit - sFit = Fit.getInstance() - sFit.recalc(boostee, withBoosters=True) - - - def getLinearFleet(self, fit): - sqIDs = eos.db.getSquadsIDsWithFitID(fit.ID) - if len(sqIDs) != 1: - return None - s = eos.db.getSquad(sqIDs[0]) - if len(s.members) != 1: - return None - w = s.wing - if len(w.squads) != 1: - return None - f = w.gang - if len(f.wings) != 1: - return None - return f - - def removeAssociatedFleetData(self, fit): - squadIDs = set(eos.db.getSquadsIDsWithFitID(fit.ID)) - if len(squadIDs) == 0: - return - squads = list(eos.db.getSquad(sqID) for sqID in squadIDs) - wingIDs = set(squad.wing.ID for squad in squads) - fleetIDs = set(squad.wing.gang.ID for squad in squads) - for fleetID in fleetIDs: - fleet = eos.db.getFleet(fleetID) - for wing in fleet.wings: - wingIDs.add(wing.ID) - for wingID in wingIDs: - wing = eos.db.getWing(wingID) - for squad in wing.squads: - squadIDs.add(squad.ID) - for squadID in squadIDs: - squad = eos.db.getSquad(squadID) - if squad.leader is not None: - try: - squad.leader.boostsFits.remove(fit.ID) - except KeyError: - pass - eos.db.remove(squad) - for wingID in wingIDs: - wing = eos.db.getWing(wingID) - if wing.leader is not None: - try: - wing.leader.boostsFits.remove(fit.ID) - except KeyError: - pass - eos.db.remove(wing) - for fleetID in fleetIDs: - fleet = eos.db.getFleet(fleetID) - if fleet.leader is not None: - try: - fleet.leader.boostsFits.remove(fit.ID) - except KeyError: - pass - eos.db.remove(fleet) - fit.fleet = None - return - - def anyBoosters(self, squad): - wing = squad.wing - fleet = wing.gang - if squad.leader is None and wing.leader is None and fleet.leader is None: - return False - return True - - def loadLinearFleet(self, fit): - if self.getLinearFleet(fit) is None: - return None - squadID = eos.db.getSquadsIDsWithFitID(fit.ID)[0] - s = eos.db.getSquad(squadID) - w = s.wing - f = w.gang - return (f.leader, w.leader, s.leader)