231 lines
8.7 KiB
Python
231 lines
8.7 KiB
Python
# coding: utf-8
|
||
|
||
import wx
|
||
|
||
from service.fit import Fit
|
||
from service.market import Market
|
||
from eos.types import Hardpoint
|
||
import gui.mainFrame
|
||
import gui.globalEvents as GE
|
||
from gui.contextMenu import ContextMenu
|
||
from gui.bitmapLoader import BitmapLoader
|
||
|
||
|
||
class ModuleAmmoPicker(ContextMenu):
|
||
DAMAGE_TYPES = ("em", "explosive", "kinetic", "thermal")
|
||
MISSILE_ORDER = ("em", "thermal", "kinetic", "explosive", "mixed")
|
||
|
||
def __init__(self):
|
||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||
|
||
def display(self, srcContext, selection):
|
||
if self.mainFrame.getActiveFit() is None or srcContext not in ("fittingModule", "projectedModule"):
|
||
return False
|
||
|
||
modules = selection if srcContext == "fittingModule" else (selection[0],)
|
||
|
||
validCharges = None
|
||
checkedTypes = set()
|
||
|
||
for mod in modules:
|
||
# loop through modules and gather list of valid charges
|
||
if mod.item.ID in checkedTypes:
|
||
continue
|
||
checkedTypes.add(mod.item.ID)
|
||
currCharges = mod.getValidCharges()
|
||
if len(currCharges) > 0:
|
||
if validCharges is not None and validCharges != currCharges:
|
||
return False
|
||
|
||
validCharges = currCharges
|
||
self.module = mod
|
||
|
||
if validCharges is None:
|
||
return False
|
||
|
||
self.modules = modules
|
||
self.charges = list(filter(lambda charge: Market.getInstance().getPublicityByItem(charge), validCharges))
|
||
return len(self.charges) > 0
|
||
|
||
def getText(self, itmContext, selection):
|
||
return "Charge"
|
||
|
||
def turretSorter(self, charge):
|
||
damage = 0
|
||
range_ = (self.module.getModifiedItemAttr("maxRange") or 0) * \
|
||
(charge.getAttribute("weaponRangeMultiplier") or 1)
|
||
falloff = (self.module.getModifiedItemAttr("falloff") or 0) * \
|
||
(charge.getAttribute("fallofMultiplier") or 1)
|
||
for type_ in self.DAMAGE_TYPES:
|
||
d = charge.getAttribute("%sDamage" % type_)
|
||
if d > 0:
|
||
damage += d
|
||
|
||
# Take optimal and half falloff as range factor
|
||
rangeFactor = range_ + falloff / 2
|
||
|
||
return - rangeFactor, charge.name.rsplit()[-2:], damage, charge.name
|
||
|
||
def missileSorter(self, charge):
|
||
# Get charge damage type and total damage
|
||
chargeDamageType, totalDamage = self.damageInfo(charge)
|
||
# Find its position in sort list
|
||
position = self.MISSILE_ORDER.index(chargeDamageType)
|
||
return position, totalDamage, charge.name
|
||
|
||
def damageInfo(self, charge):
|
||
# Set up data storage for missile damage stuff
|
||
damageMap = {}
|
||
totalDamage = 0
|
||
# Fill them with the data about charge
|
||
for damageType in self.DAMAGE_TYPES:
|
||
currentDamage = charge.getAttribute("{0}Damage".format(damageType)) or 0
|
||
damageMap[damageType] = currentDamage
|
||
totalDamage += currentDamage
|
||
# Detect type of ammo
|
||
chargeDamageType = None
|
||
for damageType in damageMap:
|
||
# If all damage belongs to certain type purely, set appropriate
|
||
# ammoType
|
||
if damageMap[damageType] == totalDamage:
|
||
chargeDamageType = damageType
|
||
break
|
||
# Else consider ammo as mixed damage
|
||
if chargeDamageType is None:
|
||
chargeDamageType = "mixed"
|
||
|
||
return chargeDamageType, totalDamage
|
||
|
||
def numericConverter(self, string):
|
||
return int(string) if string.isdigit() else string
|
||
|
||
def nameSorter(self, charge):
|
||
parts = charge.name.split(" ")
|
||
return map(self.numericConverter, parts)
|
||
|
||
def addCharge(self, menu, charge):
|
||
id_ = ContextMenu.nextID()
|
||
name = charge.name if charge is not None else "Empty"
|
||
self.chargeIds[id_] = charge
|
||
item = wx.MenuItem(menu, id_, name)
|
||
menu.Bind(wx.EVT_MENU, self.handleAmmoSwitch, item)
|
||
item.charge = charge
|
||
if charge is not None and charge.icon is not None:
|
||
bitmap = BitmapLoader.getBitmap(charge.icon.iconFile, "icons")
|
||
if bitmap is not None:
|
||
item.SetBitmap(bitmap)
|
||
|
||
return item
|
||
|
||
def addSeperator(self, m, text):
|
||
id_ = ContextMenu.nextID()
|
||
m.Append(id_, u' |