54 lines
2.1 KiB
GDScript
54 lines
2.1 KiB
GDScript
extends Control
|
|
## The compass (Gitea issue #1): a strip across the top of the screen that
|
|
## shows which way you're facing, N/E/S/W and the points between, with a tick
|
|
## at the centre. North is the map's top (-Z).
|
|
|
|
const UITheme = preload("res://scripts/ui/theme.gd")
|
|
const WIDTH := 420.0
|
|
const SPAN := 180.0 ## degrees shown across the strip
|
|
const POINTS := [[0, "N"], [45, "NE"], [90, "E"], [135, "SE"], [180, "S"], [225, "SW"], [270, "W"], [315, "NW"]]
|
|
|
|
var player: Node3D
|
|
|
|
func setup(p: Node3D) -> void:
|
|
player = p
|
|
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
set_anchors_preset(Control.PRESET_CENTER_TOP)
|
|
offset_left = -WIDTH * 0.5
|
|
offset_right = WIDTH * 0.5
|
|
offset_top = 44.0
|
|
offset_bottom = 74.0
|
|
|
|
## Which way `p` faces, in degrees clockwise from north (0 = N, 90 = E).
|
|
static func heading(p: Node3D) -> float:
|
|
var f: Vector3 = -p.global_basis.z
|
|
return fposmod(rad_to_deg(atan2(f.x, -f.z)), 360.0)
|
|
|
|
func _process(_d: float) -> void:
|
|
visible = player != null and is_instance_valid(player) and not bool(player.get("ui_open"))
|
|
queue_redraw()
|
|
|
|
func _draw() -> void:
|
|
if player == null or not is_instance_valid(player):
|
|
return
|
|
var h := heading(player)
|
|
var font := get_theme_default_font()
|
|
draw_rect(Rect2(Vector2.ZERO, size), Color(0, 0, 0, 0.35))
|
|
for deg in range(0, 360, 15):
|
|
var off := wrapf(deg - h, -180.0, 180.0)
|
|
if absf(off) > SPAN * 0.5:
|
|
continue
|
|
var x := WIDTH * 0.5 + off / SPAN * WIDTH
|
|
var big := deg % 45 == 0
|
|
draw_line(Vector2(x, 0), Vector2(x, 6 if not big else 9), Color(1, 1, 1, 0.5 if not big else 0.8), 1.0)
|
|
for pt in POINTS:
|
|
var off := wrapf(float(pt[0]) - h, -180.0, 180.0)
|
|
if absf(off) > SPAN * 0.5 - 6.0:
|
|
continue
|
|
var x := WIDTH * 0.5 + off / SPAN * WIDTH
|
|
var s := 17 if String(pt[1]).length() == 1 else 13
|
|
var col := Color(1.0, 0.55, 0.35) if pt[1] == "N" else Color(1, 1, 1, 0.9)
|
|
var w := font.get_string_size(pt[1], HORIZONTAL_ALIGNMENT_CENTER, -1, s).x
|
|
draw_string(font, Vector2(x - w * 0.5, 25), pt[1], HORIZONTAL_ALIGNMENT_LEFT, -1, s, col)
|
|
draw_line(Vector2(WIDTH * 0.5, 0), Vector2(WIDTH * 0.5, 30), Color(1.0, 0.85, 0.4, 0.9), 2.0)
|