Re-work the wormhole (now call Environmental) context menu

This commit is contained in:
blitzmann
2018-05-23 00:38:30 -04:00
parent 1c359fb6ed
commit e95cbdd19b
2 changed files with 172 additions and 83 deletions

View File

@@ -6,9 +6,23 @@ import wx
from service.market import Market from service.market import Market
from service.fit import Fit from service.fit import Fit
from service.settings import ContextMenuSettings from service.settings import ContextMenuSettings
from itertools import chain
import re
class WhProjector(ContextMenu): class WhProjector(ContextMenu):
# CCP doesn't currently provide a mapping between the general Environment, and the specific environment effect
# (which can be random when going into Abyssal space). This is how we currently define it:
# environment type: specific type name previx
abyssal_mapping = {
'caustic_toxin_weather': 47862, # Exotic Particle Storm
'darkness_weather': 47863, # Dark Matter Field
'infernal_weather': 47864, # Plasma Firestorm
'electric_storm_weather': 47865, # Electrical Storm
'xenon_gas_weather': 47866, # Gamma-Ray Afterglow
}
def __init__(self): def __init__(self):
self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.mainFrame = gui.mainFrame.MainFrame.getInstance()
self.settings = ContextMenuSettings.getInstance() self.settings = ContextMenuSettings.getInstance()
@@ -20,32 +34,50 @@ class WhProjector(ContextMenu):
return srcContext == "projected" return srcContext == "projected"
def getText(self, itmContext, selection): def getText(self, itmContext, selection):
return "Add System Effects" return "Add Environment Effects"
def getSubMenu(self, context, selection, rootMenu, i, pitem): def getSubMenu(self, context, selection, rootMenu, i, pitem):
msw = True if "wxMSW" in wx.PlatformInfo else False msw = True if "wxMSW" in wx.PlatformInfo else False
sMkt = Market.getInstance() sMkt = Market.getInstance()
effdata = sMkt.getSystemWideEffects()
# Wormholes
self.idmap = {} self.idmap = {}
sub = wx.Menu() sub = wx.Menu()
for swType in sorted(effdata): wormhole_item = wx.MenuItem(sub, wx.ID_ANY, "Wormhole")
subItem = wx.MenuItem(sub, wx.ID_ANY, swType) wormhole_menu = wx.Menu()
grandSub = wx.Menu() wormhole_item.SetSubMenu(wormhole_menu)
subItem.SetSubMenu(grandSub) sub.Append(wormhole_item)
sub.Append(subItem)
effdata = self.getEffectBeacons()
self.buildMenu(effdata, wormhole_menu, rootMenu, msw)
# Incursions
effdata = self.getEffectBeacons(incursions=True)
self.buildMenu(effdata, sub, rootMenu, msw)
# Abyssal Weather
abyssal_item = wx.MenuItem(sub, wx.ID_ANY, "Abyssal Weather")
abyssal_menu = wx.Menu()
abyssal_item.SetSubMenu(abyssal_menu)
sub.Append(abyssal_item)
effdata = self.getAbyssalWeather()
self.buildMenu(effdata, abyssal_menu, rootMenu, msw)
# Localized Weather
local_item = wx.MenuItem(sub, wx.ID_ANY, "Localized")
local_menu = wx.Menu()
local_item.SetSubMenu(local_menu)
sub.Append(local_item)
effdata = self.getLocalizedEnvironments()
self.buildMenu(effdata, local_menu, rootMenu, msw)
for swData in sorted(effdata[swType], key=lambda tpl: tpl[2]):
wxid = ContextMenu.nextID()
swObj, swName, swClass = swData
self.idmap[wxid] = (swObj, swName)
grandSubItem = wx.MenuItem(grandSub, wxid, swClass)
if msw:
rootMenu.Bind(wx.EVT_MENU, self.handleSelection, grandSubItem)
else:
grandSub.Bind(wx.EVT_MENU, self.handleSelection, grandSubItem)
grandSub.Append(grandSubItem)
return sub return sub
def handleSelection(self, event): def handleSelection(self, event):
@@ -61,5 +93,127 @@ class WhProjector(ContextMenu):
sFit.project(fitID, swObj) sFit.project(fitID, swObj)
wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID))
def buildMenu(self, data, local_menu, rootMenu, msw):
for swType in sorted(data):
subItem = wx.MenuItem(local_menu, wx.ID_ANY, swType)
grandSub = wx.Menu()
subItem.SetSubMenu(grandSub)
local_menu.Append(subItem)
for swData in sorted(data[swType], key=lambda tpl: tpl[2]):
wxid = ContextMenu.nextID()
swObj, swName, swClass = swData
self.idmap[wxid] = (swObj, swName)
grandSubItem = wx.MenuItem(grandSub, wxid, swClass)
if msw:
rootMenu.Bind(wx.EVT_MENU, self.handleSelection, grandSubItem)
else:
grandSub.Bind(wx.EVT_MENU, self.handleSelection, grandSubItem)
grandSub.Append(grandSubItem)
def getEffectBeacons(self, incursions=False):
"""
Get dictionary with system-wide effects
"""
sMkt = Market.getInstance()
# todo: rework this
# Container for system-wide effects
effects = {}
# Expressions for matching when detecting effects we're looking for
if incursions:
validgroups = ("Incursion ship attributes effects",)
else:
validgroups = ("Black Hole Effect Beacon",
"Cataclysmic Variable Effect Beacon",
"Magnetar Effect Beacon",
"Pulsar Effect Beacon",
"Red Giant Beacon",
"Wolf Rayet Effect Beacon")
# Stuff we don't want to see in names
garbages = ("Effect", "Beacon", "ship attributes effects")
# Get group with all the system-wide beacons
grp = sMkt.getGroup("Effect Beacon")
# Cycle through them
for beacon in sMkt.getItemsByGroup(grp):
# Check if it belongs to any valid group
for group in validgroups:
# Check beginning of the name only
if re.match(group, beacon.name):
# Get full beacon name
beaconname = beacon.name
for garbage in garbages:
beaconname = re.sub(garbage, "", beaconname)
beaconname = re.sub(" {2,}", " ", beaconname).strip()
# Get short name
shortname = re.sub(group, "", beacon.name)
for garbage in garbages:
shortname = re.sub(garbage, "", shortname)
shortname = re.sub(" {2,}", " ", shortname).strip()
# Get group name
groupname = group
for garbage in garbages:
groupname = re.sub(garbage, "", groupname)
groupname = re.sub(" {2,}", " ", groupname).strip()
# Add stuff to dictionary
if groupname not in effects:
effects[groupname] = set()
effects[groupname].add((beacon, beaconname, shortname))
# Break loop on 1st result
break
return effects
def getAbyssalWeather(self):
sMkt = Market.getInstance()
environments = {x.ID: x for x in sMkt.getGroup("Abyssal Environment").items}
items = chain(sMkt.getGroup("MassiveEnvironments").items, sMkt.getGroup("Non-Interactable Object").items)
effects = {}
for beacon in items:
if not beacon.isType('projected'):
continue
type = self.__class__.abyssal_mapping.get(beacon.name[0:-2], None)
type = environments.get(type, None)
if type is None:
continue
if type.name not in effects:
effects[type.name] = set()
display_name = "{} {}".format(type.name, beacon.name[-1:])
effects[type.name].add((beacon, display_name, display_name))
return effects
def getLocalizedEnvironments(self):
sMkt = Market.getInstance()
grp = sMkt.getGroup("Uninteractable Localized Effect Beacon")
effects = dict()
for beacon in grp.items:
if not beacon.isType('projected'):
continue
# Localized effects, currently, have a name like "(size) (type) Cloud"
# Until this inevitably changes, do a simple split
name_parts = beacon.name.split(" ")
key = name_parts[1].strip()
if key not in effects:
effects[key] = set()
effects[key].add((beacon, beacon.name, beacon.name))
return effects
WhProjector.register() WhProjector.register()

View File

@@ -21,6 +21,7 @@ import re
import threading import threading
from logbook import Logger from logbook import Logger
import queue import queue
from itertools import chain
# noinspection PyPackageRequirements # noinspection PyPackageRequirements
import wx import wx
@@ -799,70 +800,4 @@ class Market(object):
filtered = set([item for item in items if self.getMetaGroupIdByItem(item) in metas]) filtered = set([item for item in items if self.getMetaGroupIdByItem(item) in metas])
return filtered return filtered
def getSystemWideEffects(self):
"""
Get dictionary with system-wide effects
"""
# Container for system-wide effects
effects = {}
# Expressions for matching when detecting effects we're looking for
validgroups = ("Black Hole Effect Beacon",
"Cataclysmic Variable Effect Beacon",
"Magnetar Effect Beacon",
"Pulsar Effect Beacon",
"Red Giant Beacon",
"Wolf Rayet Effect Beacon",
"Incursion ship attributes effects",
"MassiveEnvironments",
"Non-Interactable Object")
# Stuff we don't want to see in names
garbages = ("Effect", "Beacon", "ship attributes effects")
# Get group with all the system-wide beacons
grp = self.getGroup("Effect Beacon")
grp2 = self.getGroup("MassiveEnvironments")
grp3 = self.getGroup("Non-Interactable Object")
grp4 = self.getGroup("Uninteractable Localized Effect Beacon")
# Cycle through them
for beacon in self.getItemsByGroup(grp):
print(beacon.name)
# Check if it belongs to any valid group
for group in validgroups:
# Check beginning of the name only
if re.match(group, beacon.name):
# Get full beacon name
beaconname = beacon.name
for garbage in garbages:
beaconname = re.sub(garbage, "", beaconname)
beaconname = re.sub(" {2,}", " ", beaconname).strip()
# Get short name
shortname = re.sub(group, "", beacon.name)
for garbage in garbages:
shortname = re.sub(garbage, "", shortname)
shortname = re.sub(" {2,}", " ", shortname).strip()
# Get group name
groupname = group
for garbage in garbages:
groupname = re.sub(garbage, "", groupname)
groupname = re.sub(" {2,}", " ", groupname).strip()
# Add stuff to dictionary
if groupname not in effects:
effects[groupname] = set()
effects[groupname].add((beacon, beaconname, shortname))
# Break loop on 1st result
break
effects["Weather"] = set()
for beacon in grp3.items:
if "weather" in beacon.name:
effects["Weather"].add((beacon, beacon.name, beacon.name))
for beacon in grp2.items:
if "weather" in beacon.name:
effects["Weather"].add((beacon, beacon.name, beacon.name))
effects["Localized"] = set()
for beacon in grp4.items:
effects["Localized"].add((beacon, beacon.name, beacon.name))
return effects