- constants.gd: clamp format_game_time input to 0..1439 (Hoshe #2) - interaction_list.gd: add public hide_list() wrapper (Hoshe #3, Tyre #1) - main.gd: call hide_list() instead of private _hide() - time_display.gd: cache font geometry in update_from_state(), use boolean _has_data flag instead of string guard (Tyre #2) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
98 lines
3.5 KiB
GDScript
98 lines
3.5 KiB
GDScript
extends Control
|
|
|
|
## #263: Time display — diegetic time readout on the player's neural insert (D-013, D-031).
|
|
## Shows station local time (HH:MM), day phase, and day number.
|
|
## Lives on InsertOverlay (CanvasLayer 10) per D-051 diegetic insert principle.
|
|
## Draw-based for implant visual aesthetic. Updated via update_from_state() from main.gd.
|
|
##
|
|
## Placeholder layout — position and style will be refined when #314 wireframe lands.
|
|
|
|
const FONT_SIZE_TIME: int = 15
|
|
const FONT_SIZE_META: int = 10
|
|
const PADDING := Vector2(10, 7)
|
|
const BG_COLOR := Color(0.04, 0.05, 0.08, 0.70)
|
|
const BORDER_COLOR := Color(0.10, 0.20, 0.26, 0.65)
|
|
|
|
# Day phase colors — station lighting cycle (D-031)
|
|
const PHASE_COLORS := {
|
|
"Morning": Color("#aed6dc"), # pale cyan-blue — early light
|
|
"Afternoon": Color("#E0F7FA"), # bright cyan-white — full day
|
|
"Evening": Color("#9EBFC4"), # dimmed — dusk transition
|
|
"Night": Color("#4a7080"), # dark teal — station nightwatch
|
|
}
|
|
|
|
var _time_str: String = "--:--"
|
|
var _phase_str: String = ""
|
|
var _day_str: String = ""
|
|
var _day_text: String = ""
|
|
var _phase_color: Color = Constants.IMPLANT_TEXT_DIM
|
|
var _last_signature: String = ""
|
|
var _has_data: bool = false
|
|
|
|
# Cached geometry — recomputed in update_from_state(), used in _draw()
|
|
var _time_size: Vector2 = Vector2.ZERO
|
|
var _phase_size: Vector2 = Vector2.ZERO
|
|
var _day_size: Vector2 = Vector2.ZERO
|
|
var _meta_h: float = 0.0
|
|
var _box_w: float = 0.0
|
|
var _box_h: float = 0.0
|
|
|
|
|
|
func _ready() -> void:
|
|
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
|
|
|
|
func update_from_state() -> void:
|
|
var gt: Dictionary = GameState.game_time
|
|
if gt.is_empty():
|
|
return
|
|
var tod: int = int(gt.get("time_of_day", 0))
|
|
var day: int = int(gt.get("day", 0))
|
|
var phase: String = str(gt.get("day_phase", ""))
|
|
var sig: String = "%d:%d:%s" % [tod, day, phase]
|
|
if sig == _last_signature:
|
|
return
|
|
_last_signature = sig
|
|
_time_str = Constants.format_game_time(tod)
|
|
_phase_str = phase
|
|
_day_str = "D%d" % (day + 1)
|
|
_day_text = " " + _day_str
|
|
_phase_color = PHASE_COLORS.get(phase, Constants.IMPLANT_TEXT_DIM)
|
|
_has_data = true
|
|
_cache_geometry()
|
|
queue_redraw()
|
|
|
|
|
|
func _cache_geometry() -> void:
|
|
var font := ThemeDB.fallback_font
|
|
_time_size = font.get_string_size(_time_str, HORIZONTAL_ALIGNMENT_LEFT, -1, FONT_SIZE_TIME)
|
|
_phase_size = font.get_string_size(_phase_str, HORIZONTAL_ALIGNMENT_LEFT, -1, FONT_SIZE_META)
|
|
_day_size = font.get_string_size(_day_text, HORIZONTAL_ALIGNMENT_LEFT, -1, FONT_SIZE_META)
|
|
_meta_h = font.get_string_size("A", HORIZONTAL_ALIGNMENT_LEFT, -1, FONT_SIZE_META).y
|
|
var meta_w := _phase_size.x + _day_size.x
|
|
var content_w := max(_time_size.x, meta_w)
|
|
_box_w = content_w + PADDING.x * 2
|
|
_box_h = PADDING.y * 2 + _time_size.y + 3 + _meta_h
|
|
|
|
|
|
func _draw() -> void:
|
|
if not _has_data:
|
|
return
|
|
|
|
# Background
|
|
draw_rect(Rect2(Vector2.ZERO, Vector2(_box_w, _box_h)), BG_COLOR)
|
|
draw_rect(Rect2(Vector2.ZERO, Vector2(_box_w, _box_h)), BORDER_COLOR, false, 1.0)
|
|
|
|
var font := ThemeDB.fallback_font
|
|
|
|
# HH:MM (primary, full brightness)
|
|
draw_string(font, Vector2(PADDING.x, PADDING.y + _time_size.y),
|
|
_time_str, HORIZONTAL_ALIGNMENT_LEFT, -1, FONT_SIZE_TIME, Constants.IMPLANT_TEXT_COLOR)
|
|
|
|
# Phase + day number (secondary, dimmed + phase-tinted)
|
|
var meta_y := PADDING.y + _time_size.y + 3 + _meta_h
|
|
draw_string(font, Vector2(PADDING.x, meta_y),
|
|
_phase_str, HORIZONTAL_ALIGNMENT_LEFT, -1, FONT_SIZE_META, _phase_color)
|
|
draw_string(font, Vector2(PADDING.x + _phase_size.x, meta_y),
|
|
_day_text, HORIZONTAL_ALIGNMENT_LEFT, -1, FONT_SIZE_META, Constants.IMPLANT_TEXT_DIM)
|