More fighter work. Basic abilities now work correctly.
This commit is contained in:
@@ -32,7 +32,6 @@ fighters_table = Table("fighters", saveddata_meta,
|
||||
Column("fitID", Integer, ForeignKey("fits.ID"), nullable = False, index = True),
|
||||
Column("itemID", Integer, nullable = False),
|
||||
Column("amount", Integer, nullable = False),
|
||||
Column("amountActive", Integer, nullable = False),
|
||||
Column("projected", Boolean, default = False))
|
||||
|
||||
fighter_abilities_table = Table("fightersAbilities", saveddata_meta,
|
||||
|
||||
14
eos/effects/fighterabilityattackm.py
Normal file
14
eos/effects/fighterabilityattackm.py
Normal file
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
|
||||
effects, and thus this effect file contains some custom information useful only to fighters.
|
||||
"""
|
||||
# User-friendly name for the ability
|
||||
displayName = "Turret Attack"
|
||||
|
||||
# Attribute prefix that this ability targets
|
||||
prefix = "fighterAbilityAttackMissile"
|
||||
|
||||
type = "active"
|
||||
|
||||
def handler(fit, src, context):
|
||||
pass
|
||||
16
eos/effects/fighterabilitymicrowarpdrive.py
Normal file
16
eos/effects/fighterabilitymicrowarpdrive.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
|
||||
effects, and thus this effect file contains some custom information useful only to fighters.
|
||||
"""
|
||||
# User-friendly name for the ability
|
||||
displayName = "Microwarpdrive"
|
||||
|
||||
# Is ability applied to the fighter squad as a whole, or per fighter?
|
||||
grouped = True
|
||||
|
||||
type = "active"
|
||||
runTime = "late"
|
||||
def handler(fit, module, context):
|
||||
print module.getModifiedItemAttr("fighterAbilityMicroWarpDriveSpeedBonus")
|
||||
module.boostItemAttr("maxVelocity", module.getModifiedItemAttr("fighterAbilityMicroWarpDriveSpeedBonus"))
|
||||
module.boostItemAttr("signatureRadius", module.getModifiedItemAttr("fighterAbilityMicroWarpDriveSignatureRadiusBonus"), stackingPenalties = True)
|
||||
14
eos/effects/fighterabilitymissiles.py
Normal file
14
eos/effects/fighterabilitymissiles.py
Normal file
@@ -0,0 +1,14 @@
|
||||
"""
|
||||
Since fighter abilities do not have any sort of item entity in the EVE database, we must derive the abilities from the
|
||||
effects, and thus this effect file contains some custom information useful only to fighters.
|
||||
"""
|
||||
# User-friendly name for the ability
|
||||
displayName = "Missile Attack"
|
||||
|
||||
# Attribute prefix that this ability targets
|
||||
prefix = "fighterAbilityMissiles"
|
||||
|
||||
type = "active"
|
||||
|
||||
def handler(fit, src, context):
|
||||
pass
|
||||
@@ -28,7 +28,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
DAMAGE_TYPES = ("em", "kinetic", "explosive", "thermal")
|
||||
MINING_ATTRIBUTES = ("miningAmount",)
|
||||
DAMAGE_TYPES2 = ("EM", "Kin", "Exp", "Therm")
|
||||
|
||||
def __init__(self, item):
|
||||
"""Initialize a fighter from the program"""
|
||||
@@ -38,10 +38,12 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
raise ValueError("Passed item is not a Fighter")
|
||||
|
||||
self.itemID = item.ID if item is not None else None
|
||||
self.amount = 0
|
||||
self.amountActive = 0
|
||||
self.projected = False
|
||||
|
||||
# -1 is a placeholder that represents max squadron size, which we may not know yet as ships may modify this with
|
||||
# their effects. If user changes this, it is then overridden with user value.
|
||||
self.amount = -1
|
||||
|
||||
self.__abilities = self.__getAbilities()
|
||||
|
||||
self.build()
|
||||
@@ -92,11 +94,18 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
print "getting list of abilities"
|
||||
return [FighterAbility(effect) for effect in self.item.effects.values()]
|
||||
|
||||
@property
|
||||
def amountActive(self):
|
||||
return self.getModifiedItemAttr("fighterSquadronMaxSize") if self.amount == -1 else self.amount
|
||||
|
||||
@amountActive.setter
|
||||
def amountActive(self, i):
|
||||
self.amount = max(i, self.getModifiedItemAttr("fighterSquadronMaxSize"))
|
||||
|
||||
@property
|
||||
def abilities(self):
|
||||
return self.__abilities or []
|
||||
|
||||
|
||||
@property
|
||||
def itemModifiedAttributes(self):
|
||||
return self.__itemModifiedAttributes
|
||||
@@ -117,17 +126,6 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
def charge(self):
|
||||
return self.__charge
|
||||
|
||||
@property
|
||||
def dealsDamage(self):
|
||||
for attr in ("emDamage", "kineticDamage", "explosiveDamage", "thermalDamage"):
|
||||
if attr in self.itemModifiedAttributes or attr in self.chargeModifiedAttributes:
|
||||
return True
|
||||
|
||||
@property
|
||||
def mines(self):
|
||||
if "miningAmount" in self.itemModifiedAttributes:
|
||||
return True
|
||||
|
||||
@property
|
||||
def hasAmmo(self):
|
||||
return self.charge is not None
|
||||
@@ -137,42 +135,26 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return self.damageStats()
|
||||
|
||||
def damageStats(self, targetResists = None):
|
||||
if self.__dps == None:
|
||||
if self.__dps is None:
|
||||
self.__volley = 0
|
||||
self.__dps = 0
|
||||
if self.dealsDamage is True and self.amountActive > 0:
|
||||
if self.hasAmmo:
|
||||
attr = "missileLaunchDuration"
|
||||
getter = self.getModifiedChargeAttr
|
||||
else:
|
||||
attr = "speed"
|
||||
getter = self.getModifiedItemAttr
|
||||
for ability in self.abilities:
|
||||
if ability.dealsDamage and ability.active and self.amountActive > 0:
|
||||
cycleTime = self.getModifiedItemAttr("{}Duration".format(ability.attrPrefix))
|
||||
|
||||
cycleTime = self.getModifiedItemAttr(attr)
|
||||
volley = sum(map(lambda d2, d:
|
||||
(self.getModifiedItemAttr("{}Damage{}".format(ability.attrPrefix, d2)) or 0) *
|
||||
(1-getattr(targetResists, "{}Amount".format(d), 0)),
|
||||
self.DAMAGE_TYPES2, self.DAMAGE_TYPES))
|
||||
|
||||
volley = sum(map(lambda d: (getter("%sDamage"%d) or 0) * (1-getattr(targetResists, "%sAmount"%d, 0)), self.DAMAGE_TYPES))
|
||||
volley *= self.amountActive
|
||||
volley *= self.getModifiedItemAttr("damageMultiplier") or 1
|
||||
self.__volley = volley
|
||||
self.__dps = volley / (cycleTime / 1000.0)
|
||||
volley *= self.amountActive
|
||||
print self.getModifiedItemAttr("{}DamageMultiplier".format(ability.attrPrefix))
|
||||
volley *= self.getModifiedItemAttr("{}DamageMultiplier".format(ability.attrPrefix)) or 1
|
||||
self.__volley += volley
|
||||
self.__dps += volley / (cycleTime / 1000.0)
|
||||
|
||||
return self.__dps, self.__volley
|
||||
|
||||
@property
|
||||
def miningStats(self):
|
||||
if self.__miningyield == None:
|
||||
if self.mines is True and self.amountActive > 0:
|
||||
attr = "duration"
|
||||
getter = self.getModifiedItemAttr
|
||||
|
||||
cycleTime = self.getModifiedItemAttr(attr)
|
||||
volley = sum(map(lambda d: getter(d), self.MINING_ATTRIBUTES)) * self.amountActive
|
||||
self.__miningyield = volley / (cycleTime / 1000.0)
|
||||
else:
|
||||
self.__miningyield = 0
|
||||
|
||||
return self.__miningyield
|
||||
|
||||
@property
|
||||
def maxRange(self):
|
||||
attrs = ("shieldTransferRange", "powerTransferRange",
|
||||
@@ -202,8 +184,8 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
map = {"ID": lambda val: isinstance(val, int),
|
||||
"itemID" : lambda val: isinstance(val, int),
|
||||
"chargeID" : lambda val: isinstance(val, int),
|
||||
"amount" : lambda val: isinstance(val, int) and val >= 0,
|
||||
"amountActive" : lambda val: isinstance(val, int) and val <= self.amount and val >= 0}
|
||||
"amount" : lambda val: isinstance(val, int) and val >= -1,
|
||||
}
|
||||
|
||||
if map[key](val) == False: raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else: return val
|
||||
@@ -238,24 +220,22 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
context = ("fighter",)
|
||||
projected = False
|
||||
|
||||
for effect in self.item.effects.itervalues():
|
||||
if effect.runTime == runTime and \
|
||||
((projected == True and effect.isType("projected")) or \
|
||||
projected == False and effect.isType("passive")):
|
||||
i = 0
|
||||
while i != self.amountActive:
|
||||
effect.handler(fit, self, context)
|
||||
i += 1
|
||||
|
||||
if self.charge:
|
||||
for effect in self.charge.effects.itervalues():
|
||||
if effect.runTime == runTime:
|
||||
effect.handler(fit, self, ("fighterCharge",))
|
||||
for ability in self.abilities:
|
||||
if ability.active:
|
||||
effect = ability.effect
|
||||
if effect.runTime == runTime and \
|
||||
((projected and effect.isType("projected")) or not projected):
|
||||
if ability.grouped:
|
||||
effect.handler(fit, self, context)
|
||||
else:
|
||||
i = 0
|
||||
while i != self.amountActive:
|
||||
effect.handler(fit, self, context)
|
||||
i += 1
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Fighter(self.item)
|
||||
copy.amount = self.amount
|
||||
copy.amountActive = self.amountActive
|
||||
return copy
|
||||
|
||||
def fits(self, fit):
|
||||
|
||||
@@ -53,4 +53,18 @@ class FighterAbility(object):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.__effect.handlerName
|
||||
return self.__effect.getattr('displayName') or self.__effect.handlerName
|
||||
|
||||
@property
|
||||
def attrPrefix(self):
|
||||
return self.__effect.getattr('prefix')
|
||||
|
||||
@property
|
||||
def dealsDamage(self):
|
||||
attr = "{}DamageMultiplier".format(self.attrPrefix)
|
||||
return attr in self.fighter.itemModifiedAttributes
|
||||
|
||||
@property
|
||||
def grouped(self):
|
||||
# is the ability applied per fighter (webs, returns False), or as a group (MWD, returned True)
|
||||
return self.__effect.getattr('grouped')
|
||||
@@ -22,7 +22,7 @@ from gui.viewColumn import ViewColumn
|
||||
import gui.mainFrame
|
||||
|
||||
import wx
|
||||
from eos.types import Drone, Cargo, Fit, Module, Slot, Rack, Implant
|
||||
from eos.types import Drone, Cargo, Fit, Module, Slot, Rack, Implant, Fighter
|
||||
import service
|
||||
|
||||
class BaseName(ViewColumn):
|
||||
@@ -39,6 +39,8 @@ class BaseName(ViewColumn):
|
||||
def getText(self, stuff):
|
||||
if isinstance(stuff, Drone):
|
||||
return "%dx %s" % (stuff.amount, stuff.item.name)
|
||||
if isinstance(stuff, Fighter):
|
||||
return "%d/%d %s (dps: %.2f, volley: %.2f)" % (stuff.amountActive, stuff.getModifiedItemAttr("fighterSquadronMaxSize"), stuff.item.name, stuff.damageStats()[0], stuff.damageStats()[1])
|
||||
elif isinstance(stuff, Cargo):
|
||||
return "%dx %s" % (stuff.amount, stuff.item.name)
|
||||
elif isinstance(stuff, Fit):
|
||||
|
||||
@@ -636,7 +636,7 @@ class Fit(object):
|
||||
fit.fighters.append(fighter)
|
||||
else:
|
||||
return False
|
||||
fighter.amount += 1
|
||||
|
||||
eos.db.commit()
|
||||
self.recalc(fit)
|
||||
return True
|
||||
@@ -646,10 +646,7 @@ class Fit(object):
|
||||
def removeFighter(self, fitID, i):
|
||||
fit = eos.db.getFit(fitID)
|
||||
f = fit.fighters[i]
|
||||
f.amount -= 1
|
||||
|
||||
if f.amount == 0:
|
||||
del fit.fighters[i]
|
||||
fit.fighters.remove(f)
|
||||
|
||||
eos.db.commit()
|
||||
self.recalc(fit)
|
||||
|
||||
Reference in New Issue
Block a user