More fighter work. Basic abilities now work correctly.

This commit is contained in:
blitzmann
2016-04-17 13:28:12 -04:00
parent 708425c67a
commit af9a9c5698
8 changed files with 104 additions and 68 deletions

View File

@@ -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,

View 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

View 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)

View 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

View File

@@ -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):

View File

@@ -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')

View File

@@ -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):

View File

@@ -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)