style(ui): gdformat atlas implant files

This commit is contained in:
2026-04-15 09:06:04 +02:00
parent 489aec48d8
commit 22c17f1f15
3 changed files with 146 additions and 72 deletions
+31 -14
View File
@@ -36,8 +36,15 @@ const RAIL_DASH_ON: float = 6.0
const RAIL_DASH_OFF: float = 4.0
const PRODUCTION_FUNCTIONS: Array = [
"industrial", "industry", "manufacturing", "extraction", "mining",
"refinery", "foundry", "shipyard", "production",
"industrial",
"industry",
"manufacturing",
"extraction",
"mining",
"refinery",
"foundry",
"shipyard",
"production",
]
var viewer = null # AtlasViewer (untyped to avoid cyclic ref)
@@ -56,7 +63,9 @@ func _draw() -> void:
# Terrain (heightmap) — always first
if viewer.is_overlay_visible("terrain"):
draw_texture_rect(tex, Rect2(Vector2.ZERO, Vector2(tex_w, tex_h)), false, COLOR_HEIGHTMAP_TINT)
draw_texture_rect(
tex, Rect2(Vector2.ZERO, Vector2(tex_w, tex_h)), false, COLOR_HEIGHTMAP_TINT
)
else:
draw_rect(Rect2(Vector2.ZERO, Vector2(tex_w, tex_h)), Color(0.05, 0.07, 0.10, 1.0))
@@ -128,7 +137,9 @@ func _draw_named_features(markers: Dictionary) -> void:
if label.is_empty():
continue
var p: Vector2 = _center_to_canvas(ocean.get("center"))
draw_string(font, p, label.to_upper(), HORIZONTAL_ALIGNMENT_CENTER, -1, fs, COLOR_FEATURE_LABEL)
draw_string(
font, p, label.to_upper(), HORIZONTAL_ALIGNMENT_CENTER, -1, fs, COLOR_FEATURE_LABEL
)
for mtn: Dictionary in markers.get("mountain_ranges", []):
var label: String = mtn.get("name", "") if mtn.get("name") else ""
@@ -195,12 +206,16 @@ func _draw_cities(markers: Dictionary) -> void:
var name_str: String = c.get("name", "") if c.get("name") else ""
if not name_str.is_empty() and (tier >= 3 or is_hovered or is_selected):
var lcolor: Color = (
COLOR_CITY_HOVER if is_hovered or is_selected
else Color(0.88, 0.90, 0.96, 0.85)
COLOR_CITY_HOVER if is_hovered or is_selected else Color(0.88, 0.90, 0.96, 0.85)
)
draw_string(
font, pos + Vector2(r + 2.0, r * 0.4), name_str,
HORIZONTAL_ALIGNMENT_LEFT, -1, 8, lcolor
font,
pos + Vector2(r + 2.0, r * 0.4),
name_str,
HORIZONTAL_ALIGNMENT_LEFT,
-1,
8,
lcolor
)
@@ -304,12 +319,14 @@ func _poi_pos(poi: Dictionary) -> Vector2:
func _draw_diamond(pos: Vector2, size: float, color: Color) -> void:
var pts: PackedVector2Array = PackedVector2Array([
pos + Vector2(0, -size),
pos + Vector2(size, 0),
pos + Vector2(0, size),
pos + Vector2(-size, 0),
])
var pts: PackedVector2Array = PackedVector2Array(
[
pos + Vector2(0, -size),
pos + Vector2(size, 0),
pos + Vector2(0, size),
pos + Vector2(-size, 0),
]
)
draw_colored_polygon(pts, color)
+36 -21
View File
@@ -27,12 +27,12 @@ const PANEL_MARGIN: float = 16.0
# ── Orbital diagram geometry ──────────────────────────────────────────────────
const ORBITAL_CENTER_FRACTION := Vector2(0.5, 0.55)
const STAR_RADIUS: float = 12.0
const ORBITAL_RING_BASE: float = 65.0 # innermost planet ring radius (px)
const ORBITAL_RING_STEP: float = 58.0 # radial gap between orbit rings
const MOON_ORBIT_RADIUS: float = 24.0 # sub-orbit radius for moons around parent
const STATION_SIZE: float = 6.0 # station marker half-size
const BODY_HIT_RADIUS: float = 16.0 # click/hover detection radius
const LABEL_OFFSET: float = 11.0 # px below body dot for label
const ORBITAL_RING_BASE: float = 65.0 # innermost planet ring radius (px)
const ORBITAL_RING_STEP: float = 58.0 # radial gap between orbit rings
const MOON_ORBIT_RADIUS: float = 24.0 # sub-orbit radius for moons around parent
const STATION_SIZE: float = 6.0 # station marker half-size
const BODY_HIT_RADIUS: float = 16.0 # click/hover detection radius
const LABEL_OFFSET: float = 11.0 # px below body dot for label
# ── Colors ────────────────────────────────────────────────────────────────────
const COLOR_BG: Color = Color("#0d1117")
@@ -49,28 +49,28 @@ const COLOR_TEXT_DIM: Color = Color("#667788")
# ── Navigation state ──────────────────────────────────────────────────────────
var _level: Level = Level.SYSTEM_PICKER
var _systems: Array = [] # Array[Dictionary] from star_map_data.json
var _selected_idx: int = 0 # index into _systems
var _systems: Array = [] # Array[Dictionary] from star_map_data.json
var _selected_idx: int = 0 # index into _systems
var _selected_body: Dictionary = {} # body dict at Level.BODY_ENTRY
# ── Orbital diagram runtime state ─────────────────────────────────────────────
var _orbital_bodies: Array = [] # orbit_bodies for current system
var _orbital_bodies: Array = [] # orbit_bodies for current system
var _orbital_stations: Array = [] # stations for current system
var _body_positions: Dictionary = {} # body_id -> Vector2
var _station_positions: Dictionary = {} # station_id -> Vector2
var _body_positions: Dictionary = {} # body_id -> Vector2
var _station_positions: Dictionary = {} # station_id -> Vector2
var _hovered_body: String = ""
var _hovered_station: String = ""
var _selected_station: Dictionary = {} # station clicked in orbital view
var _dirty: bool = true
# ── Visual components (D-169 ImplantPanel library) ────────────────────────────
var _implant_theme = null # ImplantTheme — loaded at runtime (autoload parse-order rule)
var _picker_panel = null # ImplantPanel — level 0 system selector
var _picker_nav_row = null # ImplantDataRow — nav hint text, updated on navigate
var _body_panel = null # ImplantPanel — level 2 body entry
var _station_panel = null # ImplantPanel — station mini, shown in level 1 on click
var _implant_theme = null # ImplantTheme — loaded at runtime (autoload parse-order rule)
var _picker_panel = null # ImplantPanel — level 0 system selector
var _picker_nav_row = null # ImplantDataRow — nav hint text, updated on navigate
var _body_panel = null # ImplantPanel — level 2 body entry
var _station_panel = null # ImplantPanel — station mini, shown in level 1 on click
var _screen_header: ImplantHeader = null # D-169-composed title/hint row (top-left)
var _viewer = null # AtlasViewer — level 3 heightmap viewer (#835)
var _viewer = null # AtlasViewer — level 3 heightmap viewer (#835)
func _ready() -> void:
@@ -446,7 +446,10 @@ func _draw_stations() -> void:
var rect: Rect2 = Rect2(pos - Vector2(half, half), Vector2(STATION_SIZE, STATION_SIZE))
if sid == _hovered_station:
draw_rect(Rect2(rect.position - Vector2(3, 3), rect.size + Vector2(6, 6)), Color(1.0, 1.0, 1.0, 0.18))
draw_rect(
Rect2(rect.position - Vector2(3, 3), rect.size + Vector2(6, 6)),
Color(1.0, 1.0, 1.0, 0.18)
)
draw_rect(rect, COLOR_STATION)
@@ -454,7 +457,15 @@ func _draw_stations() -> void:
if sid == _hovered_station:
var label: String = s.get("proper_name", sid) if s.get("proper_name") else sid
var lsz: Vector2 = font.get_string_size(label, HORIZONTAL_ALIGNMENT_LEFT, -1, 9)
draw_string(font, pos + Vector2(-lsz.x / 2.0, half + 8.0), label, HORIZONTAL_ALIGNMENT_LEFT, -1, 9, COLOR_TEXT_DIM)
draw_string(
font,
pos + Vector2(-lsz.x / 2.0, half + 8.0),
label,
HORIZONTAL_ALIGNMENT_LEFT,
-1,
9,
COLOR_TEXT_DIM
)
# =============================================================================
@@ -736,7 +747,9 @@ func _rebuild_station_panel() -> void:
return
var s: Dictionary = _selected_station
var s_name: String = s.get("proper_name", "") if s.get("proper_name") else s.get("station_id", "")
var s_name: String = (
s.get("proper_name", "") if s.get("proper_name") else s.get("station_id", "")
)
var s_type: String = s.get("station_type", "").replace("_", " ").to_upper()
var gov: String = s.get("governance_type", "") if s.get("governance_type") else ""
var role: String = s.get("economic_role", "") if s.get("economic_role") else ""
@@ -747,7 +760,9 @@ func _rebuild_station_panel() -> void:
_station_panel.add_component(ImplantHeader.new(s_name, s_type + " STATION"))
_station_panel.add_component(ImplantSeparator.new())
if not gov.is_empty():
_station_panel.add_component(ImplantDataRow.new("operator " + gov.replace("_", " ").to_upper()))
_station_panel.add_component(
ImplantDataRow.new("operator " + gov.replace("_", " ").to_upper())
)
if not role.is_empty():
_station_panel.add_component(ImplantDataRow.new("function " + role.replace("_", " ")))
_station_panel.add_component(ImplantDataRow.new("currency " + czone))
+79 -37
View File
@@ -56,28 +56,72 @@ const COLOR_EMPTY_NOTICE: Color = Color("#445566")
## visibility ladder: always = public, toggle = observable, locked = semi-
## private / private. Keep this table in sync with D-191 §7.
const OVERLAY_DEFS: Array = [
{"id": "terrain", "label": "TER", "group": "always",
"tooltip": "Terrain — base heightmap. Always visible."},
{"id": "infrastructure", "label": "INF", "group": "always",
"tooltip": "Infrastructure — roads + rail. Always visible."},
{"id": "named_features", "label": "NAM", "group": "always",
"tooltip": "Named features — rivers, oceans, ranges. Always visible."},
{"id": "gate_markers", "label": "GAT", "group": "always",
"tooltip": "Gate + spaceport markers. Always visible."},
{"id": "political_zones", "label": "POL", "group": "always",
"tooltip": "Political zones — currency-zone bands. Always visible."},
{"id": "population_density", "label": "POP", "group": "toggle",
"tooltip": "Population density (D-181 public)."},
{"id": "production_zones", "label": "PRD", "group": "toggle",
"tooltip": "Production zones (D-181 observable — requires presence)."},
{"id": "shadow_economy", "label": "SHD", "group": "toggle",
"tooltip": "Shadow economy zones (D-181 observable)."},
{"id": "corp_presence", "label": "CRP", "group": "toggle",
"tooltip": "Corporate presence — Tier 1 only (D-181 observable)."},
{"id": "stockpile_weeks", "label": "STK", "group": "locked",
"tooltip": "Stockpile weeks — LOCKED. Needs corporate contact (D-181 semi-private)."},
{"id": "production_vs_baseline", "label": "BSL", "group": "locked",
"tooltip": "Production vs baseline — LOCKED. Needs insider access (D-181 private)."},
{
"id": "terrain",
"label": "TER",
"group": "always",
"tooltip": "Terrain — base heightmap. Always visible."
},
{
"id": "infrastructure",
"label": "INF",
"group": "always",
"tooltip": "Infrastructure — roads + rail. Always visible."
},
{
"id": "named_features",
"label": "NAM",
"group": "always",
"tooltip": "Named features — rivers, oceans, ranges. Always visible."
},
{
"id": "gate_markers",
"label": "GAT",
"group": "always",
"tooltip": "Gate + spaceport markers. Always visible."
},
{
"id": "political_zones",
"label": "POL",
"group": "always",
"tooltip": "Political zones — currency-zone bands. Always visible."
},
{
"id": "population_density",
"label": "POP",
"group": "toggle",
"tooltip": "Population density (D-181 public)."
},
{
"id": "production_zones",
"label": "PRD",
"group": "toggle",
"tooltip": "Production zones (D-181 observable — requires presence)."
},
{
"id": "shadow_economy",
"label": "SHD",
"group": "toggle",
"tooltip": "Shadow economy zones (D-181 observable)."
},
{
"id": "corp_presence",
"label": "CRP",
"group": "toggle",
"tooltip": "Corporate presence — Tier 1 only (D-181 observable)."
},
{
"id": "stockpile_weeks",
"label": "STK",
"group": "locked",
"tooltip": "Stockpile weeks — LOCKED. Needs corporate contact (D-181 semi-private)."
},
{
"id": "production_vs_baseline",
"label": "BSL",
"group": "locked",
"tooltip": "Production vs baseline — LOCKED. Needs insider access (D-181 private)."
},
]
# ── Context (set by AtlasPanel.show_body) ─────────────────────────────────────
@@ -112,12 +156,12 @@ var _overlay_visibility: Dictionary = {}
var _overlay_locked: Dictionary = {}
# ── Child nodes ───────────────────────────────────────────────────────────────
var _canvas: Node2D = null # transformed node holding heightmap + markers
var _canvas: Node2D = null # transformed node holding heightmap + markers
var _overlay_node: AtlasMarkerOverlay = null # draws on top of heightmap
var _city_panel = null # ImplantPanel sidebar (city data)
var _empty_notice = null # ImplantPanel shown when heightmap missing
var _overlay_bar = null # #836 overlay toggle bar (no class_name, review #8)
var _screen_header: ImplantHeader = null # top-left title/hint (D-169 composition)
var _city_panel = null # ImplantPanel sidebar (city data)
var _empty_notice = null # ImplantPanel shown when heightmap missing
var _overlay_bar = null # #836 overlay toggle bar (no class_name, review #8)
var _screen_header: ImplantHeader = null # top-left title/hint (D-169 composition)
func _ready() -> void:
@@ -314,10 +358,7 @@ func _zoom_at(mouse_pos: Vector2, factor: float) -> void:
func grid_to_canvas(grid_point: Vector2) -> Vector2:
if _grid_w <= 0.0 or _grid_h <= 0.0:
return Vector2.ZERO
return Vector2(
grid_point.x / _grid_w * _tex_w,
grid_point.y / _grid_h * _tex_h
)
return Vector2(grid_point.x / _grid_w * _tex_w, grid_point.y / _grid_h * _tex_h)
func canvas_to_screen(canvas_point: Vector2) -> Vector2:
@@ -461,10 +502,7 @@ func city_canvas_pos(city: Dictionary) -> Vector2:
if city.has("lat") and city.has("lon"):
var lon: float = float(city["lon"])
var lat: float = float(city["lat"])
return Vector2(
(lon + 180.0) / 360.0 * _tex_w,
(90.0 - lat) / 180.0 * _tex_h
)
return Vector2((lon + 180.0) / 360.0 * _tex_w, (90.0 - lat) / 180.0 * _tex_h)
if city.has("center") and city["center"] is Array and city["center"].size() >= 2:
# center is [row, col] in grid space
return grid_to_canvas(Vector2(float(city["center"][1]), float(city["center"][0])))
@@ -526,7 +564,9 @@ func _rebuild_city_panel() -> void:
if not czone.is_empty():
_city_panel.add_component(ImplantDataRow.new("currency " + czone))
var commission: bool = bool(c.get("commission_presence", false))
_city_panel.add_component(ImplantDataRow.new("commission " + ("yes" if commission else "no")))
_city_panel.add_component(
ImplantDataRow.new("commission " + ("yes" if commission else "no"))
)
var shadow: Variant = c.get("shadow_economy_zone")
if shadow != null and not str(shadow).is_empty():
_city_panel.add_component(ImplantDataRow.new("shadow zone " + str(shadow)))
@@ -570,7 +610,9 @@ func _build_empty_notice() -> void:
_empty_notice.mouse_filter = Control.MOUSE_FILTER_IGNORE
_empty_notice.visible = false
add_child(_empty_notice)
_empty_notice.add_component(ImplantHeader.new("TERRAIN DATA PENDING", "regional atlas unavailable"))
_empty_notice.add_component(
ImplantHeader.new("TERRAIN DATA PENDING", "regional atlas unavailable")
)
_empty_notice.add_component(ImplantSeparator.new())
var notice_text: String = (
"The server atlas pipeline has not yet populated terrain_reference for this body (#839). "