Zmany
This commit is contained in:
parent
458db974c0
commit
9aa2dfebd6
BIN
assets/sounds/music/menu_music2.mp3
Normal file
BIN
assets/sounds/music/menu_music2.mp3
Normal file
Binary file not shown.
19
assets/sounds/music/menu_music2.mp3.import
Normal file
19
assets/sounds/music/menu_music2.mp3.import
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://nscqyrjfn7u4"
|
||||||
|
path="res://.godot/imported/menu_music2.mp3-7efdba0b08e1c22b65cc3d25ef9b8f90.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sounds/music/menu_music2.mp3"
|
||||||
|
dest_files=["res://.godot/imported/menu_music2.mp3-7efdba0b08e1c22b65cc3d25ef9b8f90.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
||||||
[ext_resource type="Script" uid="uid://bpaiuqwsxswii" path="res://scripts/abilities/afterburner_ability.gd" id="2"]
|
[ext_resource type="Script" uid="uid://bpaiuqwsxswii" path="res://scripts/abilities/afterburner_ability.gd" id="2"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://kukr8bhgqa7p" path="res://assets/icons/afterburner.png" id="icon"]
|
||||||
[ext_resource type="Texture2D" path="res://assets/icons/afterburner.png" id="icon"]
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Ability"]
|
[sub_resource type="Resource" id="Ability"]
|
||||||
script = ExtResource("2")
|
script = ExtResource("2")
|
||||||
@ -12,9 +11,9 @@ description = "Szybko rozpędza do 300% zwykłej prędkości (+200%), następnie
|
|||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
icon = ExtResource("icon")
|
|
||||||
item_id = "afterburner"
|
item_id = "afterburner"
|
||||||
display_name = "Dopalacz"
|
display_name = "Dopalacz"
|
||||||
|
icon = ExtResource("icon")
|
||||||
category = 5
|
category = 5
|
||||||
description = "Aktywne rozszerzenie silnika."
|
description = "Aktywne rozszerzenie silnika."
|
||||||
active_ability = SubResource("Ability")
|
active_ability = SubResource("Ability")
|
||||||
|
|||||||
@ -1,19 +1,22 @@
|
|||||||
[gd_resource type="Resource" script_class="ItemDefinition" load_steps=5 format=3]
|
[gd_resource type="Resource" script_class="ItemDefinition" format=3 uid="uid://drdg44cvejr2n"]
|
||||||
[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
||||||
[ext_resource type="Texture2D" path="res://assets/icons/extensions/cloak_art.png" id="icon"]
|
[ext_resource type="Script" uid="uid://mjofjrs3v7by" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://ddqhcasuuecgc" path="res://assets/icons/extensions/cloak_art.png" id="icon"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Ability"]
|
[sub_resource type="Resource" id="Ability"]
|
||||||
script = ExtResource("2")
|
script = ExtResource("2")
|
||||||
|
kind = 1
|
||||||
ability_id = "cloak"
|
ability_id = "cloak"
|
||||||
cooldown = 60.0
|
cooldown = 60.0
|
||||||
display_name = "Kamuflaż"
|
display_name = "Kamuflaż"
|
||||||
description = "Przez 10 s statek staje się niemal niewidoczny. Przeciwnicy nie wykrywają go ani nie śledzą. Oddanie strzału przerywa kamuflaż. Nie zapewnia odporności na już wystrzelone pociski. Odnowienie: 60 s."
|
description = "Przez 10 s statek staje się niemal niewidoczny. Przeciwnicy nie wykrywają go ani nie śledzą. Oddanie strzału przerywa kamuflaż. Nie zapewnia odporności na już wystrzelone pociski. Odnowienie: 60 s."
|
||||||
kind = 1
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
icon = ExtResource("icon")
|
|
||||||
item_id = "cloak"
|
item_id = "cloak"
|
||||||
display_name = "Kamuflaż"
|
display_name = "Kamuflaż"
|
||||||
|
icon = ExtResource("icon")
|
||||||
category = 5
|
category = 5
|
||||||
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
||||||
active_ability = SubResource("Ability")
|
active_ability = SubResource("Ability")
|
||||||
|
|||||||
@ -1,19 +1,22 @@
|
|||||||
[gd_resource type="Resource" script_class="ItemDefinition" load_steps=5 format=3]
|
[gd_resource type="Resource" script_class="ItemDefinition" format=3 uid="uid://cvauqvsl4x5gk"]
|
||||||
[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
||||||
[ext_resource type="Texture2D" path="res://assets/icons/extensions/combat_drones_art.png" id="icon"]
|
[ext_resource type="Script" uid="uid://mjofjrs3v7by" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://huejfa7inar0" path="res://assets/icons/extensions/combat_drones_art.png" id="icon"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Ability"]
|
[sub_resource type="Resource" id="Ability"]
|
||||||
script = ExtResource("2")
|
script = ExtResource("2")
|
||||||
|
kind = 5
|
||||||
ability_id = "combat_drones"
|
ability_id = "combat_drones"
|
||||||
cooldown = 30.0
|
cooldown = 30.0
|
||||||
display_name = "Drony bojowe"
|
display_name = "Drony bojowe"
|
||||||
description = "Wypuszcza 3 drony na 10 s. Strzelają działkami mechanicznymi; łącznie zadają 50% DPS statku w momencie startu. Koszt: 50 szt. zwykłej amunicji. Odnowienie: 30 s."
|
description = "Wypuszcza 3 drony na 10 s. Strzelają działkami mechanicznymi; łącznie zadają 50% DPS statku w momencie startu. Koszt: 50 szt. zwykłej amunicji. Odnowienie: 30 s."
|
||||||
kind = 5
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
icon = ExtResource("icon")
|
|
||||||
item_id = "combat_drones"
|
item_id = "combat_drones"
|
||||||
display_name = "Drony bojowe"
|
display_name = "Drony bojowe"
|
||||||
|
icon = ExtResource("icon")
|
||||||
category = 5
|
category = 5
|
||||||
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
||||||
active_ability = SubResource("Ability")
|
active_ability = SubResource("Ability")
|
||||||
|
|||||||
@ -1,19 +1,22 @@
|
|||||||
[gd_resource type="Resource" script_class="ItemDefinition" load_steps=5 format=3]
|
[gd_resource type="Resource" script_class="ItemDefinition" format=3 uid="uid://demqfp0to5pnx"]
|
||||||
[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
||||||
[ext_resource type="Texture2D" path="res://assets/icons/extensions/flares_art.png" id="icon"]
|
[ext_resource type="Script" uid="uid://mjofjrs3v7by" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://ccdxl4xyjwyg3" path="res://assets/icons/extensions/flares_art.png" id="icon"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Ability"]
|
[sub_resource type="Resource" id="Ability"]
|
||||||
script = ExtResource("2")
|
script = ExtResource("2")
|
||||||
|
kind = 3
|
||||||
ability_id = "flares"
|
ability_id = "flares"
|
||||||
cooldown = 30.0
|
cooldown = 30.0
|
||||||
display_name = "Flary"
|
display_name = "Flary"
|
||||||
description = "Wypuszcza trzy flary na 10 s. Wrogowie w zasięgu obierają je za cel zamiast gracza. Odnowienie: 30 s."
|
description = "Wypuszcza trzy flary na 10 s. Wrogowie w zasięgu obierają je za cel zamiast gracza. Odnowienie: 30 s."
|
||||||
kind = 3
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
icon = ExtResource("icon")
|
|
||||||
item_id = "flares"
|
item_id = "flares"
|
||||||
display_name = "Flary"
|
display_name = "Flary"
|
||||||
|
icon = ExtResource("icon")
|
||||||
category = 5
|
category = 5
|
||||||
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
||||||
active_ability = SubResource("Ability")
|
active_ability = SubResource("Ability")
|
||||||
|
|||||||
@ -1,19 +1,22 @@
|
|||||||
[gd_resource type="Resource" script_class="ItemDefinition" load_steps=5 format=3]
|
[gd_resource type="Resource" script_class="ItemDefinition" format=3 uid="uid://cnlcstlicfthn"]
|
||||||
[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
||||||
[ext_resource type="Texture2D" path="res://assets/icons/extensions/mine_art.png" id="icon"]
|
[ext_resource type="Script" uid="uid://mjofjrs3v7by" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dwv0fw3dyupj3" path="res://assets/icons/extensions/mine_art.png" id="icon"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Ability"]
|
[sub_resource type="Resource" id="Ability"]
|
||||||
script = ExtResource("2")
|
script = ExtResource("2")
|
||||||
|
kind = 2
|
||||||
ability_id = "mine_layer"
|
ability_id = "mine_layer"
|
||||||
cooldown = 5.0
|
cooldown = 5.0
|
||||||
display_name = "Miny"
|
display_name = "Miny"
|
||||||
description = "Zostawia minę na 60 s. Uzbraja się po 0,7 s. Trafiony wróg otrzymuje obrażenia równe 5% maksymalnego kadłuba (bez redukcji absorpcji) i zwalnia o 50% na 5 s. Zrzut co 5 s."
|
description = "Zostawia minę na 60 s. Uzbraja się po 0,7 s. Trafiony wróg otrzymuje obrażenia równe 5% maksymalnego kadłuba (bez redukcji absorpcji) i zwalnia o 50% na 5 s. Zrzut co 5 s."
|
||||||
kind = 2
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
icon = ExtResource("icon")
|
|
||||||
item_id = "mine_layer"
|
item_id = "mine_layer"
|
||||||
display_name = "Miny"
|
display_name = "Miny"
|
||||||
|
icon = ExtResource("icon")
|
||||||
category = 5
|
category = 5
|
||||||
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
||||||
active_ability = SubResource("Ability")
|
active_ability = SubResource("Ability")
|
||||||
|
|||||||
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
||||||
[ext_resource type="Script" uid="uid://bgofku10gduus" path="res://scripts/abilities/repair_drones_ability.gd" id="2"]
|
[ext_resource type="Script" uid="uid://bgofku10gduus" path="res://scripts/abilities/repair_drones_ability.gd" id="2"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://b1v55dh3vgl78" path="res://assets/icons/repair_drones.png" id="icon"]
|
||||||
[ext_resource type="Texture2D" path="res://assets/icons/repair_drones.png" id="icon"]
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Ability"]
|
[sub_resource type="Resource" id="Ability"]
|
||||||
script = ExtResource("2")
|
script = ExtResource("2")
|
||||||
@ -12,9 +11,9 @@ description = "Naprawiają tyle kadłuba, ile pozwalają części i brakujące p
|
|||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
icon = ExtResource("icon")
|
|
||||||
item_id = "repair_drones"
|
item_id = "repair_drones"
|
||||||
display_name = "Drony naprawcze"
|
display_name = "Drony naprawcze"
|
||||||
|
icon = ExtResource("icon")
|
||||||
category = 5
|
category = 5
|
||||||
description = "Aktywne rozszerzenie naprawcze."
|
description = "Aktywne rozszerzenie naprawcze."
|
||||||
active_ability = SubResource("Ability")
|
active_ability = SubResource("Ability")
|
||||||
|
|||||||
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
||||||
[ext_resource type="Script" uid="uid://bwka1dwxq64sl" path="res://scripts/abilities/shield_charge_ability.gd" id="2"]
|
[ext_resource type="Script" uid="uid://bwka1dwxq64sl" path="res://scripts/abilities/shield_charge_ability.gd" id="2"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bckqak06f6qxc" path="res://assets/icons/shield_charge.png" id="icon"]
|
||||||
[ext_resource type="Texture2D" path="res://assets/icons/shield_charge.png" id="icon"]
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Ability"]
|
[sub_resource type="Resource" id="Ability"]
|
||||||
script = ExtResource("2")
|
script = ExtResource("2")
|
||||||
@ -12,9 +11,9 @@ description = "Przywraca 100 punktów tarcz, do ich maksimum. Wymaga i zużywa 1
|
|||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
icon = ExtResource("icon")
|
|
||||||
item_id = "shield_charge"
|
item_id = "shield_charge"
|
||||||
display_name = "Ładowanie tarcz"
|
display_name = "Ładowanie tarcz"
|
||||||
|
icon = ExtResource("icon")
|
||||||
category = 5
|
category = 5
|
||||||
description = "Aktywne rozszerzenie tarcz."
|
description = "Aktywne rozszerzenie tarcz."
|
||||||
active_ability = SubResource("Ability")
|
active_ability = SubResource("Ability")
|
||||||
|
|||||||
@ -1,19 +1,22 @@
|
|||||||
[gd_resource type="Resource" script_class="ItemDefinition" load_steps=5 format=3]
|
[gd_resource type="Resource" script_class="ItemDefinition" format=3 uid="uid://x5cduw4c4tes"]
|
||||||
[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
||||||
[ext_resource type="Texture2D" path="res://assets/icons/extensions/solar_shield_charge_art.png" id="icon"]
|
[ext_resource type="Script" uid="uid://mjofjrs3v7by" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://jemfbex10v14" path="res://assets/icons/extensions/solar_shield_charge_art.png" id="icon"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Ability"]
|
[sub_resource type="Resource" id="Ability"]
|
||||||
script = ExtResource("2")
|
script = ExtResource("2")
|
||||||
|
kind = 4
|
||||||
ability_id = "solar_shield_charge"
|
ability_id = "solar_shield_charge"
|
||||||
cooldown = 30.0
|
cooldown = 30.0
|
||||||
display_name = "Doładowanie tarcz"
|
display_name = "Doładowanie tarcz"
|
||||||
description = "W zasięgu gwiazdy przywraca 20% maksymalnych tarcz na sekundę przez maksymalnie 5 s. Opuszczenie zasięgu kończy efekt. Odnowienie: 30 s."
|
description = "W zasięgu gwiazdy przywraca 20% maksymalnych tarcz na sekundę przez maksymalnie 5 s. Opuszczenie zasięgu kończy efekt. Odnowienie: 30 s."
|
||||||
kind = 4
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
icon = ExtResource("icon")
|
|
||||||
item_id = "solar_shield_charge"
|
item_id = "solar_shield_charge"
|
||||||
display_name = "Doładowanie tarcz"
|
display_name = "Doładowanie tarcz"
|
||||||
|
icon = ExtResource("icon")
|
||||||
category = 5
|
category = 5
|
||||||
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
||||||
active_ability = SubResource("Ability")
|
active_ability = SubResource("Ability")
|
||||||
|
|||||||
@ -1,19 +1,21 @@
|
|||||||
[gd_resource type="Resource" script_class="ItemDefinition" load_steps=5 format=3]
|
[gd_resource type="Resource" script_class="ItemDefinition" format=3 uid="uid://dt406oym4bd6n"]
|
||||||
[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
[ext_resource type="Script" uid="uid://d2fdtd4wjk7d" path="res://scripts/items/item_definition.gd" id="1"]
|
||||||
[ext_resource type="Texture2D" path="res://assets/icons/extensions/teleport_art.png" id="icon"]
|
[ext_resource type="Script" uid="uid://mjofjrs3v7by" path="res://scripts/abilities/tactical_extension_ability.gd" id="2"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://c8emovr704ky4" path="res://assets/icons/extensions/teleport_art.png" id="icon"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Ability"]
|
[sub_resource type="Resource" id="Ability"]
|
||||||
script = ExtResource("2")
|
script = ExtResource("2")
|
||||||
ability_id = "teleport"
|
ability_id = "teleport"
|
||||||
cooldown = 60.0
|
cooldown = 60.0
|
||||||
display_name = "Teleport"
|
display_name = "Teleport"
|
||||||
description = "Teleportuje w losowe, bezpieczne miejsce systemu. Zużywa całą aktualną energię (wymaga dodatniej energii). Odnowienie: 60 s."
|
description = "Teleportuje w losowe, bezpieczne miejsce systemu. Zużywa całą aktualną energię (wymaga dodatniej energii). Odnowienie: 60 s."
|
||||||
kind = 0
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
icon = ExtResource("icon")
|
|
||||||
item_id = "teleport"
|
item_id = "teleport"
|
||||||
display_name = "Teleport"
|
display_name = "Teleport"
|
||||||
|
icon = ExtResource("icon")
|
||||||
category = 5
|
category = 5
|
||||||
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
description = "Aktywne rozszerzenie statku. Zamontuj w slocie rozszerzeń i użyj przypisanego klawisza 1–5."
|
||||||
active_ability = SubResource("Ability")
|
active_ability = SubResource("Ability")
|
||||||
|
|||||||
@ -1,16 +1,15 @@
|
|||||||
[gd_resource type="Theme" load_steps=3 format=3]
|
[gd_resource type="Theme" format=3 uid="uid://c0tot0b54dn2e"]
|
||||||
|
|
||||||
[ext_resource type="FontFile" path="res://assets/fonts/font2.ttf" id="1_font"]
|
[ext_resource type="FontFile" uid="uid://drp85tpfncq5m" path="res://assets/fonts/font2.ttf" id="1_font"]
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="TooltipShell"]
|
[sub_resource type="StyleBoxFlat" id="TooltipShell"]
|
||||||
bg_color = Color(0.035, 0.055, 0.085, 1)
|
|
||||||
content_margin_left = 2.0
|
content_margin_left = 2.0
|
||||||
content_margin_top = 2.0
|
content_margin_top = 2.0
|
||||||
content_margin_right = 2.0
|
content_margin_right = 2.0
|
||||||
content_margin_bottom = 2.0
|
content_margin_bottom = 2.0
|
||||||
shadow_size = 0
|
bg_color = Color(0.035, 0.055, 0.085, 1)
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
default_font = ExtResource("1_font")
|
default_font = ExtResource("1_font")
|
||||||
TooltipPanel/styles/panel = SubResource("TooltipShell")
|
|
||||||
TooltipLabel/font_sizes/font_size = 11
|
TooltipLabel/font_sizes/font_size = 11
|
||||||
|
TooltipPanel/styles/panel = SubResource("TooltipShell")
|
||||||
|
|||||||
@ -93,10 +93,7 @@ ENERGIA: 100 / 100"
|
|||||||
[node name="ShipEquipmentPanel" parent="HUD/HUDRoot" unique_id=1637844841 instance=ExtResource("5_equipment")]
|
[node name="ShipEquipmentPanel" parent="HUD/HUDRoot" unique_id=1637844841 instance=ExtResource("5_equipment")]
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
offset_left = -270.0
|
offset_left = -270.0
|
||||||
offset_top = 244.0
|
|
||||||
offset_right = -10.0
|
|
||||||
offset_bottom = 422.0
|
offset_bottom = 422.0
|
||||||
grow_vertical = 1
|
|
||||||
|
|
||||||
[node name="ShipInventoryPanel" parent="HUD/HUDRoot" unique_id=1116676462 instance=ExtResource("6_inventory")]
|
[node name="ShipInventoryPanel" parent="HUD/HUDRoot" unique_id=1116676462 instance=ExtResource("6_inventory")]
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[ext_resource type="Script" uid="uid://csjojorlptcs1" path="res://scripts/ui/main_menu.gd" id="1_script"]
|
[ext_resource type="Script" uid="uid://csjojorlptcs1" path="res://scripts/ui/main_menu.gd" id="1_script"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bfc6l14s8iwhp" path="res://assets/background/background_menu.jpg" id="2_background"]
|
[ext_resource type="Texture2D" uid="uid://bfc6l14s8iwhp" path="res://assets/background/background_menu.jpg" id="2_background"]
|
||||||
[ext_resource type="Script" path="res://scripts/game/scene_music_player.gd" id="3_scene_music"]
|
[ext_resource type="Script" uid="uid://dvokq8qdccw37" path="res://scripts/game/scene_music_player.gd" id="3_scene_music"]
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBox_primary"]
|
[sub_resource type="StyleBoxFlat" id="StyleBox_primary"]
|
||||||
content_margin_left = 22.0
|
content_margin_left = 22.0
|
||||||
@ -67,7 +67,7 @@ script = ExtResource("1_script")
|
|||||||
|
|
||||||
[node name="MenuMusic" type="AudioStreamPlayer" parent="." unique_id=784369201]
|
[node name="MenuMusic" type="AudioStreamPlayer" parent="." unique_id=784369201]
|
||||||
script = ExtResource("3_scene_music")
|
script = ExtResource("3_scene_music")
|
||||||
track_path = "res://assets/sounds/music/menu_music.mp3"
|
track_path = "res://assets/sounds/music/menu_music2.mp3"
|
||||||
playback_volume_db = -13.0
|
playback_volume_db = -13.0
|
||||||
|
|
||||||
[node name="Background" type="TextureRect" parent="." unique_id=1339534440]
|
[node name="Background" type="TextureRect" parent="." unique_id=1339534440]
|
||||||
|
|||||||
@ -1,116 +1,88 @@
|
|||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
const SETTLE_TIME := 8.0
|
const PICKUP := preload("res://scripts/items/mineral_pickup.gd")
|
||||||
var _texture: Texture2D
|
|
||||||
var _fragments: Array[Dictionary] = []
|
|
||||||
var _dust: Array[Dictionary] = []
|
|
||||||
var _elapsed := 0.0
|
var _elapsed := 0.0
|
||||||
var _rng := RandomNumberGenerator.new()
|
var _dust: Array[Dictionary] = []
|
||||||
var _dust_color := Color("b4a99a")
|
|
||||||
|
|
||||||
func configure(sprite: Sprite2D) -> void:
|
func configure(sprite: Sprite2D, count: int = 6, mineral: String = "iron") -> void:
|
||||||
_texture = sprite.texture
|
|
||||||
transform = sprite.global_transform
|
transform = sprite.global_transform
|
||||||
var sprite_scale := global_scale
|
var source_scale := scale
|
||||||
scale = Vector2.ONE
|
scale = Vector2.ONE
|
||||||
_rng.randomize()
|
var dimensions := sprite.texture.get_size()
|
||||||
var dimensions := _texture.get_size()
|
var offset := randf()
|
||||||
var grid: Array[Vector2] = []
|
var cracks: Array[PackedVector2Array] = []
|
||||||
for y in 5:
|
for index in count:
|
||||||
for x in 5:
|
var endpoint := _edge_point(offset + float(index) * 4.0 / count) * dimensions
|
||||||
var vertex := Vector2(x, y) * dimensions / 4.0
|
cracks.append(_fracture_edge(endpoint, count))
|
||||||
if x > 0 and x < 4:
|
for index in count:
|
||||||
vertex.x += _rng.randf_range(-0.3, 0.3) * dimensions.x / 4.0
|
# Neighbours share the same jagged fracture, so the pieces fit together.
|
||||||
if y > 0 and y < 4:
|
var start := offset + float(index) * 4.0 / count
|
||||||
vertex.y += _rng.randf_range(-0.3, 0.3) * dimensions.y / 4.0
|
var finish := offset + float(index + 1) * 4.0 / count
|
||||||
grid.append(vertex)
|
var vertices := cracks[index].duplicate()
|
||||||
# Shared jagged cracks keep neighbouring pieces fitted together.
|
for corner in range(int(floor(start)) + 1, int(ceil(finish))):
|
||||||
var horizontal: Array[PackedVector2Array] = []
|
vertices.append(_edge_point(float(corner)) * dimensions)
|
||||||
var vertical: Array[PackedVector2Array] = []
|
var next_crack := cracks[(index + 1) % count]
|
||||||
for y in 5:
|
for vertex_index in range(next_crack.size() - 1, 0, -1):
|
||||||
for x in 4:
|
vertices.append(next_crack[vertex_index])
|
||||||
horizontal.append(_fracture_edge(grid[y * 5 + x], grid[y * 5 + x + 1], y > 0 and y < 4))
|
|
||||||
for y in 4:
|
|
||||||
for x in 5:
|
|
||||||
vertical.append(_fracture_edge(grid[y * 5 + x], grid[(y + 1) * 5 + x], x > 0 and x < 4))
|
|
||||||
for y in 4:
|
|
||||||
for x in 4:
|
|
||||||
var outline := PackedVector2Array()
|
|
||||||
outline.append_array(_edge_vertices(horizontal[y * 4 + x], false))
|
|
||||||
outline.append_array(_edge_vertices(vertical[y * 5 + x + 1], false))
|
|
||||||
outline.append_array(_edge_vertices(horizontal[(y + 1) * 4 + x], true))
|
|
||||||
outline.append_array(_edge_vertices(vertical[y * 5 + x], true))
|
|
||||||
# Rare jagged cracks can cross at a corner. Repair the silhouette once,
|
|
||||||
# rather than submitting an invalid polygon every rendered frame.
|
|
||||||
if Geometry2D.triangulate_polygon(outline).is_empty():
|
|
||||||
outline = Geometry2D.convex_hull(outline)
|
|
||||||
if outline.size() > 1 and outline[0].is_equal_approx(outline[outline.size() - 1]):
|
|
||||||
outline.remove_at(outline.size() - 1)
|
|
||||||
if outline.size() < 3 or Geometry2D.triangulate_polygon(outline).is_empty():
|
|
||||||
continue
|
|
||||||
var center := Vector2.ZERO
|
var center := Vector2.ZERO
|
||||||
for vertex in outline:
|
for vertex in vertices:
|
||||||
center += vertex
|
center += vertex
|
||||||
center /= outline.size()
|
center /= vertices.size()
|
||||||
var origin := (center - dimensions * 0.5) * sprite_scale
|
var fragment_points := PackedVector2Array()
|
||||||
var points := PackedVector2Array()
|
var fragment_uv := PackedVector2Array()
|
||||||
var uv := PackedVector2Array()
|
for vertex in vertices:
|
||||||
for vertex in outline:
|
fragment_points.append((vertex - center) * source_scale)
|
||||||
points.append((vertex - center) * sprite_scale)
|
fragment_uv.append(vertex / dimensions + Vector2(0.5, 0.5))
|
||||||
uv.append(vertex / dimensions)
|
var fragment := Node2D.new()
|
||||||
var direction := origin.normalized() if origin.length_squared() > 0.1 else Vector2.RIGHT
|
fragment.set_script(PICKUP)
|
||||||
_fragments.append({"points": points, "uv": uv, "position": origin,
|
fragment.set("mineral", mineral)
|
||||||
"velocity": direction.rotated(_rng.randf_range(-0.35, 0.35)) * _rng.randf_range(40.0, 95.0),
|
fragment.set("texture", sprite.texture)
|
||||||
"angle": 0.0, "spin": _rng.randf_range(-4.0, 4.0)})
|
fragment.set("points", fragment_points)
|
||||||
var mineral := _texture.resource_path.get_file().get_basename()
|
fragment.set("uv", fragment_uv)
|
||||||
_dust_color = {"iron": Color("be9b75"), "titanium": Color("9ecbe9"), "uranium": Color("a9db71"), "aluminium": Color("d3dce0"), "sulfur": Color("e8cd65")}.get(mineral, Color("b4a99a"))
|
fragment.position = center * source_scale
|
||||||
|
fragment.set("drift", center.normalized() * randf_range(65.0, 115.0))
|
||||||
|
fragment.set("spin", randf_range(-2.5, 2.5))
|
||||||
|
add_child(fragment)
|
||||||
for index in 28:
|
for index in 28:
|
||||||
_dust.append({"direction": Vector2.RIGHT.rotated(_rng.randf_range(0.0, TAU)),
|
_dust.append({"velocity": Vector2.from_angle(randf() * TAU) * randf_range(45.0, 180.0), "size": randf_range(1.0, 3.0)})
|
||||||
"speed": _rng.randf_range(45.0, 210.0), "size": _rng.randf_range(1.0, 3.0)})
|
|
||||||
z_index = 35
|
|
||||||
light_mask = 4
|
light_mask = 4
|
||||||
|
|
||||||
func _fracture_edge(start: Vector2, end: Vector2, jagged: bool) -> PackedVector2Array:
|
func _fracture_edge(endpoint: Vector2, count: int) -> PackedVector2Array:
|
||||||
var edge := PackedVector2Array([start])
|
var edge := PackedVector2Array([Vector2.ZERO])
|
||||||
if jagged:
|
var normal := endpoint.orthogonal().normalized()
|
||||||
var normal := (end - start).orthogonal().normalized()
|
var roughness := endpoint.length() * minf(0.14, 0.65 / count)
|
||||||
var roughness := start.distance_to(end) * 0.13
|
var side := -1.0 if randf() < 0.5 else 1.0
|
||||||
var side := 1.0 if _rng.randf() > 0.5 else -1.0
|
for index in 5:
|
||||||
for index in 3:
|
var along := float(index + 1) / 6.0
|
||||||
var along := (index + 1.0) / 4.0 + _rng.randf_range(-0.05, 0.05)
|
var offset := roughness * sin(along * PI) * side * randf_range(0.6, 1.0)
|
||||||
edge.append(start.lerp(end, along) + normal * roughness * side * _rng.randf_range(0.5, 1.0))
|
edge.append(endpoint * along + normal * offset)
|
||||||
side *= -1.0
|
side *= -1.0
|
||||||
edge.append(end)
|
edge.append(endpoint)
|
||||||
return edge
|
return edge
|
||||||
|
|
||||||
func _edge_vertices(edge: PackedVector2Array, backwards: bool) -> PackedVector2Array:
|
func _edge_point(distance: float) -> Vector2:
|
||||||
var vertices := PackedVector2Array()
|
var t := fposmod(distance, 4.0)
|
||||||
# The next edge supplies the end vertex, avoiding duplicate polygon points.
|
if t < 1.0:
|
||||||
for index in edge.size() - 1:
|
return Vector2(-0.5 + t, -0.5)
|
||||||
vertices.append(edge[edge.size() - 1 - index] if backwards else edge[index])
|
if t < 2.0:
|
||||||
return vertices
|
return Vector2(0.5, -0.5 + t - 1.0)
|
||||||
|
if t < 3.0:
|
||||||
|
return Vector2(0.5 - (t - 2.0), 0.5)
|
||||||
|
return Vector2(-0.5, 0.5 - (t - 3.0))
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
_elapsed += delta
|
_elapsed += delta
|
||||||
for fragment in _fragments:
|
if _elapsed <= 1.0:
|
||||||
fragment.position += fragment.velocity * delta
|
|
||||||
fragment.velocity *= exp(-1.2 * delta)
|
|
||||||
fragment.angle += fragment.spin * delta
|
|
||||||
fragment.spin *= exp(-0.7 * delta)
|
|
||||||
queue_redraw()
|
queue_redraw()
|
||||||
# Leave the settled debris visible without updating it every frame.
|
elif not _dust.is_empty():
|
||||||
if _elapsed >= SETTLE_TIME:
|
|
||||||
_dust.clear()
|
_dust.clear()
|
||||||
set_process(false)
|
queue_redraw()
|
||||||
|
if _elapsed > 1.0 and get_child_count() == 0:
|
||||||
|
queue_free()
|
||||||
|
|
||||||
func _draw() -> void:
|
func _draw() -> void:
|
||||||
for fragment in _fragments:
|
var fade := maxf(0.0, 1.0 - _elapsed)
|
||||||
draw_set_transform(fragment.position, fragment.angle)
|
|
||||||
draw_polygon(fragment.points, PackedColorArray([Color.WHITE]), fragment.uv, _texture)
|
|
||||||
draw_set_transform(Vector2.ZERO)
|
|
||||||
var dust_fade := maxf(0.0, 1.0 - _elapsed / 0.8)
|
|
||||||
for mote in _dust:
|
for mote in _dust:
|
||||||
var travel: Vector2 = mote.direction * mote.speed * (1.0 - exp(-2.0 * _elapsed)) / 2.0
|
draw_circle(mote.velocity * (1.0 - exp(-2.0 * _elapsed)) * 0.5, mote.size, Color(0.7, 0.75, 0.8, fade * 0.65))
|
||||||
draw_circle(travel, mote.size * (1.0 + _elapsed), Color(_dust_color, dust_fade * 0.65))
|
|
||||||
if _elapsed < 0.18:
|
if _elapsed < 0.18:
|
||||||
draw_circle(Vector2.ZERO, 16.0 * (1.0 - _elapsed / 0.18), Color(0.85, 0.9, 1.0, (1.0 - _elapsed / 0.18) * 0.55))
|
draw_circle(Vector2.ZERO, 16.0 * (1.0 - _elapsed / 0.18), Color(0.85, 0.9, 1.0, fade * 0.5))
|
||||||
|
|||||||
@ -4,7 +4,8 @@ const VFX := preload("res://scripts/game/extension_vfx.gd")
|
|||||||
const MINE_TEXTURE := preload("res://assets/icons/extensions/mine_art.png")
|
const MINE_TEXTURE := preload("res://assets/icons/extensions/mine_art.png")
|
||||||
const LIFETIME := 60.0
|
const LIFETIME := 60.0
|
||||||
const ARM_TIME := 0.7
|
const ARM_TIME := 0.7
|
||||||
const TRIGGER_RADIUS := 34.0
|
const TRIGGER_RADIUS := 60.0
|
||||||
|
const BLAST_RADIUS := 140.0
|
||||||
var drift := Vector2.ZERO
|
var drift := Vector2.ZERO
|
||||||
var _age := 0.0
|
var _age := 0.0
|
||||||
var _triggered := false
|
var _triggered := false
|
||||||
@ -27,16 +28,29 @@ func _physics_process(delta: float) -> void:
|
|||||||
if enemy.is_queued_for_deletion() or float(enemy.get("hull")) <= 0.0:
|
if enemy.is_queued_for_deletion() or float(enemy.get("hull")) <= 0.0:
|
||||||
continue
|
continue
|
||||||
if global_position.distance_to(enemy.global_position) <= TRIGGER_RADIUS + float(enemy.call("get_visual_size")) * 0.35:
|
if global_position.distance_to(enemy.global_position) <= TRIGGER_RADIUS + float(enemy.call("get_visual_size")) * 0.35:
|
||||||
|
_detonate()
|
||||||
|
return
|
||||||
|
|
||||||
|
func _detonate() -> void:
|
||||||
|
if _triggered:
|
||||||
|
return
|
||||||
_triggered = true
|
_triggered = true
|
||||||
|
# Resolve the entire blast once; each nearby enemy receives one hit.
|
||||||
|
for enemy in get_tree().get_nodes_in_group("enemies"):
|
||||||
|
if enemy.is_queued_for_deletion() or float(enemy.get("hull")) <= 0.0:
|
||||||
|
continue
|
||||||
|
var hull_radius := float(enemy.call("get_visual_size")) * 0.35
|
||||||
|
if global_position.distance_to(enemy.global_position) <= BLAST_RADIUS + hull_radius:
|
||||||
enemy.call("apply_mine_hit")
|
enemy.call("apply_mine_hit")
|
||||||
var explosion := Node2D.new()
|
var explosion := Node2D.new()
|
||||||
explosion.set_script(preload("res://scripts/game/deployment_flash.gd"))
|
explosion.set_script(preload("res://scripts/game/deployment_flash.gd"))
|
||||||
explosion.set("color", Color("ffbc75"))
|
explosion.set("color", Color("ffbc75"))
|
||||||
explosion.set("blast", true)
|
explosion.set("blast", true)
|
||||||
|
# The shockwave reaches the same radius as the area damage.
|
||||||
|
explosion.scale = Vector2.ONE * (BLAST_RADIUS / 88.0)
|
||||||
explosion.position = position
|
explosion.position = position
|
||||||
get_parent().add_child(explosion)
|
get_parent().add_child(explosion)
|
||||||
queue_free()
|
queue_free()
|
||||||
return
|
|
||||||
|
|
||||||
func _draw() -> void:
|
func _draw() -> void:
|
||||||
var armed := _age >= ARM_TIME
|
var armed := _age >= ARM_TIME
|
||||||
|
|||||||
55
scripts/game/enemy_mine.gd
Normal file
55
scripts/game/enemy_mine.gd
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
extends Node2D
|
||||||
|
|
||||||
|
const ARM_TIME := 0.7
|
||||||
|
const LIFETIME := 60.0
|
||||||
|
const TRIGGER_RADIUS := 54.0
|
||||||
|
var player: CharacterBody2D
|
||||||
|
var drift := Vector2.ZERO
|
||||||
|
var _age := 0.0
|
||||||
|
var _triggered := false
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
add_to_group("enemy_mines")
|
||||||
|
z_index = 12
|
||||||
|
|
||||||
|
func _physics_process(delta: float) -> void:
|
||||||
|
_age += delta
|
||||||
|
position += drift * delta
|
||||||
|
drift = drift.move_toward(Vector2.ZERO, 100.0 * delta)
|
||||||
|
queue_redraw()
|
||||||
|
if _age >= LIFETIME:
|
||||||
|
queue_free()
|
||||||
|
return
|
||||||
|
if _triggered or _age < ARM_TIME or not is_instance_valid(player) or bool(player.get("_is_destroyed")):
|
||||||
|
return
|
||||||
|
if global_position.distance_to(player.global_position) <= TRIGGER_RADIUS:
|
||||||
|
_triggered = true
|
||||||
|
player.call("take_damage", float(player.get("max_hull")) * 0.05, false, DamageTypes.Type.KINETIC)
|
||||||
|
var explosion := Node2D.new()
|
||||||
|
explosion.set_script(preload("res://scripts/game/deployment_flash.gd"))
|
||||||
|
explosion.set("color", Color("ff4265"))
|
||||||
|
explosion.set("blast", true)
|
||||||
|
explosion.position = position
|
||||||
|
get_parent().add_child(explosion)
|
||||||
|
queue_free()
|
||||||
|
|
||||||
|
func _draw() -> void:
|
||||||
|
var armed := _age >= ARM_TIME
|
||||||
|
var pulse := 0.65 + 0.35 * sin(_age * 7.0)
|
||||||
|
var accent := Color("ff4265") if armed else Color("ffb45c")
|
||||||
|
var fade := clampf(LIFETIME - _age, 0.0, 1.0)
|
||||||
|
draw_circle(Vector2.ZERO, 30.0, Color(accent, 0.08 * pulse * fade))
|
||||||
|
var shell := PackedVector2Array()
|
||||||
|
for index in 16:
|
||||||
|
var radius := 24.0 if index % 2 == 0 else 13.0
|
||||||
|
shell.append(Vector2.from_angle(TAU * index / 16.0) * radius)
|
||||||
|
draw_colored_polygon(shell, Color("292236") * Color(1, 1, 1, fade))
|
||||||
|
var outline := shell.duplicate()
|
||||||
|
outline.append(shell[0])
|
||||||
|
draw_polyline(outline, Color(accent, 0.9 * fade), 1.5, true)
|
||||||
|
draw_circle(Vector2.ZERO, 10.0, Color("13101e") * Color(1, 1, 1, fade))
|
||||||
|
draw_arc(Vector2.ZERO, 11.0, 0.0, TAU, 32, Color(accent, fade), 2.0, true)
|
||||||
|
for index in 3:
|
||||||
|
var direction := Vector2.from_angle(-PI * 0.5 + TAU * index / 3.0)
|
||||||
|
draw_line(direction * 4.0, direction * 8.0, Color(accent, pulse * fade), 2.5, true)
|
||||||
|
draw_circle(Vector2.ZERO, 3.0, Color(accent, pulse * fade))
|
||||||
1
scripts/game/enemy_mine.gd.uid
Normal file
1
scripts/game/enemy_mine.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://dgo884psqgnsd
|
||||||
@ -35,6 +35,7 @@ var _shield_visual: Node2D
|
|||||||
var hull := 50.0
|
var hull := 50.0
|
||||||
var _player: CharacterBody2D
|
var _player: CharacterBody2D
|
||||||
var _activated := false
|
var _activated := false
|
||||||
|
var _retreat_mine_rolled := false
|
||||||
var _sprite: Sprite2D
|
var _sprite: Sprite2D
|
||||||
var _weapon_timer := 0.0
|
var _weapon_timer := 0.0
|
||||||
var _slow_remaining := 0.0
|
var _slow_remaining := 0.0
|
||||||
@ -115,10 +116,14 @@ func _physics_process(delta: float) -> void:
|
|||||||
if _activated and to_player.length_squared() > 1.0:
|
if _activated and to_player.length_squared() > 1.0:
|
||||||
var direction := to_player.normalized()
|
var direction := to_player.normalized()
|
||||||
var fleeing := is_retreating()
|
var fleeing := is_retreating()
|
||||||
|
if fleeing and not _retreat_mine_rolled:
|
||||||
|
_retreat_mine_rolled = true
|
||||||
|
if randf() < 0.15:
|
||||||
|
_drop_retreat_mine(to_player.normalized())
|
||||||
var movement := combat_movement(to_player)
|
var movement := combat_movement(to_player)
|
||||||
var desired_rotation := (movement if fleeing else direction).angle() + PI * 0.5
|
var desired_rotation := (movement if fleeing else direction).angle() + PI * 0.5
|
||||||
rotation = rotate_toward(rotation, desired_rotation, turn_speed * delta)
|
rotation = rotate_toward(rotation, desired_rotation, turn_speed * delta)
|
||||||
velocity = velocity.move_toward(movement * approach_speed * (1.35 if fleeing else 1.0) * get_slow_multiplier(), approach_acceleration * get_slow_multiplier() * delta)
|
velocity = velocity.move_toward(movement * approach_speed * (0.5 if fleeing else 1.0) * get_slow_multiplier(), approach_acceleration * get_slow_multiplier() * delta)
|
||||||
if not fleeing and to_player.length() <= weapon_range and _weapon_timer <= 0.0:
|
if not fleeing and to_player.length() <= weapon_range and _weapon_timer <= 0.0:
|
||||||
_fire_plasma(direction)
|
_fire_plasma(direction)
|
||||||
_weapon_timer = get_fire_interval()
|
_weapon_timer = get_fire_interval()
|
||||||
@ -129,7 +134,15 @@ func _physics_process(delta: float) -> void:
|
|||||||
_check_player_collision()
|
_check_player_collision()
|
||||||
|
|
||||||
func is_retreating() -> bool:
|
func is_retreating() -> bool:
|
||||||
return hull < max_hull * 0.5
|
return hull > 0.0 and hull < max_hull * 0.1
|
||||||
|
|
||||||
|
func _drop_retreat_mine(toward_target: Vector2) -> void:
|
||||||
|
var mine := Node2D.new()
|
||||||
|
mine.set_script(preload("res://scripts/game/enemy_mine.gd"))
|
||||||
|
mine.set("player", _player)
|
||||||
|
mine.set("drift", toward_target * 36.0)
|
||||||
|
mine.position = position + toward_target * (get_visual_size() * 0.5 + 16.0)
|
||||||
|
get_parent().add_child.call_deferred(mine)
|
||||||
|
|
||||||
func combat_movement(to_target: Vector2) -> Vector2:
|
func combat_movement(to_target: Vector2) -> Vector2:
|
||||||
var distance := to_target.length()
|
var distance := to_target.length()
|
||||||
@ -175,7 +188,7 @@ func apply_mine_hit() -> void:
|
|||||||
return
|
return
|
||||||
_slow_remaining = 5.0
|
_slow_remaining = 5.0
|
||||||
velocity = velocity.limit_length(approach_speed * 0.5)
|
velocity = velocity.limit_length(approach_speed * 0.5)
|
||||||
take_damage(max_hull * 0.05, false, DamageTypes.Type.KINETIC, true)
|
take_damage(hull * 0.5, false, DamageTypes.Type.KINETIC, true)
|
||||||
|
|
||||||
func _check_player_collision() -> void:
|
func _check_player_collision() -> void:
|
||||||
for collision_index in get_slide_collision_count():
|
for collision_index in get_slide_collision_count():
|
||||||
|
|||||||
@ -148,6 +148,11 @@ func _ready() -> void:
|
|||||||
_window_manager.call("register_window", _inventory_clip, inventory_panel, inventory_panel.get_node("Contents/Header"))
|
_window_manager.call("register_window", _inventory_clip, inventory_panel, inventory_panel.get_node("Contents/Header"))
|
||||||
$HUDRoot.resized.connect(func() -> void: _layout_sidebar.call_deferred())
|
$HUDRoot.resized.connect(func() -> void: _layout_sidebar.call_deferred())
|
||||||
_create_ability_bar()
|
_create_ability_bar()
|
||||||
|
var objectives := PanelContainer.new()
|
||||||
|
objectives.name = "MissionObjectives"
|
||||||
|
objectives.set_script(preload("res://scripts/ui/mission_objectives.gd"))
|
||||||
|
objectives.set("game", get_parent())
|
||||||
|
$HUDRoot.add_child(objectives)
|
||||||
debug_toggle.pressed.connect(_toggle_debug)
|
debug_toggle.pressed.connect(_toggle_debug)
|
||||||
inventory_button.pressed.connect(_toggle_inventory)
|
inventory_button.pressed.connect(_toggle_inventory)
|
||||||
_update_debug_toggle()
|
_update_debug_toggle()
|
||||||
|
|||||||
@ -400,7 +400,7 @@ func start_boost(speed_bonus: float, acceleration_time: float) -> void:
|
|||||||
|
|
||||||
func get_active_ability(slot_index: int) -> ActiveAbility:
|
func get_active_ability(slot_index: int) -> ActiveAbility:
|
||||||
var item: ItemInstance = $ShipInventory.get_item("extension", slot_index)
|
var item: ItemInstance = $ShipInventory.get_item("extension", slot_index)
|
||||||
return item.definition.active_ability if item != null and item.definition != null else null
|
return item.get_active_ability() if item != null and item.definition != null else null
|
||||||
|
|
||||||
func get_luck_chance() -> float:
|
func get_luck_chance() -> float:
|
||||||
return GameState.captain.get_luck_chance(luck_percent)
|
return GameState.captain.get_luck_chance(luck_percent)
|
||||||
|
|||||||
@ -1,33 +1,35 @@
|
|||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
|
const VORTEX := preload("res://scripts/game/wormhole_vortex.gdshader")
|
||||||
var _time := 0.0
|
var _time := 0.0
|
||||||
|
var _vortex_material: ShaderMaterial
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
z_index = -2
|
z_index = -2
|
||||||
|
light_mask = 4
|
||||||
|
var vortex := ColorRect.new()
|
||||||
|
vortex.name = "Vortex"
|
||||||
|
vortex.position = Vector2(-144, -144)
|
||||||
|
vortex.size = Vector2(288, 288)
|
||||||
|
vortex.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
|
_vortex_material = ShaderMaterial.new()
|
||||||
|
_vortex_material.shader = VORTEX
|
||||||
|
vortex.material = _vortex_material
|
||||||
|
add_child(vortex)
|
||||||
var label := Label.new()
|
var label := Label.new()
|
||||||
|
label.name = "EntryLabel"
|
||||||
label.text = "WORMHOLE\nWleć, aby przejść do następnego układu"
|
label.text = "WORMHOLE\nWleć, aby przejść do następnego układu"
|
||||||
label.position = Vector2(-180, 72)
|
label.position = Vector2(-200, 106)
|
||||||
label.size = Vector2(360, 44)
|
label.size = Vector2(400, 48)
|
||||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
label.add_theme_font_size_override("font_size", 13)
|
label.add_theme_font_size_override("font_size", 13)
|
||||||
label.add_theme_color_override("font_color", Color("89e8ff"))
|
label.add_theme_color_override("font_color", Color("a0e7ff"))
|
||||||
|
label.add_theme_color_override("font_outline_color", Color("030916"))
|
||||||
|
label.add_theme_constant_override("outline_size", 5)
|
||||||
add_child(label)
|
add_child(label)
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
_time += delta
|
_time += delta
|
||||||
queue_redraw()
|
if _vortex_material != null:
|
||||||
|
_vortex_material.set_shader_parameter("elapsed", _time)
|
||||||
func _draw() -> void:
|
|
||||||
var pulse := 1.0 + sin(_time * 2.5) * 0.06
|
|
||||||
for ring in range(6, 0, -1):
|
|
||||||
draw_circle(Vector2.ZERO, (48.0 + ring * 4.0) * pulse, Color(0.28, 0.35, 0.95, 0.025 * (7 - ring)))
|
|
||||||
draw_circle(Vector2.ZERO, 43.0, Color("040917"))
|
|
||||||
for arm in 3:
|
|
||||||
var points := PackedVector2Array()
|
|
||||||
for segment in 65:
|
|
||||||
var progress := segment / 64.0
|
|
||||||
var angle := progress * TAU * 1.3 + _time * 1.6 + TAU * arm / 3.0
|
|
||||||
points.append(Vector2.RIGHT.rotated(angle) * (8.0 + progress * 44.0) * pulse)
|
|
||||||
draw_polyline(points, Color(0.35 + arm * 0.12, 0.55, 1.0, 0.8), 3.0, true)
|
|
||||||
draw_arc(Vector2.ZERO, 49.0 * pulse, 0, TAU, 96, Color("8beaff"), 2.0, true)
|
|
||||||
|
|||||||
62
scripts/game/wormhole_vortex.gdshader
Normal file
62
scripts/game/wormhole_vortex.gdshader
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
shader_type canvas_item;
|
||||||
|
render_mode unshaded;
|
||||||
|
|
||||||
|
uniform float elapsed = 0.0;
|
||||||
|
|
||||||
|
float hash(vec2 p) {
|
||||||
|
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
||||||
|
}
|
||||||
|
float noise(vec2 p) {
|
||||||
|
vec2 i = floor(p);
|
||||||
|
vec2 f = fract(p);
|
||||||
|
f = f * f * (3.0 - 2.0 * f);
|
||||||
|
return mix(mix(hash(i), hash(i + vec2(1, 0)), f.x),
|
||||||
|
mix(hash(i + vec2(0, 1)), hash(i + vec2(1, 1)), f.x), f.y);
|
||||||
|
}
|
||||||
|
float turbulence(vec2 p) {
|
||||||
|
return noise(p) * 0.55 + noise(p * 2.07) * 0.28 + noise(p * 4.13) * 0.17;
|
||||||
|
}
|
||||||
|
void fragment() {
|
||||||
|
vec2 p = (UV - 0.5) * 2.0;
|
||||||
|
float r = length(p);
|
||||||
|
float a = atan(p.y, p.x);
|
||||||
|
float t = elapsed;
|
||||||
|
float reveal = smoothstep(0.0, 1.2, t);
|
||||||
|
float pulse = 1.0 + 0.012 * sin(t * 2.1);
|
||||||
|
float radius = r / pulse;
|
||||||
|
// Use circular coordinates for seamless turbulent filaments.
|
||||||
|
float twist = a + 2.6 * log(max(radius, 0.035)) - t * 0.65;
|
||||||
|
vec2 flow = vec2(cos(twist), sin(twist));
|
||||||
|
float clouds = turbulence(flow * 5.0 + vec2(radius * 13.0, -t * 0.3));
|
||||||
|
float filaments = pow(max(0.0, sin(twist * 7.0 + clouds * 5.0)), 5.0);
|
||||||
|
float disc = exp(-pow((radius - 0.46) / 0.125, 2.0));
|
||||||
|
float rim_r = 0.432 + 0.008 * sin(a * 6.0 - t * 1.4) + (clouds - 0.5) * 0.017;
|
||||||
|
float rim = exp(-abs(radius - rim_r) * 170.0);
|
||||||
|
float bloom = exp(-abs(radius - rim_r) * 25.0);
|
||||||
|
float halo = exp(-pow(radius / 0.66, 4.0));
|
||||||
|
vec3 cyan = vec3(0.16, 0.73, 1.0);
|
||||||
|
vec3 violet = vec3(0.40, 0.15, 0.93);
|
||||||
|
vec3 tint = mix(violet, cyan, 0.5 + 0.5 * sin(twist * 2.0 + t * 0.3));
|
||||||
|
vec3 color = tint * disc * (0.18 + clouds * 0.55 + filaments * 0.85);
|
||||||
|
color += cyan * bloom * 0.3 + vec3(0.63, 0.92, 1.0) * rim * 1.5;
|
||||||
|
color += violet * halo * 0.055;
|
||||||
|
// A dark throat with contracting spiral bands suggests a deep tunnel.
|
||||||
|
float inside = 1.0 - smoothstep(0.37, 0.425, radius);
|
||||||
|
float depth = -log(max(radius / 0.425, 0.015));
|
||||||
|
float tunnel = pow(max(0.0, sin(depth * 16.0 - t * 3.3 + a * 2.0)), 12.0);
|
||||||
|
float throat_fade = smoothstep(0.035, 0.3, radius);
|
||||||
|
vec3 throat = vec3(0.003, 0.006, 0.026);
|
||||||
|
throat += mix(violet, cyan, radius / 0.425) * tunnel * throat_fade * 0.22;
|
||||||
|
throat += cyan * pow(max(0.0, sin(twist * 5.0 + clouds * 2.0)), 14.0) * throat_fade * 0.11;
|
||||||
|
color = mix(color, throat, inside);
|
||||||
|
// Orbiting pinpoints and their short luminous trails, outside the event horizon.
|
||||||
|
float orbit_angle = a - t * 0.24;
|
||||||
|
vec2 orbit = vec2(cos(orbit_angle), sin(orbit_angle)) * radius * 43.0;
|
||||||
|
float sparks = pow(turbulence(orbit), 18.0) * 32.0;
|
||||||
|
sparks *= smoothstep(0.45, 0.52, radius) * (1.0 - smoothstep(0.62, 0.86, radius));
|
||||||
|
color += vec3(0.56, 0.83, 1.0) * sparks;
|
||||||
|
float alpha = max(inside, max(disc * (0.5 + clouds * 0.5), bloom * 0.8));
|
||||||
|
alpha = max(alpha, halo * 0.1 + sparks);
|
||||||
|
alpha *= (1.0 - smoothstep(0.84, 0.98, radius)) * reveal;
|
||||||
|
COLOR = vec4(color, clamp(alpha, 0.0, 1.0));
|
||||||
|
}
|
||||||
1
scripts/game/wormhole_vortex.gdshader.uid
Normal file
1
scripts/game/wormhole_vortex.gdshader.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://cintxpcnpffcx
|
||||||
@ -4,12 +4,14 @@ const MINERALS := ["iron", "titanium", "uranium", "aluminium", "sulfur"]
|
|||||||
const NAMES := {"iron": "Żelazo", "titanium": "Tytan", "uranium": "Uran", "aluminium": "Aluminium", "sulfur": "Siarka"}
|
const NAMES := {"iron": "Żelazo", "titanium": "Tytan", "uranium": "Uran", "aluminium": "Aluminium", "sulfur": "Siarka"}
|
||||||
const COLORS := {"iron": Color("c5b5a0"), "titanium": Color("9ecbe9"), "uranium": Color("a9ef83"), "aluminium": Color("dce8ef"), "sulfur": Color("f4d466")}
|
const COLORS := {"iron": Color("c5b5a0"), "titanium": Color("9ecbe9"), "uranium": Color("a9ef83"), "aluminium": Color("dce8ef"), "sulfur": Color("f4d466")}
|
||||||
const IDS := ["parts", "ammunition", "missile", "energy_bank", "irradiated_ammunition"]
|
const IDS := ["parts", "ammunition", "missile", "energy_bank", "irradiated_ammunition"]
|
||||||
|
# Base asteroid yield increased from mean 2 (1-3) to mean 6 (5-7).
|
||||||
|
# Triple mineral costs to preserve base crafts per asteroid; miner remains a bonus.
|
||||||
const DATA := {
|
const DATA := {
|
||||||
"parts": {"name": "Części", "amount": 1, "cost": {"titanium": 1, "iron": 1, "aluminium": 1}},
|
"parts": {"name": "Części", "amount": 1, "cost": {"titanium": 3, "iron": 3, "aluminium": 3}},
|
||||||
"ammunition": {"name": "Amunicja", "amount": 50, "cost": {"titanium": 1, "sulfur": 1}},
|
"ammunition": {"name": "Amunicja", "amount": 50, "cost": {"titanium": 3, "sulfur": 3}},
|
||||||
"missile": {"name": "Rakieta", "amount": 1, "cost": {"iron": 1, "sulfur": 1, "uranium": 1}},
|
"missile": {"name": "Rakieta", "amount": 1, "cost": {"iron": 3, "sulfur": 3, "uranium": 3}},
|
||||||
"energy_bank": {"name": "Powerbank", "amount": 1, "cost": {"iron": 1, "aluminium": 1}},
|
"energy_bank": {"name": "Powerbank", "amount": 1, "cost": {"iron": 3, "aluminium": 3}},
|
||||||
"irradiated_ammunition": {"name": "Amunicja radiacyjna", "amount": 50, "cost": {"titanium": 1, "uranium": 1}},
|
"irradiated_ammunition": {"name": "Amunicja radiacyjna", "amount": 50, "cost": {"titanium": 3, "uranium": 3}},
|
||||||
}
|
}
|
||||||
|
|
||||||
static func icon(id: String) -> Texture2D:
|
static func icon(id: String) -> Texture2D:
|
||||||
|
|||||||
27
scripts/items/extension_cooldowns.gd
Normal file
27
scripts/items/extension_cooldowns.gd
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
extends RefCounted
|
||||||
|
|
||||||
|
const MIN_SECONDS := 5
|
||||||
|
const BASE_SECONDS := 30
|
||||||
|
# Cumulative P(cooldown <= seconds); interpolate exponentially between anchors.
|
||||||
|
const SECONDS := [5, 10, 15, 20, 25, 30]
|
||||||
|
const CHANCES := [0.0002, 0.0015, 0.01, 0.05, 0.25, 1.0]
|
||||||
|
|
||||||
|
static func cumulative_chance(seconds: int) -> float:
|
||||||
|
if seconds < MIN_SECONDS:
|
||||||
|
return 0.0
|
||||||
|
if seconds >= BASE_SECONDS:
|
||||||
|
return 1.0
|
||||||
|
for index in SECONDS.size() - 1:
|
||||||
|
if seconds <= SECONDS[index + 1]:
|
||||||
|
var progress := float(seconds - SECONDS[index]) / float(SECONDS[index + 1] - SECONDS[index])
|
||||||
|
return exp(lerpf(log(CHANCES[index]), log(CHANCES[index + 1]), progress))
|
||||||
|
return 1.0
|
||||||
|
|
||||||
|
static func from_roll(roll: float) -> int:
|
||||||
|
for seconds in range(MIN_SECONDS, BASE_SECONDS):
|
||||||
|
if roll < cumulative_chance(seconds):
|
||||||
|
return seconds
|
||||||
|
return BASE_SECONDS
|
||||||
|
|
||||||
|
static func roll_seconds() -> int:
|
||||||
|
return from_roll(randf())
|
||||||
1
scripts/items/extension_cooldowns.gd.uid
Normal file
1
scripts/items/extension_cooldowns.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://4nswtu72lqfp
|
||||||
@ -49,6 +49,7 @@ static func generate_for_definition(definition: ItemDefinition, level: int, enem
|
|||||||
item.primary_value_override = (item.damage_min + item.damage_max) * 0.5
|
item.primary_value_override = (item.damage_min + item.damage_max) * 0.5
|
||||||
item.energy_regeneration_override = item.definition.energy_regeneration_bonus * scale_factor * randf_range(0.8, 1.2)
|
item.energy_regeneration_override = item.definition.energy_regeneration_bonus * scale_factor * randf_range(0.8, 1.2)
|
||||||
if definition.category == ItemDefinition.Category.ACTIVE_EXTENSION:
|
if definition.category == ItemDefinition.Category.ACTIVE_EXTENSION:
|
||||||
|
item.extension_cooldown = ItemInstance.EXTENSION_COOLDOWNS.roll_seconds()
|
||||||
return item
|
return item
|
||||||
var roll := randf()
|
var roll := randf()
|
||||||
var count := 1 if roll < 0.5 else (2 if roll < 0.75 else (3 if roll < 0.89 else (4 if roll < 0.97 else 5)))
|
var count := 1 if roll < 0.5 else (2 if roll < 0.75 else (3 if roll < 0.89 else (4 if roll < 0.97 else 5)))
|
||||||
|
|||||||
@ -2,6 +2,30 @@ extends Resource
|
|||||||
class_name ItemInstance
|
class_name ItemInstance
|
||||||
|
|
||||||
const ENERGY_REGENERATION_BONUS_MULTIPLIER := 0.5
|
const ENERGY_REGENERATION_BONUS_MULTIPLIER := 0.5
|
||||||
|
const EXTENSION_COOLDOWNS := preload("res://scripts/items/extension_cooldowns.gd")
|
||||||
|
# Exported with the item; old items default to 30 seconds without rerolling.
|
||||||
|
@export_range(5, 30, 1) var extension_cooldown: int = 30
|
||||||
|
var _instance_ability: ActiveAbility
|
||||||
|
|
||||||
|
func get_active_ability() -> ActiveAbility:
|
||||||
|
if definition == null or definition.active_ability == null:
|
||||||
|
return null
|
||||||
|
if definition.category != ItemDefinition.Category.ACTIVE_EXTENSION:
|
||||||
|
return definition.active_ability
|
||||||
|
if _instance_ability != null and _instance_ability.cooldown == clampi(extension_cooldown, 5, 30):
|
||||||
|
return _instance_ability
|
||||||
|
if _instance_ability == null:
|
||||||
|
# Never mutate the shared ability resource in the item definition.
|
||||||
|
_instance_ability = definition.active_ability.duplicate() as ActiveAbility
|
||||||
|
_instance_ability.cooldown = clampi(extension_cooldown, 5, 30)
|
||||||
|
var description := definition.active_ability.description
|
||||||
|
var fixed_cooldown := RegEx.new()
|
||||||
|
fixed_cooldown.compile(" (Odnowienie:|Zrzut co) [0-9]+ s\\.")
|
||||||
|
description = fixed_cooldown.sub(description, "", true)
|
||||||
|
if definition.item_id == "mine_layer":
|
||||||
|
description = "Zostawia minę na 60 s. Uzbraja się po 0,7 s. Wykrywa bliski przelot wroga. Wybuch w promieniu 140 jednostek zadaje każdemu wrogowi 50% aktualnego kadłuba bez redukcji absorpcji (tarcze pochłaniają obrażenia) i spowalnia o 50% na 5 s."
|
||||||
|
_instance_ability.description = description + "\nOdnowienie: %d s." % _instance_ability.cooldown
|
||||||
|
return _instance_ability
|
||||||
|
|
||||||
@export var definition: ItemDefinition
|
@export var definition: ItemDefinition
|
||||||
@export_range(1, 1000, 1) var item_level: int = 1
|
@export_range(1, 1000, 1) var item_level: int = 1
|
||||||
@ -110,7 +134,7 @@ func get_tooltip_text() -> String:
|
|||||||
if definition.category == ItemDefinition.Category.WEAPON:
|
if definition.category == ItemDefinition.Category.WEAPON:
|
||||||
primary_text = "Obrażenia: %s" % get_damage_range_text()
|
primary_text = "Obrażenia: %s" % get_damage_range_text()
|
||||||
elif definition.active_ability != null:
|
elif definition.active_ability != null:
|
||||||
primary_text = definition.active_ability.description
|
primary_text = get_active_ability().description
|
||||||
var lines: Array[String] = [definition.display_name, "%s • Poziom %d" % [get_rarity_name(), item_level], "", definition.description, "", "CECHA GŁÓWNA", primary_text]
|
var lines: Array[String] = [definition.display_name, "%s • Poziom %d" % [get_rarity_name(), item_level], "", definition.description, "", "CECHA GŁÓWNA", primary_text]
|
||||||
if definition.energy_regeneration_bonus > 0.0:
|
if definition.energy_regeneration_bonus > 0.0:
|
||||||
lines.append("Regeneracja generatora: +%.1f /s" % ((energy_regeneration_override if energy_regeneration_override >= 0.0 else definition.energy_regeneration_bonus) * ENERGY_REGENERATION_BONUS_MULTIPLIER))
|
lines.append("Regeneracja generatora: +%.1f /s" % ((energy_regeneration_override if energy_regeneration_override >= 0.0 else definition.energy_regeneration_bonus) * ENERGY_REGENERATION_BONUS_MULTIPLIER))
|
||||||
|
|||||||
48
scripts/items/mineral_pickup.gd
Normal file
48
scripts/items/mineral_pickup.gd
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
extends Node2D
|
||||||
|
|
||||||
|
const PICKUP_RADIUS := 48.0
|
||||||
|
const ATTRACTION_RADIUS := 150.0
|
||||||
|
var mineral := "iron"
|
||||||
|
var texture: Texture2D
|
||||||
|
var points := PackedVector2Array()
|
||||||
|
var uv := PackedVector2Array()
|
||||||
|
var drift := Vector2.ZERO
|
||||||
|
var spin := 0.0
|
||||||
|
var _age := 0.0
|
||||||
|
var _collected := false
|
||||||
|
var _player: CharacterBody2D
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
add_to_group("loot")
|
||||||
|
add_to_group("mineral_pickups")
|
||||||
|
_player = get_tree().current_scene.get_node_or_null("PlayerShip") as CharacterBody2D
|
||||||
|
z_index = 18
|
||||||
|
light_mask = 4
|
||||||
|
|
||||||
|
func _physics_process(delta: float) -> void:
|
||||||
|
_age += delta
|
||||||
|
position += drift * delta
|
||||||
|
drift *= exp(-1.8 * delta)
|
||||||
|
rotation += spin * delta
|
||||||
|
spin *= exp(-0.7 * delta)
|
||||||
|
queue_redraw()
|
||||||
|
if _collected or _age < 0.8 or not is_instance_valid(_player) or bool(_player.get("_is_destroyed")):
|
||||||
|
return
|
||||||
|
var distance := global_position.distance_to(_player.global_position)
|
||||||
|
if distance <= PICKUP_RADIUS:
|
||||||
|
_collected = true
|
||||||
|
GameState.captain.minerals[mineral] = int(GameState.captain.minerals.get(mineral, 0)) + 1
|
||||||
|
GameState.captain.emit_changed()
|
||||||
|
var popup := preload("res://scenes/game/damage_popup.tscn").instantiate() as Label
|
||||||
|
popup.text = "+1 %s" % {"iron": "żelaza", "aluminium": "aluminium", "titanium": "tytanu", "uranium": "uranu", "sulfur": "siarki"}.get(mineral, mineral)
|
||||||
|
popup.set("text_color", Color("c9e8ff"))
|
||||||
|
popup.position = _player.position + Vector2(-40, -50)
|
||||||
|
get_tree().current_scene.add_child.call_deferred(popup)
|
||||||
|
queue_free()
|
||||||
|
elif distance <= ATTRACTION_RADIUS:
|
||||||
|
global_position = global_position.move_toward(_player.global_position, 180.0 * delta)
|
||||||
|
|
||||||
|
func _draw() -> void:
|
||||||
|
if texture == null or points.size() < 3:
|
||||||
|
return
|
||||||
|
draw_polygon(points, PackedColorArray([Color.WHITE]), uv, texture)
|
||||||
1
scripts/items/mineral_pickup.gd.uid
Normal file
1
scripts/items/mineral_pickup.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://cssyy83yo8lss
|
||||||
@ -58,7 +58,7 @@ func _update_label() -> void:
|
|||||||
_label.text = display_name + "\nGwiazda centralna"
|
_label.text = display_name + "\nGwiazda centralna"
|
||||||
_label.add_theme_color_override("font_color", Color("ffdb98"))
|
_label.add_theme_color_override("font_color", Color("ffdb98"))
|
||||||
elif is_protected:
|
elif is_protected:
|
||||||
_label.text = display_name + " — zamieszkana\n" + ("USŁUGI DOSTĘPNE" if is_safe else "POKONAJ WSZYSTKICH WROGÓW")
|
_label.text = display_name + " — zamieszkana" + ("\nUSŁUGI DOSTĘPNE" if is_safe else "")
|
||||||
_label.add_theme_color_override("font_color", Color("77e8bc") if is_safe else Color("ffbd83"))
|
_label.add_theme_color_override("font_color", Color("77e8bc") if is_safe else Color("ffbd83"))
|
||||||
else:
|
else:
|
||||||
_label.text = display_name
|
_label.text = display_name
|
||||||
|
|||||||
@ -121,9 +121,15 @@ func claim() -> bool:
|
|||||||
var summary := ""
|
var summary := ""
|
||||||
var scale := reward_scale()
|
var scale := reward_scale()
|
||||||
if kind == "asteroid":
|
if kind == "asteroid":
|
||||||
var amount := maxi(1, roundi(_rng.randi_range(1, 3) * scale)) + roundi(GameState.captain.get_skill_bonus("miner"))
|
var amount := _rng.randi_range(5, 7) + maxi(0, roundi(GameState.captain.get_skill_bonus("miner")))
|
||||||
GameState.captain.minerals[_mineral] = int(GameState.captain.minerals.get(_mineral, 0)) + amount
|
var debris := Node2D.new()
|
||||||
summary = "+%d %s" % [amount, {"iron": "żelaza", "aluminium": "aluminium", "titanium": "tytanu", "uranium": "uranu", "sulfur": "siarki"}[_mineral]]
|
debris.set_script(ASTEROID_DESTRUCTION)
|
||||||
|
debris.name = "AsteroidDebris"
|
||||||
|
debris.call("configure", _asteroid_sprite, amount, _mineral)
|
||||||
|
get_parent().add_child.call_deferred(debris)
|
||||||
|
set_physics_process(false)
|
||||||
|
queue_free()
|
||||||
|
return true
|
||||||
elif kind == "ruin":
|
elif kind == "ruin":
|
||||||
var xp := roundi(_rng.randi_range(10, 20) * scale)
|
var xp := roundi(_rng.randi_range(10, 20) * scale)
|
||||||
GameState.captain.add_rewards(xp, 0)
|
GameState.captain.add_rewards(xp, 0)
|
||||||
@ -156,13 +162,6 @@ func claim() -> bool:
|
|||||||
popup.position = position + Vector2(-80, -65)
|
popup.position = position + Vector2(-80, -65)
|
||||||
get_parent().add_child.call_deferred(popup)
|
get_parent().add_child.call_deferred(popup)
|
||||||
set_physics_process(false)
|
set_physics_process(false)
|
||||||
if kind == "asteroid" and is_instance_valid(_asteroid_sprite):
|
|
||||||
var debris := Node2D.new()
|
|
||||||
debris.set_script(ASTEROID_DESTRUCTION)
|
|
||||||
debris.name = "AsteroidDebris"
|
|
||||||
debris.call("configure", _asteroid_sprite)
|
|
||||||
# The POI may be destroyed during a physics query; add debris outside it.
|
|
||||||
get_parent().add_child.call_deferred(debris)
|
|
||||||
queue_free()
|
queue_free()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|||||||
@ -9,8 +9,6 @@ var _panel: PanelContainer
|
|||||||
var _contents: VBoxContainer
|
var _contents: VBoxContainer
|
||||||
var _bar: HBoxContainer
|
var _bar: HBoxContainer
|
||||||
var _buttons: Dictionary = {}
|
var _buttons: Dictionary = {}
|
||||||
var _was_paused := false
|
|
||||||
var _owns_pause := false
|
|
||||||
var _refresh_pending := false
|
var _refresh_pending := false
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
@ -78,19 +76,11 @@ func open_management() -> void:
|
|||||||
if bool(player.get("_is_destroyed")):
|
if bool(player.get("_is_destroyed")):
|
||||||
return
|
return
|
||||||
if not _screen.visible:
|
if not _screen.visible:
|
||||||
_was_paused = get_tree().paused
|
|
||||||
_owns_pause = true
|
|
||||||
get_tree().paused = true
|
|
||||||
_screen.show()
|
_screen.show()
|
||||||
_build_management()
|
_build_management()
|
||||||
|
|
||||||
func _close() -> void:
|
func _close() -> void:
|
||||||
if not _captain.skill_offers.is_empty():
|
|
||||||
return
|
|
||||||
_screen.hide()
|
_screen.hide()
|
||||||
if _owns_pause:
|
|
||||||
get_tree().paused = _was_paused
|
|
||||||
_owns_pause = false
|
|
||||||
|
|
||||||
func _build_management() -> void:
|
func _build_management() -> void:
|
||||||
for child in _contents.get_children():
|
for child in _contents.get_children():
|
||||||
@ -103,13 +93,12 @@ func _build_management() -> void:
|
|||||||
var title := _label("AWANS KAPITANA" if choosing else "UMIEJĘTNOŚCI KAPITANA", 25, Color("91dbea"))
|
var title := _label("AWANS KAPITANA" if choosing else "UMIEJĘTNOŚCI KAPITANA", 25, Color("91dbea"))
|
||||||
title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
heading.add_child(title)
|
heading.add_child(title)
|
||||||
if not choosing:
|
|
||||||
var close := Button.new()
|
var close := Button.new()
|
||||||
close.name = "Close"
|
close.name = "Close"
|
||||||
close.text = "WRÓĆ DO LOTU"
|
close.text = "WRÓĆ DO LOTU"
|
||||||
close.pressed.connect(_close)
|
close.pressed.connect(_close)
|
||||||
heading.add_child(close)
|
heading.add_child(close)
|
||||||
_contents.add_child(_label("POZIOM %d · GRA WSTRZYMANA" % _captain.level, 13, Color("91aabd")))
|
_contents.add_child(_label("POZIOM %d" % _captain.level, 13, Color("91aabd")))
|
||||||
if choosing:
|
if choosing:
|
||||||
_contents.add_child(_label("Wybierz jedną umiejętność. Wybór obowiązuje przez całą rozgrywkę.", 16))
|
_contents.add_child(_label("Wybierz jedną umiejętność. Wybór obowiązuje przez całą rozgrywkę.", 16))
|
||||||
var choices := HBoxContainer.new()
|
var choices := HBoxContainer.new()
|
||||||
@ -327,6 +316,4 @@ func _layout() -> void:
|
|||||||
else:
|
else:
|
||||||
_bar.position = Vector2(16, viewport_size.y - 190)
|
_bar.position = Vector2(16, viewport_size.y - 190)
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
|
||||||
if _owns_pause and is_inside_tree():
|
|
||||||
get_tree().paused = _was_paused
|
|
||||||
|
|||||||
@ -24,4 +24,10 @@ func _draw() -> void:
|
|||||||
var warning_color := Color(1.0, 0.32, 0.26, pulse)
|
var warning_color := Color(1.0, 0.32, 0.26, pulse)
|
||||||
draw_rect(Rect2(Vector2(3, 3), size - Vector2(6, 6)), warning_color, false, 3)
|
draw_rect(Rect2(Vector2(3, 3), size - Vector2(6, 6)), warning_color, false, 3)
|
||||||
var warning := "NISKI KADŁUB — %d%%" % roundi(hull / max_hull * 100)
|
var warning := "NISKI KADŁUB — %d%%" % roundi(hull / max_hull * 100)
|
||||||
draw_string(FONT, Vector2(0, 34), warning, HORIZONTAL_ALIGNMENT_CENTER, size.x, 18, warning_color)
|
# Keep the warning below the navigation buttons, including after a resize.
|
||||||
|
var navigation := get_parent().get_node_or_null("TopNavigation") as Control
|
||||||
|
var warning_top := 104.0
|
||||||
|
if is_instance_valid(navigation):
|
||||||
|
warning_top = navigation.get_global_rect().end.y - global_position.y + 12.0
|
||||||
|
var baseline := warning_top + FONT.get_ascent(18)
|
||||||
|
draw_string(FONT, Vector2(0, baseline), warning, HORIZONTAL_ALIGNMENT_CENTER, size.x, 18, warning_color)
|
||||||
|
|||||||
@ -35,7 +35,7 @@ func _draw() -> void:
|
|||||||
if _inventory == null or not is_instance_valid(player) or size.x < 50 or size.y < 50:
|
if _inventory == null or not is_instance_valid(player) or size.x < 50 or size.y < 50:
|
||||||
return
|
return
|
||||||
var outline := PackedVector2Array([Vector2(24, 0), Vector2(size.x - 24, 0), Vector2(size.x, 24), Vector2(size.x, size.y - 12), Vector2(size.x - 12, size.y), Vector2(12, size.y), Vector2(0, size.y - 12), Vector2(0, 24)])
|
var outline := PackedVector2Array([Vector2(24, 0), Vector2(size.x - 24, 0), Vector2(size.x, 24), Vector2(size.x, size.y - 12), Vector2(size.x - 12, size.y), Vector2(12, size.y), Vector2(0, size.y - 12), Vector2(0, 24)])
|
||||||
draw_colored_polygon(outline, Color(0.025, 0.041, 0.063, 1.0))
|
draw_colored_polygon(outline, Color(0.025, 0.041, 0.063, 0.78))
|
||||||
var closed := outline.duplicate()
|
var closed := outline.duplicate()
|
||||||
closed.append(outline[0])
|
closed.append(outline[0])
|
||||||
draw_polyline(closed, Color("376779"), 1.5, true)
|
draw_polyline(closed, Color("376779"), 1.5, true)
|
||||||
|
|||||||
50
scripts/ui/mission_objectives.gd
Normal file
50
scripts/ui/mission_objectives.gd
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
extends PanelContainer
|
||||||
|
|
||||||
|
var game: Node2D
|
||||||
|
var _objective: Label
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
|
var style := StyleBoxFlat.new()
|
||||||
|
style.bg_color = Color(0.025, 0.041, 0.063, 0.72)
|
||||||
|
style.border_color = Color("376779")
|
||||||
|
style.set_border_width_all(1)
|
||||||
|
style.set_corner_radius_all(6)
|
||||||
|
style.set_content_margin_all(12)
|
||||||
|
add_theme_stylebox_override("panel", style)
|
||||||
|
var contents := VBoxContainer.new()
|
||||||
|
contents.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
|
contents.add_theme_constant_override("separation", 6)
|
||||||
|
add_child(contents)
|
||||||
|
var title := Label.new()
|
||||||
|
title.text = "CELE"
|
||||||
|
title.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
|
title.add_theme_font_size_override("font_size", 12)
|
||||||
|
title.add_theme_color_override("font_color", Color("91dbea"))
|
||||||
|
contents.add_child(title)
|
||||||
|
_objective = Label.new()
|
||||||
|
_objective.name = "CurrentObjective"
|
||||||
|
_objective.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
|
_objective.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||||
|
_objective.add_theme_font_size_override("font_size", 11)
|
||||||
|
_objective.add_theme_color_override("font_color", Color("efb568"))
|
||||||
|
contents.add_child(_objective)
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
if not is_instance_valid(game):
|
||||||
|
return
|
||||||
|
if bool(game.get("system_cleared")):
|
||||||
|
_objective.text = "Znajdź zamieszkaną planetę"
|
||||||
|
elif bool(game.get("_boss_spawned")):
|
||||||
|
_objective.text = "Pokonaj bossa"
|
||||||
|
else:
|
||||||
|
_objective.text = "Pokonaj wszystkich wrogów"
|
||||||
|
var cockpit := get_parent().get_node_or_null("Cockpit") as Control
|
||||||
|
var available_width := cockpit.position.x - 24.0 if is_instance_valid(cockpit) else 260.0
|
||||||
|
var panel_width := clampf(available_width, 180.0, 260.0)
|
||||||
|
size.x = panel_width
|
||||||
|
size.y = get_combined_minimum_size().y
|
||||||
|
var bottom: float = (get_parent() as Control).size.y - 12.0
|
||||||
|
if available_width < 180.0 and is_instance_valid(cockpit):
|
||||||
|
bottom = cockpit.position.y - 64.0
|
||||||
|
position = Vector2(12.0, bottom - size.y)
|
||||||
1
scripts/ui/mission_objectives.gd.uid
Normal file
1
scripts/ui/mission_objectives.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://bd8lju10fyxbr
|
||||||
Loading…
x
Reference in New Issue
Block a user