mirror of
https://github.com/norohind/HabZone.git
synced 2025-04-12 05:10:00 +03:00
Option to look up system in EDSM
This commit is contained in:
parent
470eca92e9
commit
20f9bb2e83
@ -1,10 +1,12 @@
|
||||
# Habitable Zone plugin for [EDMC](https://github.com/Marginal/EDMarketConnector/wiki)
|
||||
|
||||
This plugin displays the "habitable-zone" (i.e. the range of distances in which you might find an Earth-Like World) when you scan the primary star in a system with a [Detailed Surface Scanner](http://elite-dangerous.wikia.com/wiki/Detailed_Surface_Scanner).
|
||||
This plugin helps explorers find high-value planets. It displays the "habitable-zone" (i.e. the range of distances in which you might find an Earth-Like World) when you scan the primary star in a system with a [Detailed Surface Scanner](http://elite-dangerous.wikia.com/wiki/Detailed_Surface_Scanner).
|
||||
|
||||

|
||||
|
||||
Optionally, you can choose to display the ranges in which you might find Metal-Rich, Water and/or Ammonia Worlds.
|
||||
Optionally, you can choose to display the ranges in which you might find other high-value planets - Metal-Rich, Water and/or Ammonia Worlds.
|
||||
|
||||
Optionally, you can choose to display the high-value planets known to [Elite Dangerous Star Map](https://www.edsm.net/).
|
||||
|
||||
## Installation
|
||||
|
||||
|
BIN
img/screenie.png
BIN
img/screenie.png
Binary file not shown.
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
162
load.py
162
load.py
@ -3,9 +3,14 @@
|
||||
# Display the "habitable-zone" (i.e. the range of distances in which you might find an Earth-Like World)
|
||||
#
|
||||
|
||||
from collections import defaultdict
|
||||
import requests
|
||||
import sys
|
||||
import threading
|
||||
import urllib2
|
||||
|
||||
import Tkinter as tk
|
||||
from ttkHyperlinkLabel import HyperlinkLabel
|
||||
import myNotebook as nb
|
||||
|
||||
if __debug__:
|
||||
@ -16,70 +21,90 @@ from l10n import Locale
|
||||
|
||||
VERSION = '1.00'
|
||||
|
||||
SETTING_DEFAULT = 2 # Earth-like
|
||||
SETTING_DEFAULT = 0x0002 # Earth-like
|
||||
SETTING_EDSM = 0x1000
|
||||
SETTING_NONE = 0xffff
|
||||
|
||||
WORLDS = [
|
||||
# Type Black-body temp range
|
||||
('Metal-Rich', 0, 1103.0),
|
||||
('Earth-Like', 278.0, 227.0),
|
||||
('Water', 307.0, 156.0),
|
||||
('Ammonia', 193.0, 117.0),
|
||||
# Type Black-body temp range EDSM description
|
||||
('Metal-Rich', 0, 1103.0, 'Metal-rich body'),
|
||||
('Earth-Like', 278.0, 227.0, 'Earth-like world'),
|
||||
('Water', 307.0, 156.0, 'Water world'),
|
||||
('Ammonia', 193.0, 117.0, 'Ammonia world'),
|
||||
]
|
||||
|
||||
LS = 300000000.0 # 1 ls in m (approx)
|
||||
|
||||
this = sys.modules[__name__] # For holding module globals
|
||||
this.frame = None
|
||||
this.worlds = []
|
||||
this.edsm_session = None
|
||||
this.edsm_data = None
|
||||
|
||||
# Used during preferences
|
||||
this.settings = None
|
||||
this.edsm_setting = None
|
||||
|
||||
|
||||
def plugin_start():
|
||||
# App isn't initialised at this point so can't do anything interesting
|
||||
return 'HabZone'
|
||||
|
||||
def plugin_app(parent):
|
||||
frame = tk.Frame(parent)
|
||||
frame.columnconfigure(3, weight=1)
|
||||
this.worlds = []
|
||||
for (name, high, low) in WORLDS:
|
||||
this.worlds.append((tk.Label(frame, text = name + ':'),
|
||||
tk.Label(frame),
|
||||
tk.Label(frame),
|
||||
tk.Label(frame),
|
||||
tk.Label(frame),
|
||||
# Create and display widgets
|
||||
this.frame = tk.Frame(parent)
|
||||
this.frame.columnconfigure(3, weight=1)
|
||||
this.frame.bind('<<HabZoneData>>', edsm_data) # callback when EDSM data received
|
||||
for (name, high, low, subType) in WORLDS:
|
||||
this.worlds.append((tk.Label(this.frame, text = name + ':'),
|
||||
HyperlinkLabel(this.frame), # edsm
|
||||
tk.Label(this.frame), # near
|
||||
tk.Label(this.frame), # dash
|
||||
tk.Label(this.frame), # far
|
||||
tk.Label(this.frame), # ls
|
||||
))
|
||||
this.spacer = tk.Frame(frame) # Main frame can't be empty or it doesn't resize
|
||||
this.terraformable_label = tk.Label(this.frame, text = 'Terraformable:')
|
||||
this.terraformable = HyperlinkLabel(this.frame)
|
||||
this.spacer = tk.Frame(this.frame) # Main frame can't be empty or it doesn't resize
|
||||
update_visibility()
|
||||
return frame
|
||||
return this.frame
|
||||
|
||||
def plugin_prefs(parent):
|
||||
def plugin_prefs(parent, cmdr, is_beta):
|
||||
frame = nb.Frame(parent)
|
||||
nb.Label(frame, text = 'Display:').grid(row = 0, padx = 10, pady = (10,0), sticky=tk.W)
|
||||
|
||||
setting = get_setting()
|
||||
this.settings = []
|
||||
row = 1
|
||||
for (name, high, low) in WORLDS:
|
||||
for (name, high, low, subType) in WORLDS:
|
||||
var = tk.IntVar(value = (setting & row) and 1)
|
||||
nb.Checkbutton(frame, text = name, variable = var).grid(row = row, padx = 10, pady = 2, sticky=tk.W)
|
||||
this.settings.append(var)
|
||||
row *= 2
|
||||
|
||||
nb.Label(frame, text = 'Elite Dangerous Star Map:').grid(padx = 10, pady = (10,0), sticky=tk.W)
|
||||
this.edsm_setting = tk.IntVar(value = (setting & SETTING_EDSM) and 1)
|
||||
nb.Checkbutton(frame, text = 'Look up system in EDSM database', variable = this.edsm_setting).grid(padx = 10, pady = 2, sticky=tk.W)
|
||||
|
||||
nb.Label(frame, text = 'Version %s' % VERSION).grid(padx = 10, pady = 10, sticky=tk.W)
|
||||
|
||||
return frame
|
||||
|
||||
def prefs_changed():
|
||||
def prefs_changed(cmdr, is_beta):
|
||||
row = 1
|
||||
setting = 0
|
||||
for var in this.settings:
|
||||
setting += var.get() and row
|
||||
row *= 2
|
||||
|
||||
setting += this.edsm_setting.get() and SETTING_EDSM
|
||||
config.set('habzone', setting or SETTING_NONE)
|
||||
this.settings = None
|
||||
this.edsm_setting = None
|
||||
update_visibility()
|
||||
|
||||
|
||||
def journal_entry(cmdr, system, station, entry, state):
|
||||
def journal_entry(cmdr, is_beta, system, station, entry, state):
|
||||
|
||||
if entry['event'] == 'Scan':
|
||||
try:
|
||||
@ -87,8 +112,8 @@ def journal_entry(cmdr, system, station, entry, state):
|
||||
r = float(entry['Radius'])
|
||||
t = float(entry['SurfaceTemperature'])
|
||||
for i in range(len(WORLDS)):
|
||||
(name, high, low) = WORLDS[i]
|
||||
(label, near, dash, far, ls) = this.worlds[i]
|
||||
(name, high, low, subType) = WORLDS[i]
|
||||
(label, edsm, near, dash, far, ls) = this.worlds[i]
|
||||
far_dist = int(0.5 + dfort(r, t, low))
|
||||
radius = int(0.5 + r / LS)
|
||||
if far_dist <= radius:
|
||||
@ -105,24 +130,93 @@ def journal_entry(cmdr, system, station, entry, state):
|
||||
far['text'] = Locale.stringFromNumber(far_dist)
|
||||
ls['text'] = 'ls'
|
||||
except:
|
||||
for (label, near, dash, far, ls) in this.worlds:
|
||||
for (label, edsm, near, dash, far, ls) in this.worlds:
|
||||
near['text'] = ''
|
||||
dash['text'] = ''
|
||||
far['text'] = ''
|
||||
ls['text'] = '?'
|
||||
|
||||
elif entry['event'] == 'FSDJump':
|
||||
for (label, near, dash, far, ls) in this.worlds:
|
||||
for (label, edsm, near, dash, far, ls) in this.worlds:
|
||||
edsm['text'] = ''
|
||||
edsm['url'] = ''
|
||||
near['text'] = ''
|
||||
dash['text'] = ''
|
||||
far['text'] = ''
|
||||
ls['text'] = ''
|
||||
|
||||
if entry['event'] in ['Location', 'FSDJump'] and get_setting() & SETTING_EDSM:
|
||||
thread = threading.Thread(target = edsm_worker, name = 'EDSM worker', args = (entry['StarSystem'],))
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
|
||||
def cmdr_data(data, is_beta):
|
||||
# Manual Update
|
||||
if get_setting() & SETTING_EDSM and not data['commander']['docked']:
|
||||
thread = threading.Thread(target = edsm_worker, name = 'EDSM worker', args = (data['lastSystem']['name'],))
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
|
||||
# Distance for target black-body temperature
|
||||
# From Jackie Silver's Hab-Zone Calculator https://forums.frontier.co.uk/showthread.php?p=5452081
|
||||
def dfort(r, t, target):
|
||||
return (((r ** 2) * (t ** 4) / (4 * (target ** 4))) ** 0.5) / LS
|
||||
|
||||
|
||||
# EDSM lookup
|
||||
def edsm_worker(systemName):
|
||||
|
||||
if not this.edsm_session:
|
||||
this.edsm_session = requests.Session()
|
||||
|
||||
r = this.edsm_session.get('https://www.edsm.net/api-system-v1/bodies?systemName=%s' % urllib2.quote(systemName), timeout=10)
|
||||
if r.status_code != requests.codes.ok:
|
||||
this.edsm_data = None
|
||||
else:
|
||||
try:
|
||||
this.edsm_data = r.json()
|
||||
except:
|
||||
this.edsm_data = None
|
||||
|
||||
# Tk is not thread-safe, so can't access widgets in this thread.
|
||||
# event_generate() is the only safe way to poke the main thread from this thread.
|
||||
this.frame.event_generate('<<HabZoneData>>', when='tail')
|
||||
|
||||
|
||||
# EDSM data received
|
||||
def edsm_data(event):
|
||||
|
||||
if this.edsm_data is None:
|
||||
# error
|
||||
for (label, edsm, near, dash, far, ls) in this.worlds:
|
||||
edsm['text'] = '?'
|
||||
edsm['url'] = None
|
||||
this.terraformable['text'] = '?'
|
||||
this.terraformable['url'] = None
|
||||
return
|
||||
|
||||
# Collate
|
||||
bodies = defaultdict(list)
|
||||
for body in this.edsm_data.get('bodies', []):
|
||||
if body.get('terraformingState') == 'Candidate for terraforming':
|
||||
bodies['terraformable'].append(body['name'])
|
||||
else:
|
||||
bodies[body['subType']].append(body['name'])
|
||||
|
||||
# Display
|
||||
systemName = this.edsm_data.get('name', '')
|
||||
url = 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote(systemName)
|
||||
for i in range(len(WORLDS)):
|
||||
(name, high, low, subType) = WORLDS[i]
|
||||
(label, edsm, near, dash, far, ls) = this.worlds[i]
|
||||
edsm['text'] = ' '.join([x[len(systemName):].replace(' ', '') if x.startswith(systemName) else x for x in bodies[subType]])
|
||||
edsm['url'] = url
|
||||
this.terraformable['text'] = ' '.join([x[len(systemName):].replace(' ', '') if x.startswith(systemName) else x for x in bodies['terraformable']])
|
||||
this.terraformable['url'] = url
|
||||
|
||||
|
||||
def get_setting():
|
||||
setting = config.getint('habzone')
|
||||
if setting == 0:
|
||||
@ -135,20 +229,28 @@ def get_setting():
|
||||
def update_visibility():
|
||||
setting = get_setting()
|
||||
row = 1
|
||||
for (label, near, dash, far, ls) in this.worlds:
|
||||
for (label, edsm, near, dash, far, ls) in this.worlds:
|
||||
if setting & row:
|
||||
label.grid(row = row, column = 0, sticky=tk.W)
|
||||
near.grid(row = row, column = 1, sticky=tk.E)
|
||||
dash.grid(row = row, column = 2, sticky=tk.E)
|
||||
far.grid(row = row, column = 3, sticky=tk.E)
|
||||
ls.grid(row = row, column = 4, sticky=tk.W)
|
||||
edsm.grid(row = row, column = 1, sticky=tk.W, padx = (0,10))
|
||||
near.grid(row = row, column = 2, sticky=tk.E)
|
||||
dash.grid(row = row, column = 3, sticky=tk.E)
|
||||
far.grid(row = row, column = 4, sticky=tk.E)
|
||||
ls.grid(row = row, column = 5, sticky=tk.W)
|
||||
else:
|
||||
label.grid_remove()
|
||||
edsm.grid_remove()
|
||||
near.grid_remove()
|
||||
dash.grid_remove()
|
||||
far.grid_remove()
|
||||
ls.grid_remove()
|
||||
row *= 2
|
||||
if setting & SETTING_EDSM:
|
||||
this.terraformable_label.grid(row = row, column = 0, sticky=tk.W)
|
||||
this.terraformable.grid(row = row, column = 1, sticky=tk.W)
|
||||
else:
|
||||
this.terraformable_label.grid_remove()
|
||||
this.terraformable.grid_remove()
|
||||
if setting:
|
||||
this.spacer.grid_remove()
|
||||
else:
|
||||
|
Loading…
x
Reference in New Issue
Block a user