mirror of
https://github.com/ElHombreAlex/FTL-Faster-Than-Light-VR.git
synced 2026-10-06 03:00:06 +02:00
V0.1
First publishable version of the mod
This commit is contained in:
commit
35cdf71054
112 files changed
+18125
No files matched your search
@@ -0,0 +1,114 @@
|
||||
extends Node3D
|
||||
|
||||
# One FTL-styled radial surface. Choosing a sector redraws once; no animated
|
||||
# viewport or per-label meshes are needed while the wheel is held open.
|
||||
const UI = preload("res://scripts/ftl_ui_theme.gd")
|
||||
const SIZE := Vector2(0.54,0.60)
|
||||
const PIXELS := Vector2(720,800)
|
||||
var selected := -1
|
||||
var entries: Array = []
|
||||
var heading := "ACTIONS"
|
||||
var viewport: SubViewport
|
||||
var canvas: Control
|
||||
var content_revision := 0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
viewport = SubViewport.new()
|
||||
viewport.size = Vector2i(PIXELS)
|
||||
viewport.transparent_bg = true
|
||||
viewport.render_target_update_mode = SubViewport.UPDATE_ONCE
|
||||
add_child(viewport)
|
||||
canvas = WheelCanvas.new()
|
||||
canvas.wheel = self
|
||||
canvas.size = PIXELS
|
||||
canvas.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
viewport.add_child(canvas)
|
||||
var backing := MeshInstance3D.new()
|
||||
var quad := QuadMesh.new()
|
||||
quad.size = SIZE
|
||||
backing.mesh = quad
|
||||
backing.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||
var material := StandardMaterial3D.new()
|
||||
material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
||||
material.no_depth_test = true
|
||||
material.render_priority = 125
|
||||
material.texture_filter = BaseMaterial3D.TEXTURE_FILTER_NEAREST
|
||||
material.albedo_texture = viewport.get_texture()
|
||||
backing.material_override = material
|
||||
add_child(backing)
|
||||
visible = false
|
||||
|
||||
|
||||
func set_entries(value: Array, title: String) -> void:
|
||||
if entries == value and heading == title:
|
||||
return
|
||||
entries = value.duplicate(true)
|
||||
heading = title
|
||||
_redraw()
|
||||
|
||||
|
||||
func choose(stick: Vector2) -> void:
|
||||
# Top = 1, clockwise through 8. Center releases without an action.
|
||||
var next := -1 if stick.length() < 0.45 else posmod(roundi(atan2(stick.x,stick.y) / (TAU / 8.0)),8)
|
||||
if next == selected:
|
||||
return
|
||||
selected = next
|
||||
_redraw()
|
||||
|
||||
|
||||
func _redraw() -> void:
|
||||
content_revision += 1
|
||||
if canvas != null:
|
||||
canvas.queue_redraw()
|
||||
viewport.render_target_update_mode = SubViewport.UPDATE_ONCE
|
||||
|
||||
|
||||
class WheelCanvas extends Control:
|
||||
var wheel: Node3D
|
||||
const CENTER := Vector2(360,353)
|
||||
|
||||
|
||||
func _sector(angle: float) -> PackedVector2Array:
|
||||
var points := PackedVector2Array()
|
||||
var half := TAU / 16.0 - .025
|
||||
for j in range(13):
|
||||
var a := angle - half + (half * 2) * j / 12.0
|
||||
points.append(CENTER + Vector2(sin(a),-cos(a)) * 326)
|
||||
for j in range(12,-1,-1):
|
||||
var a := angle - half + (half * 2) * j / 12.0
|
||||
points.append(CENTER + Vector2(sin(a),-cos(a)) * 129)
|
||||
return points
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
for i in range(8):
|
||||
var enabled: bool = i < wheel.entries.size() and bool(wheel.entries[i].get("enabled",true))
|
||||
var active: bool = wheel.selected == i and enabled
|
||||
var angle := i * TAU / 8.0
|
||||
var outline := _sector(angle)
|
||||
draw_colored_polygon(outline,UI.SELECTED if active else UI.PANEL if enabled else UI.DARK)
|
||||
outline.append(outline[0])
|
||||
draw_polyline(outline,UI.GOLD if active else UI.EDGE if enabled else UI.MUTED,1.5,false)
|
||||
var center := CENTER + Vector2(sin(angle),-cos(angle)) * 225
|
||||
UI.centered_text(self,str(i + 1),center + Vector2(0,-22),38,UI.GOLD if active else UI.GREEN if enabled else UI.MUTED,"header")
|
||||
var label := str(wheel.entries[i].get("label","")) if i < wheel.entries.size() else "-"
|
||||
var lines := label.replace("\n"," ").split(" ",false)
|
||||
var current := ""
|
||||
var wrapped: Array[String] = []
|
||||
for word in lines:
|
||||
if current.length() + word.length() + 1 > 12 and current != "":
|
||||
wrapped.append(current)
|
||||
current = ""
|
||||
current = word if current == "" else current + " " + word
|
||||
if current != "": wrapped.append(current)
|
||||
for line in range(mini(3,wrapped.size())):
|
||||
UI.centered_text(self,wrapped[line],center + Vector2(0,11 + line * 21),24,UI.INK if enabled else UI.MUTED)
|
||||
UI.frame(self,Rect2(CENTER - Vector2(102,56),Vector2(204,112)),UI.DARK,UI.EDGE,17)
|
||||
var titles := str(wheel.heading).split("\n")
|
||||
for i in range(titles.size()):
|
||||
UI.centered_text(self,titles[i],CENTER + Vector2(0,(i - (titles.size() - 1) * .5) * 29),25,UI.INK,"header")
|
||||
UI.frame(self,Rect2(38,700,644,88),UI.DARK,UI.EDGE,12)
|
||||
UI.centered_text(self,"STICK: CHOOSE RELEASE BUMPER: CONFIRM",Vector2(360,727),24,UI.INK)
|
||||
UI.centered_text(self,"A: CATEGORY B / CENTER: CANCEL",Vector2(360,760),24,UI.MUTED)
|
||||
Reference in new issue
Block a user