This commit is contained in:
Tomasz Boruc 2026-10-20 20:32:50 +02:00
parent d9b323b3c7
commit 76c40a8395
28 changed files with 420 additions and 26 deletions

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path d="m3 11 17-6 9 6-17 7Z" fill="#efaa61" stroke="#ffd4a2"/><path d="m3 11 9 7v8l-9-7Z" fill="#9b512d" stroke="#f5b778"/><path d="m12 18 17-7v8l-17 7Z" fill="#d48242" stroke="#f5b778"/><path d="m9 8 9 6" stroke="#ffe4bf" stroke-width="2"/></svg>

After

Width:  |  Height:  |  Size: 332 B

View File

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://43c7sinoianv"
path="res://.godot/imported/copper.svg-c4834a0ae790a1aca61a3ea757550082.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/resources/copper.svg"
dest_files=["res://.godot/imported/copper.svg-c4834a0ae790a1aca61a3ea757550082.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path d="M16 2C13 9 5 15 5 21a11 9 0 0 0 22 0c0-6-8-12-11-19Z" fill="#9cbbd0" stroke="#e2f6ff" stroke-width="1.5"/><path d="M16 8c-2 5-7 10-7 13 0 3 3 5 5 5" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round"/><path d="M24 18c2 7-5 11-11 8" fill="none" stroke="#608395" stroke-width="2"/></svg>

After

Width:  |  Height:  |  Size: 395 B

View File

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dhpa3d5vmo1xt"
path="res://.godot/imported/mercury.svg-3546da7d239e034406cb1796c7686f29.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/resources/mercury.svg"
dest_files=["res://.godot/imported/mercury.svg-3546da7d239e034406cb1796c7686f29.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path d="m8 5 15 1 6 11-9 11-14-5-3-11Z" fill="#7eaaa0" stroke="#d2e2d7" stroke-width="1.5"/><path d="m8 5 7 10 8-9M3 12l12 3-9 8m9-8 5 13m-5-13 14 2" fill="none" stroke="#c5d6ca"/><path d="m8 5 7 10 8-9Z" fill="#bfd1c3"/></svg>

After

Width:  |  Height:  |  Size: 311 B

View File

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://iwgmkvim18x7"
path="res://.godot/imported/nickel.svg-74a50f81c6a0062c599a21d76004d8b5.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/resources/nickel.svg"
dest_files=["res://.godot/imported/nickel.svg-74a50f81c6a0062c599a21d76004d8b5.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path d="M15 2 26 12 24 24 12 29 3 19 5 8Z" fill="#7188ac" stroke="#c5deee" stroke-width="1.5"/><path d="m15 2 2 12-5 15M5 8l12 6 9-2M3 19l14-5 7 10" fill="none" stroke="#d1e6f7"/><path d="m15 2 2 12 9-2Z" fill="#c9ddf0"/></svg>

After

Width:  |  Height:  |  Size: 311 B

View File

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d30h5prcd37f1"
path="res://.godot/imported/silicon.svg-47711e837a4f7b234816e567c07748c8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/resources/silicon.svg"
dest_files=["res://.godot/imported/silicon.svg-47711e837a4f7b234816e567c07748c8.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path d="m3 19 16-6 10 6-17 9Z" fill="#555b70" stroke="#c1c4d4"/><path d="m3 13 16-6 10 6-17 9Z" fill="#7e8197" stroke="#d4d6e3"/><path d="m3 7 16-5 10 5-17 8Z" fill="#c0c2cf" stroke="#f0eff7"/><path d="M3 7v6l9 6v-6m17-6v6l-17 6" fill="none" stroke="#e0e1ea"/></svg>

After

Width:  |  Height:  |  Size: 350 B

View File

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b1w6koagwn8x5"
path="res://.godot/imported/tungsten.svg-59167c98018d9a1577b7791d34661e4e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icons/resources/tungsten.svg"
dest_files=["res://.godot/imported/tungsten.svg-59167c98018d9a1577b7791d34661e4e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -25,8 +25,8 @@ func _ready() -> void:
panel.set_anchors_and_offsets_preset(Control.PRESET_CENTER_TOP)
panel.offset_left = -195
panel.offset_right = 195
panel.offset_top = 104
panel.offset_bottom = 174
panel.offset_top = 136
panel.offset_bottom = 206
var ui := preload("res://scripts/planets/freighter_menu.gd")
ui.style(panel,8,0.5)
var column := VBoxContainer.new()

View File

@ -45,8 +45,8 @@ func _create_navigation() -> void:
navigation.set_anchors_and_offsets_preset(Control.PRESET_CENTER_TOP)
navigation.offset_left = -32
navigation.offset_right = 32
navigation.offset_top = 12
navigation.offset_bottom = 92
navigation.offset_top = 44
navigation.offset_bottom = 124
navigation.add_theme_constant_override("separation", 10)
_captain_skills_ui = CanvasLayer.new()
_captain_skills_ui.set_script(preload("res://scripts/ui/captain_skills_ui.gd"))
@ -62,6 +62,14 @@ func _create_navigation() -> void:
func _ready() -> void:
layer = RENDER_LAYERS.HUD
var resource_layer := CanvasLayer.new()
resource_layer.name = "ResourceLedger"
resource_layer.layer = 70
resource_layer.process_mode = Node.PROCESS_MODE_ALWAYS
add_child(resource_layer)
var resource_bar := Control.new()
resource_bar.set_script(preload("res://scripts/ui/resource_bar.gd"))
resource_layer.add_child(resource_bar)
var cursor := Node.new()
cursor.name = "FlightCursor"
cursor.set_script(preload("res://scripts/ui/flight_cursor.gd"))
@ -119,7 +127,7 @@ func _ready() -> void:
func _create_sidebar() -> void:
_captain_panel = $HUDRoot/CaptainPanel
_captain_panel.set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT)
_captain_panel.position = Vector2(12, 12)
_captain_panel.position = Vector2(12, 44)
_captain_panel.size = _captain_panel.get_combined_minimum_size()
_captain_panel.resized.connect(_layout_debug)
_create_system_badge()
@ -213,8 +221,8 @@ func _create_sidebar() -> void:
_sidebar_toggle.set_anchors_and_offsets_preset(Control.PRESET_TOP_RIGHT)
_sidebar_toggle.offset_left = -233
_sidebar_toggle.offset_right = -12
_sidebar_toggle.offset_top = 12
_sidebar_toggle.offset_bottom = 83.5
_sidebar_toggle.offset_top = 44
_sidebar_toggle.offset_bottom = 115.5
_sidebar_toggle.pressed.connect(_toggle_sidebar)
_cockpit = Control.new()
_cockpit.name = "Cockpit"
@ -290,7 +298,7 @@ func _layout_sidebar() -> void:
var scroll := _sidebar.get_node("Scroll") as ScrollContainer
scroll.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
var content_height: float = scroll.get_node("Contents").get_combined_minimum_size().y + 16.0
var available_height := maxf(100.0, $HUDRoot.size.y - 148.0 - _ship_passive_reserved_height)
var available_height := maxf(100.0, $HUDRoot.size.y - 180.0 - _ship_passive_reserved_height)
var panel_scale := minf(EQUIPMENT_UI_SCALE, available_height / content_height)
_sidebar.scale = Vector2.ONE * panel_scale
_sidebar.size = Vector2(maxf(SIDEBAR_WIDTH, _sidebar.get_combined_minimum_size().x), content_height)
@ -307,7 +315,7 @@ func _layout_sidebar() -> void:
_captain_skills_ui.call_deferred("_layout")
_layout_debug()
if not _sidebar.has_meta("floating_window_dragged"):
_sidebar.position = Vector2($HUDRoot.size.x - _sidebar.size.x * _sidebar.scale.x - 8, 136)
_sidebar.position = Vector2($HUDRoot.size.x - _sidebar.size.x * _sidebar.scale.x - 8, 168)
else:
_window_manager.call("clamp_window", _sidebar)
_sidebar.visible = _sidebar_open

View File

@ -2,6 +2,8 @@ extends Node2D
const PICKUP_RADIUS := 48.0
const ATTRACTION_RADIUS := 150.0
const POPUP := preload("res://scenes/game/damage_popup.tscn")
# Retain the texture for the lifetime of the queued canvas draw commands.
const ICON := preload("res://assets/icons/resources/time_crystals.png")
var amount := 0
var _player: CharacterBody2D
var _collected := false
@ -13,8 +15,7 @@ func _ready() -> void:
func _draw() -> void:
for radius in [27.0,22.0,18.0]: draw_circle(Vector2.ZERO,radius,Color(0.42,0.86,1.0,0.07))
var icon := load("res://assets/icons/resources/time_crystals.png") as Texture2D
if icon != null: draw_texture_rect(icon,Rect2(-18,-18,36,36),false)
draw_texture_rect(ICON,Rect2(-18,-18,36,36),false)
func _physics_process(delta: float) -> void:
if _collected or not is_instance_valid(_player) or bool(_player.get("_is_destroyed")): return

View File

@ -1,5 +1,5 @@
extends RefCounted
const HERMIT_CHANCE := 0.35
const HERMIT_CHANCE := 0.70
const CREDITS_PER_LEVEL := 1000
const DEUTER_PER_LEVEL := 1000

View File

@ -21,6 +21,7 @@ var _economy_labels: Dictionary = {}
@onready var _audio: Node = $FreighterAudio
func _ready() -> void:
offset_top = preload("res://scripts/ui/resource_bar.gd").HEIGHT
if captain == null:
captain = GameState.captain
captain.expedition.freighter_rooms["expansion_3"] = "module_storage"

View File

@ -53,7 +53,8 @@ static func has_recruit(profile: Dictionary) -> bool:
static func recruit(profile: Dictionary) -> Dictionary:
var rng := planet_roll(profile, 0x50455253)
var rating := clampi(1 + roundi(clampf(float(profile.get("difficulty", 0)), 0, 1) * 80) + rng.randi_range(0, 19), 1, 100)
var level := clampi(int(profile.get("system_level",1)),1,100)
var rating := rng.randi_range(maxi(1,level-5),mini(100,level+5))
return {"id":str(profile.id)+":crew", "name":FIRST_NAMES[rng.randi_range(0,9)]+" "+LAST_NAMES[rng.randi_range(0,9)], "management":rating, "planet_id":str(profile.id), "planet_name":str(profile.name), "cabin":""}
static func free_cabin(progress: Resource) -> String:

View File

@ -1,5 +1,5 @@
extends RefCounted
const NAMES := {"deposit":"Złoże surowców", "ruins":"Starożytna struktura", "warehouse":"Opuszczony magazyn", "village":"Opuszczona wioska", "cave":"Jaskinia", "deep_deposit":"Głębokie złoże deuteru", "crew":"Domek specjalisty", "hermit":"Pustelnik / Kartograf", "time_engineer":"Inżynier chronalny"}
const NAMES := {"deposit":"Złoże surowców", "ruins":"Starożytna struktura", "warehouse":"Opuszczony magazyn", "village":"Opuszczona wioska", "cave":"Jaskinia", "deep_deposit":"Głębokie złoże deuteru", "crew":"Obóz specjalisty", "hermit":"Pustelnik / Kartograf", "time_engineer":"Inżynier chronalny"}
const STAGES := {
"deposit":["Zbierz odsłonięte minerały", "Wykonaj odwiert", "Wydobądź głęboką żyłę"],
"ruins":["Przeszukaj przedsionek", "Otwórz komorę", "Zbadaj rdzeń"],

View File

@ -37,6 +37,7 @@ var _surface_viewport: SubViewport
func _ready() -> void:
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
offset_top = preload("res://scripts/ui/resource_bar.gd").HEIGHT
mouse_filter = Control.MOUSE_FILTER_STOP
_rng.seed = progress.visit_seed ^ 90317
if planet_texture == null:
@ -53,7 +54,7 @@ func _ready() -> void:
add_child(container)
var viewport := SubViewport.new()
_surface_viewport = viewport
viewport.size = Vector2i(get_viewport_rect().size * SURFACE_RENDER_SCALE)
viewport.size = Vector2i(size * SURFACE_RENDER_SCALE)
viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
viewport.world_2d = World2D.new()
container.add_child(viewport)
@ -128,18 +129,18 @@ func _ready() -> void:
_threat = _telemetry.threat
var back := POI_CARD.button(self, "POWRÓT NA STATEK [L]", func(): _return(true))
back.set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT)
back.position = Vector2(get_viewport_rect().size.x-285, 24)
back.position = Vector2(size.x-285, 24)
back.size.x = 260
var help := UI.panel(self)
help.name = "SurfaceControls"
help.custom_minimum_size.x = 350
help.set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT)
help.position = Vector2(24, get_viewport_rect().size.y-84)
help.position = Vector2(24, size.y-84)
POI_CARD.panel_style(help)
POI_CARD.text(help, "W — ciąg · S — hamuj / wstecz · A/D — obrót\nQ/E — ruch boczny · TAB — dopalanie · F — zbadaj", 13)
var map_frame := UI.panel(self, Vector2(195,195))
map_frame.set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT)
map_frame.position = get_viewport_rect().size-Vector2(220,220)
map_frame.position = size-Vector2(220,220)
var minimap := Control.new()
minimap.set_script(preload("res://scripts/planets/surface_minimap.gd"))
minimap.world = world
@ -403,7 +404,7 @@ func _event_action(action: String) -> void:
func _layout_dialog() -> void:
if not is_instance_valid(_dialog):
return
var view := get_viewport_rect().size
var view := size
var width := minf(450,maxf(280,view.x-32))
var height := minf(600,maxf(180,view.y-48))
_dialog.size = Vector2(width,height)
@ -423,7 +424,7 @@ func _show_colony_poi(message: String) -> void:
art.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
art.custom_minimum_size.y = 170
_choices.add_child(art)
POI_CARD.text(_choices, "GŁĘBOKIE ZŁOŻE / DEUTER" if is_deposit else "DOMEK SPECJALISTY / REKRUTACJA", 15, POI_CARD.GOLD)
POI_CARD.text(_choices, "GŁĘBOKIE ZŁOŻE / DEUTER" if is_deposit else "OBÓZ SPECJALISTY / REKRUTACJA", 15, POI_CARD.GOLD)
if not message.is_empty(): POI_CARD.text(_choices, message, 13, POI_CARD.GOLD)
if is_deposit:
var id := str(progress.active_profile.id)
@ -444,7 +445,7 @@ func _show_colony_poi(message: String) -> void:
build.name = "BuildMiningOutpost"
build.disabled = captain.parts < cost
else:
POI_CARD.text(_choices, "Mieszkaniec domku szuka pracy. Obejrzyj umiejętności i zdecyduj — możesz wrócić później. Koszt zatrudnienia: 1000 kredytów × zarządzanie.", 12)
POI_CARD.text(_choices, "Specjalista z obozu szuka pracy. Obejrzyj umiejętności i zdecyduj — możesz wrócić później. Koszt zatrudnienia: 1000 kredytów × zarządzanie.", 12)
var candidate: Dictionary = network.recruit(progress.active_profile)
var hire_cost: int = network.recruitment_cost(candidate)
POI_CARD.text(_choices, "Rekrutacja: %d kredytów · posiadasz: %d" % [hire_cost, captain.credits], 13, POI_CARD.GOLD)

View File

@ -75,8 +75,8 @@ func _ready() -> void:
if sprite.texture != null and poi.kind != "cave":
sprite.scale = Vector2.ONE * 125.0*BUILDING_SCALE / maxf(sprite.texture.get_width(), sprite.texture.get_height())
sprite.z_index = 10
if poi.kind == "crew":
sprite.set_script(preload("res://scripts/planets/specialist_house.gd"))
if poi.kind == "crew" and sprite.texture != null:
sprite.scale = Vector2.ONE * 170.0 / maxf(sprite.texture.get_width(),sprite.texture.get_height())
add_child(sprite)
_poi_sprites[poi.id] = sprite
var label := Label.new()
@ -163,7 +163,7 @@ func refresh_pois(lander_position: Vector2) -> void:
label.text = "Pustelnik / Kartograf" + (" · mapa kupiona" if owned else ("\n[F] Kup mapę" if lander_position.distance_to(poi.position) <= 150 else ""))
continue
if poi.kind == "crew":
label.text = "Domek specjalisty" + (" · zatrudniono" if poi.complete else ("\n[F] Porozmawiaj" if lander_position.distance_to(poi.position) <= 150 else ""))
label.text = "Obóz specjalisty" + (" · zatrudniono" if poi.complete else ("\n[F] Porozmawiaj" if lander_position.distance_to(poi.position) <= 150 else ""))
continue
var title: String = preload("res://scripts/planets/poi_rules.gd").NAMES[poi.kind]
label.text = title + ((" · zatrudniono" if poi.kind == "crew" else " · zbadano") if poi.complete else ("\n[F] Zbadaj" if lander_position.distance_to(poi.position) <= 150 else ""))

View File

@ -1,5 +1,5 @@
extends RefCounted
const CHANCE := 0.30
const CHANCE := 0.70
const CRYSTALS_PER_LEVEL := 10
const AFFIXES := preload("res://resources/items/affix_database.tres")

View File

@ -124,7 +124,8 @@ func clamp_window(root: Control) -> void:
return
var viewport_size := get_viewport().get_visible_rect().size
var dimensions := root.size * root.get_global_transform().get_scale().abs()
root.global_position = root.global_position.clamp(Vector2(8, 8), (viewport_size - dimensions - Vector2(8, 8)).max(Vector2(8, 8)))
var minimum := Vector2(8, preload("res://scripts/ui/resource_bar.gd").HEIGHT + 8)
root.global_position = root.global_position.clamp(minimum, (viewport_size - dimensions - Vector2(8, 8)).max(minimum))
func _clamp_all() -> void:
for entry in _windows:

117
scripts/ui/resource_bar.gd Normal file
View File

@ -0,0 +1,117 @@
extends Control
const HEIGHT := 32.0
const ENTRIES := [
["credits","Kredyty","svg",Color("efd48e")],
["parts","Części","png",Color("dfded2")],
["deuter","Deuter","svg",Color("9cdeef")],
["time_crystals","Kryształy czasu","png",Color("d4b6ff")],
["iron","Żelazo","png",Color("d3dce0")],
["titanium","Tytan","png",Color("d3dce0")],
["aluminium","Aluminium","png",Color("d3dce0")],
["uranium","Uran","png",Color("d3dce0")],
["sulfur","Siarka","png",Color("d3dce0")],
["silicon","Krzem","svg",Color("d3dce0")],
["copper","Miedź","svg",Color("d3dce0")],
["nickel","Nikiel","svg",Color("d3dce0")],
["tungsten","Wolfram","svg",Color("d3dce0")],
["mercury","Rtęć","svg",Color("d3dce0")]
]
var _row: HBoxContainer
var _labels: Dictionary = {}
var _cells: Dictionary = {}
var _style: StyleBoxFlat
var _elapsed := 0.0
func _ready() -> void:
name = "ResourceBar"
process_mode = Node.PROCESS_MODE_ALWAYS
set_anchors_and_offsets_preset(Control.PRESET_TOP_WIDE)
offset_bottom = HEIGHT
mouse_filter = Control.MOUSE_FILTER_STOP
_style = StyleBoxFlat.new()
_style.bg_color = Color("0a171ff0")
_style.border_color = Color("46666a")
_style.border_width_bottom = 1
_row = HBoxContainer.new()
_row.add_theme_constant_override("separation",8)
_row.mouse_filter = Control.MOUSE_FILTER_PASS
add_child(_row)
for index in ENTRIES.size():
var entry: Array = ENTRIES[index]
var key := str(entry[0])
if index in [4,9]:
var separator := VSeparator.new()
separator.mouse_filter = Control.MOUSE_FILTER_IGNORE
separator.modulate = Color("48636a")
_row.add_child(separator)
var cell := HBoxContainer.new()
cell.name = key.to_pascal_case()
cell.size_flags_horizontal = Control.SIZE_EXPAND_FILL
cell.add_theme_constant_override("separation",4)
cell.mouse_filter = Control.MOUSE_FILTER_PASS
_row.add_child(cell)
var icon := TextureRect.new()
icon.texture = load("res://assets/icons/resources/%s.%s" % [key,entry[2]])
icon.custom_minimum_size = Vector2(18,18)
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
icon.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR
icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
cell.add_child(icon)
var label := Label.new()
label.custom_minimum_size.x = 36
label.add_theme_font_override("font",ThemeDB.fallback_font)
label.add_theme_font_size_override("font_size",11)
label.add_theme_color_override("font_color",entry[3])
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
cell.add_child(label)
_labels[key] = label
_cells[key] = cell
GameState.captain.changed.connect(refresh)
GameState.captain.expedition.changed.connect(refresh)
resized.connect(_layout)
_row.minimum_size_changed.connect(_layout.call_deferred)
refresh()
_layout.call_deferred()
static func compact(value: float) -> String:
if value >= 1000000: return ("%.1fM" % (floorf(value/100000.0)/10.0)).replace(".0M","M")
if value >= 1000: return ("%.1fK" % (floorf(value/100.0)/10.0)).replace(".0K","K")
return str(floori(value))
func refresh() -> void:
if _labels.is_empty(): return
var captain: Resource = GameState.captain
var progress: Resource = captain.expedition
for entry in ENTRIES:
var key := str(entry[0])
var amount := float(captain.minerals.get(key,0))
match key:
"credits": amount = captain.credits
"parts": amount = captain.parts
"deuter": amount = progress.deuter
"time_crystals": amount = progress.time_crystals
var label: Label = _labels[key]
label.text = compact(amount)
var exact := "%.1f" % amount if key == "deuter" else str(floori(amount))
_cells[key].tooltip_text = "%s: %s" % [entry[1],exact]
func _process(delta: float) -> void:
_elapsed += delta
if _elapsed >= 0.25:
_elapsed = 0
refresh()
func _layout() -> void:
if not is_instance_valid(_row): return
var minimum := _row.get_combined_minimum_size()
var available := maxf(1,size.x-24)
var factor := minf(1.0,available/maxf(1,minimum.x))
_row.scale = Vector2.ONE*factor
_row.size = Vector2(available/factor,minimum.y)
_row.position = Vector2(12,(HEIGHT-minimum.y*factor)*0.5)
queue_redraw()
func _draw() -> void:
if _style != null: draw_style_box(_style,Rect2(Vector2.ZERO,size))

View File

@ -0,0 +1 @@
uid://3hrqurqwqdcu

View File

@ -0,0 +1,17 @@
@tool
extends Node
func run_checks() -> Dictionary:
var network := preload("res://scripts/planets/mining_network.gd")
var failures: Array[String] = []
for level in [1,5,20,50,80,100,120]:
var center := clampi(level,1,100)
for seed_value in 1000:
var profile := {"id":"test:%d" % seed_value,"seed":seed_value,"name":"Test","difficulty":1.0,"system_level":level}
var candidate: Dictionary = network.recruit(profile)
if int(candidate.management) < maxi(1,center-5) or int(candidate.management) > mini(100,center+5): failures.append("Out of level bounds")
if candidate != network.recruit(profile): failures.append("Rerolled on revisit")
var safe := profile.duplicate()
safe.difficulty = 0.0
if candidate.management != network.recruit(safe).management: failures.append("Biome changed rating")
if network.recruitment_cost(candidate) != int(candidate.management)*1000: failures.append("Wrong price")
return {"failures":failures,"rolls_checked":7000,"passed":failures.is_empty()}

View File

@ -0,0 +1 @@
uid://lpfj0avxfgt8

View File

@ -0,0 +1,18 @@
extends Node2D
func _ready() -> void:
var background := ColorRect.new()
background.color = Color("0b1826")
background.size = Vector2(1280,720)
add_child(background)
var crystal := Node2D.new()
crystal.set_script(preload("res://scripts/items/time_crystal_pickup.gd"))
crystal.position = Vector2(640,340)
crystal.scale = Vector2.ONE*3
crystal.amount = 10
add_child(crystal)
crystal.set_physics_process(false)
var label := Label.new()
label.text = "KRYSZTAŁY CZASU"
label.position = Vector2(500,440)
label.add_theme_font_size_override("font_size",20)
add_child(label)

View File

@ -0,0 +1 @@
uid://cmhvnvlru1bep

View File

@ -0,0 +1,6 @@
[gd_scene format=3 uid="uid://dr6cwynsabgda"]
[ext_resource type="Script" uid="uid://cmhvnvlru1bep" path="res://tests/time_crystal_visual.gd" id="1_7w67k"]
[node name="time_crystal_visual" type="Node2D" unique_id=651484583]
script = ExtResource("1_7w67k")