Implemented projected fighters, and various fighter bugfixes / improvements
This commit is contained in:
@@ -137,6 +137,12 @@ mapper(Fit, fits_table,
|
||||
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,
|
||||
|
||||
@@ -13,6 +13,6 @@ type = "projected", "active"
|
||||
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
|
||||
|
||||
@@ -12,8 +12,7 @@ prefix = "fighterAbilityEnergyNeutralizer"
|
||||
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)
|
||||
fit.addDrain(time, amount, 0)
|
||||
@@ -13,5 +13,4 @@ type = "active", "projected"
|
||||
|
||||
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)))
|
||||
|
||||
@@ -239,6 +239,9 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return True
|
||||
|
||||
def calculateModifiedAttributes(self, fit, runTime, forceProjected = False):
|
||||
if not self.active:
|
||||
return
|
||||
|
||||
if self.projected or forceProjected:
|
||||
context = "projected", "fighter"
|
||||
projected = True
|
||||
|
||||
@@ -68,6 +68,7 @@ class Fit(object):
|
||||
#self.__projectedFits = {}
|
||||
self.__projectedModules = HandledProjectedModList()
|
||||
self.__projectedDrones = HandledProjectedDroneList()
|
||||
self.__projectedFighters = HandledProjectedDroneList()
|
||||
self.__character = None
|
||||
self.__owner = None
|
||||
|
||||
@@ -231,6 +232,10 @@ class Fit(object):
|
||||
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 @@ class Fit(object):
|
||||
self.implants,
|
||||
self.projectedDrones,
|
||||
self.projectedModules,
|
||||
self.projectedFighters,
|
||||
(self.character, self.extraAttributes),
|
||||
)
|
||||
|
||||
@@ -508,7 +514,7 @@ class Fit(object):
|
||||
|
||||
# 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 @@ class Fit(object):
|
||||
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)
|
||||
|
||||
@@ -29,7 +29,6 @@ from eos.saveddata.module import Module, State, Slot, Hardpoint, Rack
|
||||
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
|
||||
|
||||
@@ -11,7 +11,7 @@ class ChangeAmount(ContextMenu):
|
||||
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)
|
||||
|
||||
@@ -9,7 +9,7 @@ class FighterAbility(ContextMenu):
|
||||
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]
|
||||
|
||||
@@ -13,7 +13,8 @@ class ItemRemove(ContextMenu):
|
||||
"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 @@ class ItemRemove(ContextMenu):
|
||||
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":
|
||||
|
||||
@@ -17,7 +17,8 @@ class ItemStats(ContextMenu):
|
||||
"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")
|
||||
|
||||
@@ -13,7 +13,8 @@ class MarketJump(ContextMenu):
|
||||
"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
|
||||
|
||||
@@ -22,8 +22,8 @@ from gui.viewColumn import ViewColumn
|
||||
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 @@ class Abilities(ViewColumn):
|
||||
|
||||
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()
|
||||
|
||||
@@ -21,6 +21,8 @@ from gui import builtinViewColumns
|
||||
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 @@ class Ammo(ViewColumn):
|
||||
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 @@ class Ammo(ViewColumn):
|
||||
return -1
|
||||
|
||||
Ammo.register()
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@ class ImplantView(wx.Panel):
|
||||
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()
|
||||
|
||||
@@ -144,6 +144,9 @@ class ProjectedView(d.Display):
|
||||
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 @@ class ProjectedView(d.Display):
|
||||
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 @@ class ProjectedView(d.Display):
|
||||
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 @@ class ProjectedView(d.Display):
|
||||
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
|
||||
|
||||
@@ -329,6 +329,9 @@ class Fit(object):
|
||||
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 @@ class Fit(object):
|
||||
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 @@ class Fit(object):
|
||||
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 @@ class Fit(object):
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user