From d416124081a76712c4891ca2be4df79f08b9ea36 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Sat, 30 Apr 2016 19:49:45 -0400 Subject: [PATCH] Implemented projected fighters, and various fighter bugfixes / improvements --- eos/db/saveddata/fit.py | 6 ++++++ eos/effects/fighterabilityecm.py | 2 +- eos/effects/fighterabilityenergyneutralizer.py | 5 ++--- eos/effects/fighterabilitystasiswebifier.py | 3 +-- eos/saveddata/fighter.py | 3 +++ eos/saveddata/fit.py | 10 ++++++++-- eos/types.py | 1 - gui/builtinContextMenus/amount.py | 2 +- gui/builtinContextMenus/fighterAbilities.py | 2 +- gui/builtinContextMenus/itemRemove.py | 5 ++++- gui/builtinContextMenus/itemStats.py | 3 ++- gui/builtinContextMenus/marketJump.py | 3 ++- gui/builtinViewColumns/abilities.py | 9 ++++++--- gui/builtinViewColumns/ammo.py | 9 +++++++++ gui/implantView.py | 3 +++ gui/projectedView.py | 17 +++++++++++++++-- service/fit.py | 11 +++++++++++ 17 files changed, 75 insertions(+), 19 deletions(-) diff --git a/eos/db/saveddata/fit.py b/eos/db/saveddata/fit.py index 29f51ef6c4..060d7b2a1d 100644 --- a/eos/db/saveddata/fit.py +++ b/eos/db/saveddata/fit.py @@ -137,6 +137,12 @@ def __repr__(self): cascade='all, delete, delete-orphan', single_parent=True, primaryjoin=and_(drones_table.c.fitID == fits_table.c.ID, drones_table.c.projected == True)), + "_Fit__projectedFighters": relation( + Fighter, + collection_class=HandledProjectedDroneList, + cascade='all, delete, delete-orphan', + single_parent=True, + primaryjoin=and_(fighters_table.c.fitID == fits_table.c.ID, fighters_table.c.projected == True)), "_Fit__implants": relation( Implant, collection_class=HandledImplantBoosterList, diff --git a/eos/effects/fighterabilityecm.py b/eos/effects/fighterabilityecm.py index 10be847667..e211e7424f 100644 --- a/eos/effects/fighterabilityecm.py +++ b/eos/effects/fighterabilityecm.py @@ -13,6 +13,6 @@ def handler(fit, module, context): if "projected" not in context: return # jam formula: 1 - (1- (jammer str/ship str))^(# of jam mods with same str)) - strModifier = 1 - module.getModifiedItemAttr("{}Srength{}".format(prefix, fit.scanType))/fit.scanStrength + strModifier = 1 - module.getModifiedItemAttr("{}Strength{}".format(prefix, fit.scanType))/fit.scanStrength fit.ecmProjectedStr *= strModifier diff --git a/eos/effects/fighterabilityenergyneutralizer.py b/eos/effects/fighterabilityenergyneutralizer.py index 2601bc535c..ca0460e158 100644 --- a/eos/effects/fighterabilityenergyneutralizer.py +++ b/eos/effects/fighterabilityenergyneutralizer.py @@ -12,8 +12,7 @@ type = "active", "projected" def handler(fit, container, context): - if "projected" in context and ((hasattr(container, "state") and container.state >= State.ACTIVE) or hasattr(container, "amountActive")): - multiplier = container.amountActive if hasattr(container, "amountActive") else 1 + if "projected" in context: amount = container.getModifiedItemAttr("{}Amount".format(prefix)) time = container.getModifiedItemAttr("{}Duration".format(prefix)) - fit.addDrain(time, amount * multiplier, 0) \ No newline at end of file + fit.addDrain(time, amount, 0) \ No newline at end of file diff --git a/eos/effects/fighterabilitystasiswebifier.py b/eos/effects/fighterabilitystasiswebifier.py index 90da7a4eb3..2a3aa03932 100644 --- a/eos/effects/fighterabilitystasiswebifier.py +++ b/eos/effects/fighterabilitystasiswebifier.py @@ -13,5 +13,4 @@ def handler(fit, src, context): if "projected" not in context: return - multiplier = src.amountActive if hasattr(src, "amountActive") else 1 - fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("{}SpeedPenalty") * multiplier) + fit.ship.boostItemAttr("maxVelocity", src.getModifiedItemAttr("{}SpeedPenalty".format(prefix))) diff --git a/eos/saveddata/fighter.py b/eos/saveddata/fighter.py index 0791d33974..3532731068 100644 --- a/eos/saveddata/fighter.py +++ b/eos/saveddata/fighter.py @@ -239,6 +239,9 @@ def canBeApplied(self, projectedOnto): return True def calculateModifiedAttributes(self, fit, runTime, forceProjected = False): + if not self.active: + return + if self.projected or forceProjected: context = "projected", "fighter" projected = True diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 63e04e7470..3ab32c7d46 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -68,6 +68,7 @@ def __init__(self, ship=None, name=""): #self.__projectedFits = {} self.__projectedModules = HandledProjectedModList() self.__projectedDrones = HandledProjectedDroneList() + self.__projectedFighters = HandledProjectedDroneList() self.__character = None self.__owner = None @@ -231,6 +232,10 @@ def getProjectionInfo(self, fitID): def projectedDrones(self): return self.__projectedDrones + @property + def projectedFighters(self): + return self.__projectedFighters + @property def weaponDPS(self): if self.__weaponDPS is None: @@ -386,6 +391,7 @@ def clear(self, projected=False): self.implants, self.projectedDrones, self.projectedModules, + self.projectedFighters, (self.character, self.extraAttributes), ) @@ -508,7 +514,7 @@ def calculateModifiedAttributes(self, targetFit=None, withBoosters=False, dirtyS # Items that are restricted. These items are only run on the local # fit. They are NOT projected onto the target fit. # See issue 354 - r = [(self.mode,), self.projectedDrones, self.projectedModules] + r = [(self.mode,), self.projectedDrones, self.projectedFighters, self.projectedModules] # chain unrestricted and restricted into one iterable c = chain.from_iterable(u+r) @@ -1049,7 +1055,7 @@ def __deepcopy__(self, memo): copy.damagePattern = self.damagePattern copy.targetResists = self.targetResists - toCopy = ("modules", "drones", "fighters", "cargo", "implants", "boosters", "projectedModules", "projectedDrones") + toCopy = ("modules", "drones", "fighters", "cargo", "implants", "boosters", "projectedModules", "projectedDrones", "projectedFighters") for name in toCopy: orig = getattr(self, name) c = getattr(copy, name) diff --git a/eos/types.py b/eos/types.py index 05c37767b5..fc25741b2d 100644 --- a/eos/types.py +++ b/eos/types.py @@ -29,7 +29,6 @@ from eos.saveddata.drone import Drone from eos.saveddata.fighterAbility import FighterAbility from eos.saveddata.fighter import Fighter - from eos.saveddata.cargo import Cargo from eos.saveddata.implant import Implant from eos.saveddata.implantSet import ImplantSet diff --git a/gui/builtinContextMenus/amount.py b/gui/builtinContextMenus/amount.py index ab7c82ca20..99acdf2478 100644 --- a/gui/builtinContextMenus/amount.py +++ b/gui/builtinContextMenus/amount.py @@ -11,7 +11,7 @@ def __init__(self): self.mainFrame = gui.mainFrame.MainFrame.getInstance() def display(self, srcContext, selection): - return srcContext in ("cargoItem","projectedFit","fighterItem") + return srcContext in ("cargoItem","projectedFit","fighterItem","projectedFighter") def getText(self, itmContext, selection): return "Change {0} Quantity".format(itmContext) diff --git a/gui/builtinContextMenus/fighterAbilities.py b/gui/builtinContextMenus/fighterAbilities.py index da62c3af93..9107036593 100644 --- a/gui/builtinContextMenus/fighterAbilities.py +++ b/gui/builtinContextMenus/fighterAbilities.py @@ -9,7 +9,7 @@ def __init__(self): self.mainFrame = gui.mainFrame.MainFrame.getInstance() def display(self, srcContext, selection): - if self.mainFrame.getActiveFit() is None or srcContext != "fighterItem": + if self.mainFrame.getActiveFit() is None or srcContext not in ("fighterItem", "projectedFighter"): return False self.fighter = selection[0] diff --git a/gui/builtinContextMenus/itemRemove.py b/gui/builtinContextMenus/itemRemove.py index fbb3850720..c355d98b55 100644 --- a/gui/builtinContextMenus/itemRemove.py +++ b/gui/builtinContextMenus/itemRemove.py @@ -13,7 +13,8 @@ def display(self, srcContext, selection): "droneItem", "implantItem", "boosterItem", "projectedModule", "projectedCharge", "cargoItem", - "projectedFit", "projectedDrone") + "projectedFit", "projectedDrone", + "fighterItem", "projectedFighter") def getText(self, itmContext, selection): return "Remove {0}".format(itmContext if itmContext is not None else "Item") @@ -32,6 +33,8 @@ def activate(self, fullContext, selection, i): sFit.setAmmo(fitID, None, selection) elif srcContext == "droneItem": sFit.removeDrone(fitID, fit.drones.index(selection[0])) + elif srcContext == "fighterItem": + sFit.removeFighter(fitID, fit.fighters.index(selection[0])) elif srcContext == "implantItem": sFit.removeImplant(fitID, fit.implants.index(selection[0])) elif srcContext == "boosterItem": diff --git a/gui/builtinContextMenus/itemStats.py b/gui/builtinContextMenus/itemStats.py index 7669b1f2f0..d8d7e04ac1 100644 --- a/gui/builtinContextMenus/itemStats.py +++ b/gui/builtinContextMenus/itemStats.py @@ -17,7 +17,8 @@ def display(self, srcContext, selection): "implantItem", "boosterItem", "skillItem", "projectedModule", "projectedDrone", "projectedCharge", - "itemStats", "fighterItem", "implantItemChar") + "itemStats", "fighterItem", + "implantItemChar", "projectedFighter") def getText(self, itmContext, selection): return "{0} Stats".format(itmContext if itmContext is not None else "Item") diff --git a/gui/builtinContextMenus/marketJump.py b/gui/builtinContextMenus/marketJump.py index 180935cbf6..75884576de 100644 --- a/gui/builtinContextMenus/marketJump.py +++ b/gui/builtinContextMenus/marketJump.py @@ -13,7 +13,8 @@ def display(self, srcContext, selection): "implantItem", "boosterItem", "projectedModule", "projectedDrone", "projectedCharge", "cargoItem", - "implantItemChar", "fighterItem") + "implantItemChar", "fighterItem", + "projectedDrone") if not srcContext in validContexts or selection is None or len(selection) < 1: return False diff --git a/gui/builtinViewColumns/abilities.py b/gui/builtinViewColumns/abilities.py index 12081500a4..f615574466 100644 --- a/gui/builtinViewColumns/abilities.py +++ b/gui/builtinViewColumns/abilities.py @@ -22,8 +22,8 @@ import gui.mainFrame import wx -from eos.types import Drone, Cargo, Fit, Module, Slot, Rack, Implant, Fighter -import service +from eos.types import Fighter + class Abilities(ViewColumn): name = "Fighter Abilities" @@ -36,6 +36,9 @@ def __init__(self, fittingView, params): def getText(self, stuff): if isinstance(stuff, Fighter): - return ", ".join([x.name for x in stuff.abilities if x.active]) + active = [x.name for x in stuff.abilities if x.active] + if len(active) == 0: + return "None" + return ", ".join(active) Abilities.register() diff --git a/gui/builtinViewColumns/ammo.py b/gui/builtinViewColumns/ammo.py index ba22229aff..698e8595b9 100644 --- a/gui/builtinViewColumns/ammo.py +++ b/gui/builtinViewColumns/ammo.py @@ -21,6 +21,8 @@ from gui.viewColumn import ViewColumn from gui.bitmapLoader import BitmapLoader import wx +from eos.types import Fighter + class Ammo(ViewColumn): name = "Ammo" @@ -31,6 +33,12 @@ def __init__(self, fittingView, params): self.bitmap = BitmapLoader.getBitmap("damagePattern_small", "gui") def getText(self, stuff): + if isinstance(stuff, Fighter): + # this is an experiment, not sure I like it. But it saves us from duplicating code. + col = self.columns['Fighter Abilities'](self.fittingView, {}) + text = col.getText(stuff) + del col + return text if getattr(stuff, "charge", None) is not None: charges = stuff.numCharges if charges > 0: @@ -47,3 +55,4 @@ def getImageId(self, mod): return -1 Ammo.register() + diff --git a/gui/implantView.py b/gui/implantView.py index 4b47552527..8ae9ac50a8 100644 --- a/gui/implantView.py +++ b/gui/implantView.py @@ -65,6 +65,9 @@ def fitChanged(self, event): else: self.rbChar.SetValue(True) + self.rbFit.Enable(fit is not None) + self.rbChar.Enable(fit is not None) + def OnRadioSelect(self, event): fitID = self.mainFrame.getActiveFit() sFit = service.Fit.getInstance() diff --git a/gui/projectedView.py b/gui/projectedView.py index 0043ac639e..3600620fd2 100644 --- a/gui/projectedView.py +++ b/gui/projectedView.py @@ -144,6 +144,9 @@ def _merge(self, src, dst): def moduleSort(self, module): return module.item.name + def fighterSort(self, fighter): + return fighter.item.name + def droneSort(self, drone): item = drone.item if item.marketGroup is None: @@ -169,14 +172,17 @@ def fitChanged(self, event): if fit is not None: self.modules = fit.projectedModules[:] self.drones = fit.projectedDrones[:] + self.fighters = fit.projectedFighters[:] self.fits = fit.projectedFits[:] self.modules.sort(key=self.moduleSort) self.drones.sort(key=self.droneSort) + self.fighters.sort(key=self.fighterSort) self.fits.sort(key=self.fitSort) stuff.extend(self.modules) stuff.extend(self.drones) + stuff.extend(self.fighters) stuff.extend(self.fits) if event.fitID != self.lastFitId: @@ -197,17 +203,20 @@ def fitChanged(self, event): def get(self, row): numMods = len(self.modules) numDrones = len(self.drones) + numFighters = len(self.fighters) numFits = len(self.fits) - if (numMods + numDrones + numFits) == 0: + if (numMods + numDrones + numFighters + numFits) == 0: return None if row < numMods: stuff = self.modules[row] elif row - numMods < numDrones: stuff = self.drones[row - numMods] + elif row - numMods - numDrones < numFighters: + stuff = self.fighters[row - numMods - numDrones] else: - stuff = self.fits[row - numMods - numDrones] + stuff = self.fits[row - numMods - numDrones - numFighters] return stuff @@ -238,6 +247,10 @@ def spawnMenu(self): srcContext = "projectedDrone" itemContext = sMkt.getCategoryByItem(item.item).name context = ((srcContext, itemContext),) + elif isinstance(item, eos.types.Fighter): + srcContext = "projectedFighter" + itemContext = sMkt.getCategoryByItem(item.item).name + context = ((srcContext, itemContext),) elif isinstance(item, eos.types.Module): modSrcContext = "projectedModule" modItemContext = sMkt.getCategoryByItem(item.item).name diff --git a/service/fit.py b/service/fit.py index 84c42d7236..3ae8c51fa9 100644 --- a/service/fit.py +++ b/service/fit.py @@ -329,6 +329,9 @@ def removeBooster(self, fitID, position): return True def project(self, fitID, thing): + if fitID is None: + return + fit = eos.db.getFit(fitID) if isinstance(thing, int): @@ -356,6 +359,10 @@ def project(self, fitID, thing): fit.projectedDrones.append(drone) drone.amount += 1 + elif thing.category.name == "Fighter": + print "dskfnds" + fighter = eos.types.Fighter(thing) + fit.projectedFighters.append(fighter) elif thing.group.name == "Effect Beacon": module = eos.types.Module(thing) module.state = State.ONLINE @@ -378,6 +385,8 @@ def toggleProjected(self, fitID, thing, click): thing.amountActive = thing.amount else: thing.amountActive = 0 + elif isinstance(thing, eos.types.Fighter): + thing.active = not thing.active elif isinstance(thing, eos.types.Module): thing.state = self.__getProposedState(thing, click) if not thing.canHaveState(thing.state, fit): @@ -414,6 +423,8 @@ def removeProjected(self, fitID, thing): fit.projectedDrones.remove(thing) elif isinstance(thing, eos.types.Module): fit.projectedModules.remove(thing) + elif isinstance(thing, eos.types.Fighter): + fit.projectedFighters.remove(thing) else: del fit.__projectedFits[thing.ID] #fit.projectedFits.remove(thing)