Refactor skill components and update resource paths for consistency; enhance skill management in scenes
This commit is contained in:
@@ -1,11 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
var settings_config := ConfigFile.new()
|
|
||||||
const SETTINGS_PATH := "user://settings.ini"
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if !FileAccess.file_exists(SETTINGS_PATH):
|
|
||||||
settings_config.save(SETTINGS_PATH)
|
|
||||||
else:
|
|
||||||
settings_config.load(SETTINGS_PATH)
|
|
@@ -1 +0,0 @@
|
|||||||
uid://dueoywjgtwv7m
|
|
@@ -1,42 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
@export var save_path: String = "user://savegame.save"
|
|
||||||
@export var version: int = 1
|
|
||||||
|
|
||||||
@onready var gm: GM = $"/root/GameManager"
|
|
||||||
|
|
||||||
|
|
||||||
func save_game():
|
|
||||||
var save_data := {
|
|
||||||
"player_state": gm.player_state,
|
|
||||||
"version": version,
|
|
||||||
}
|
|
||||||
var file := FileAccess.open(save_path, FileAccess.WRITE)
|
|
||||||
file.store_var(save_data)
|
|
||||||
file.close()
|
|
||||||
print("Game saved to: ", save_path)
|
|
||||||
|
|
||||||
|
|
||||||
func load_game() -> bool:
|
|
||||||
if not FileAccess.file_exists(save_path):
|
|
||||||
return false
|
|
||||||
var file := FileAccess.open(save_path, FileAccess.READ)
|
|
||||||
var save_data: Dictionary = file.get_var()
|
|
||||||
file.close()
|
|
||||||
|
|
||||||
if save_data.has("version") and save_data["version"] != version:
|
|
||||||
print("Save file version mismatch. Expected: ", version, ", Found: ", save_data["version"])
|
|
||||||
return false
|
|
||||||
print("Game state loaded from: ", save_path)
|
|
||||||
print("Player state: ", save_data["player_state"])
|
|
||||||
gm.player_state = save_data["player_state"]
|
|
||||||
var skills: Array[SkillData] = []
|
|
||||||
for skill in gm.player_state["unlocked_skills"]:
|
|
||||||
skills.append(skill)
|
|
||||||
|
|
||||||
gm.unlock_skills(skills)
|
|
||||||
return true
|
|
||||||
|
|
||||||
|
|
||||||
func check_save_exists() -> bool:
|
|
||||||
return FileAccess.file_exists(save_path)
|
|
@@ -1 +0,0 @@
|
|||||||
uid://d3tgf7fyr6xek
|
|
@@ -1,169 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
## A globally accessible manager for device-specific actions using SteamInput for any controller
|
|
||||||
## and standard Godot Input for the keyboard.
|
|
||||||
##
|
|
||||||
## All methods in this class that have a "device" parameter can accept -1
|
|
||||||
## which means the keyboard device.
|
|
||||||
|
|
||||||
# The actions defined in the Steam .vdf file are listed here
|
|
||||||
# with true or false indicating if input is analog or digital.
|
|
||||||
# False is digital (buttons), true is analog (joysticks, triggers, etc).
|
|
||||||
|
|
||||||
var action_names := {
|
|
||||||
"move": true,
|
|
||||||
"jump": false,
|
|
||||||
"left": false,
|
|
||||||
"right": false,
|
|
||||||
"down": false,
|
|
||||||
"up": false,
|
|
||||||
"interact": false,
|
|
||||||
"pause": false,
|
|
||||||
}
|
|
||||||
|
|
||||||
var got_handles := false
|
|
||||||
var game_action_set
|
|
||||||
var current_action_set
|
|
||||||
var actions := {}
|
|
||||||
# Store the state of each action and the frame it entered that state.
|
|
||||||
var action_states := {}
|
|
||||||
|
|
||||||
|
|
||||||
func init() -> void:
|
|
||||||
Steam.input_device_connected.connect(_on_steam_input_device_connected)
|
|
||||||
Steam.input_device_disconnected.connect(_on_steam_input_device_disconnected)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_steam_input_device_connected(input_handle: int) -> void:
|
|
||||||
if not got_handles:
|
|
||||||
get_handles()
|
|
||||||
|
|
||||||
Steam.activateActionSet(input_handle, current_action_set)
|
|
||||||
print("Device connected %s" % str(input_handle))
|
|
||||||
|
|
||||||
|
|
||||||
func _on_steam_input_device_disconnected(input_handle: int) -> void:
|
|
||||||
print("Device disconnected %s" % str(input_handle))
|
|
||||||
|
|
||||||
|
|
||||||
func get_handles() -> void:
|
|
||||||
got_handles = true
|
|
||||||
game_action_set = Steam.getActionSetHandle("GameControls")
|
|
||||||
current_action_set = game_action_set
|
|
||||||
get_action_handles(action_names)
|
|
||||||
|
|
||||||
|
|
||||||
func get_action_handles(action_names: Dictionary) -> void:
|
|
||||||
for action in action_names.keys():
|
|
||||||
if action_names[action]:
|
|
||||||
actions[action] = Steam.getAnalogActionHandle(action)
|
|
||||||
else:
|
|
||||||
actions[action] = Steam.getDigitalActionHandle(action)
|
|
||||||
|
|
||||||
|
|
||||||
func get_controllers() -> Array[int]:
|
|
||||||
var controllers: Array[int] = [-1]
|
|
||||||
var steam_controllers = Steam.getConnectedControllers()
|
|
||||||
if steam_controllers:
|
|
||||||
controllers.append_array(steam_controllers)
|
|
||||||
|
|
||||||
return controllers
|
|
||||||
|
|
||||||
|
|
||||||
func get_action_strength(device: int, action: StringName, exact_match: bool = false) -> float:
|
|
||||||
if device >= 0:
|
|
||||||
if not got_handles: return 0
|
|
||||||
var action_data = Steam.getAnalogActionData(device, actions[action])
|
|
||||||
return action_data.x
|
|
||||||
return Input.get_action_strength(action, exact_match)
|
|
||||||
|
|
||||||
|
|
||||||
func get_axis(device: int, negative_action: StringName, positive_action: StringName) -> float:
|
|
||||||
if device >= 0:
|
|
||||||
if not got_handles: return 0
|
|
||||||
var negative = Steam.getAnalogActionData(device, actions[negative_action])
|
|
||||||
var positive = Steam.getAnalogActionData(device, actions[positive_action])
|
|
||||||
return positive.x - negative.x
|
|
||||||
return Input.get_axis(negative_action, positive_action)
|
|
||||||
|
|
||||||
|
|
||||||
func get_vector(device: int, negative_x: StringName, positive_x: StringName, negative_y: StringName, positive_y: StringName, deadzone: float = -1.0) -> Vector2:
|
|
||||||
if device >= 0:
|
|
||||||
if not got_handles: return Vector2.ZERO
|
|
||||||
var negative_x_val = Steam.getAnalogActionData(device, actions[negative_x])
|
|
||||||
var positive_x_val = Steam.getAnalogActionData(device, actions[positive_x])
|
|
||||||
var negative_y_val = Steam.getAnalogActionData(device, actions[negative_y])
|
|
||||||
var positive_y_val = Steam.getAnalogActionData(device, actions[positive_y])
|
|
||||||
# Steam's y axis is inverted compared to Godot
|
|
||||||
return Vector2(positive_x_val - negative_x_val, -(positive_y_val - negative_y_val)).normalized()
|
|
||||||
return Input.get_vector(negative_x, positive_x, negative_y, positive_y, deadzone)
|
|
||||||
|
|
||||||
|
|
||||||
func get_move_input(device: int) -> Vector2:
|
|
||||||
if device >= 0:
|
|
||||||
if not got_handles: return Vector2.ZERO
|
|
||||||
# Get the analog stick movement
|
|
||||||
var action_data = Steam.getAnalogActionData(device, actions["Move"])
|
|
||||||
return Vector2(action_data.x, -action_data.y).normalized()
|
|
||||||
return Vector2(Input.get_axis("left", "right"), Input.get_axis("up", "down")).normalized()
|
|
||||||
|
|
||||||
|
|
||||||
func get_action_state(device: int, action: String) -> Dictionary:
|
|
||||||
# Get the current action, but create the defaults along the way if they don't exist.
|
|
||||||
if not action_states.get(device):
|
|
||||||
action_states[device] = {}
|
|
||||||
if not action_states[device].get(action):
|
|
||||||
action_states[device][action] = { "held": false, "press_frame": -1, "release_frame": -1 }
|
|
||||||
return action_states[device][action]
|
|
||||||
|
|
||||||
|
|
||||||
func set_action_state(device: int, action: StringName, currently_held: bool, current_frame: int) -> Dictionary:
|
|
||||||
# Get the state of the action last frame
|
|
||||||
var previous_action_state := get_action_state(device, action)
|
|
||||||
|
|
||||||
# If we're pressing the action now and we weren't pressing it last frame,
|
|
||||||
# track that we pressed the action this frame.
|
|
||||||
if currently_held and not previous_action_state.held:
|
|
||||||
action_states[device][action].held = true
|
|
||||||
action_states[device][action].press_frame = current_frame
|
|
||||||
# If we're not pressing it this frame but we were pressing it last frame,
|
|
||||||
# track that we released the action this frame.
|
|
||||||
elif not currently_held and previous_action_state.held:
|
|
||||||
action_states[device][action].held = false
|
|
||||||
action_states[device][action].release_frame = current_frame
|
|
||||||
|
|
||||||
# Return the current state of the action
|
|
||||||
return action_states[device][action]
|
|
||||||
|
|
||||||
|
|
||||||
func is_action_pressed(device: int, action: StringName, exact_match: bool = false) -> bool:
|
|
||||||
if device >= 0:
|
|
||||||
if not got_handles: return false
|
|
||||||
var current_frame := Engine.get_process_frames()
|
|
||||||
var currently_held = Steam.getDigitalActionData(device, actions[action]).state
|
|
||||||
set_action_state(device, action, currently_held, current_frame)
|
|
||||||
return currently_held
|
|
||||||
# If keyboard, use normal Godot input system.
|
|
||||||
return Input.is_action_pressed(action, exact_match)
|
|
||||||
|
|
||||||
|
|
||||||
func is_action_just_pressed(device: int, action: StringName, exact_match: bool = false) -> bool:
|
|
||||||
if device >= 0:
|
|
||||||
if not got_handles: return false
|
|
||||||
var current_frame := Engine.get_process_frames()
|
|
||||||
var currently_held = Steam.getDigitalActionData(device, actions[action]).state
|
|
||||||
var action_state := set_action_state(device, action, currently_held, current_frame)
|
|
||||||
return currently_held and action_state.press_frame == current_frame
|
|
||||||
# If keyboard, use normal Godot input system.
|
|
||||||
return Input.is_action_just_pressed(action, exact_match)
|
|
||||||
|
|
||||||
|
|
||||||
func is_action_just_released(device: int, action: StringName, exact_match: bool = false) -> bool:
|
|
||||||
if device >= 0:
|
|
||||||
if not got_handles: return false
|
|
||||||
var current_frame := Engine.get_process_frames()
|
|
||||||
var currently_held = Steam.getDigitalActionData(device, actions[action]).state
|
|
||||||
var action_state := set_action_state(device, action, currently_held, current_frame)
|
|
||||||
return not currently_held and action_state.release_frame == current_frame
|
|
||||||
# If keyboard, use normal Godot input system.
|
|
||||||
return Input.is_action_just_released(action, exact_match)
|
|
@@ -1 +0,0 @@
|
|||||||
uid://ctb7ehok6dme3
|
|
@@ -1,54 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
@export var ui_stack: Array[Control] = []
|
|
||||||
signal screen_pushed(screen: Control)
|
|
||||||
signal screen_popped(screen: Control)
|
|
||||||
|
|
||||||
|
|
||||||
func push_screen(screen: Control) -> void:
|
|
||||||
if not screen:
|
|
||||||
push_error("Cannot push a null screen.")
|
|
||||||
return
|
|
||||||
|
|
||||||
ui_stack.append(screen)
|
|
||||||
screen.show()
|
|
||||||
screen.set_process_input(true)
|
|
||||||
screen.set_focus_mode(Control.FOCUS_ALL)
|
|
||||||
screen.grab_focus()
|
|
||||||
screen_pushed.emit(screen)
|
|
||||||
|
|
||||||
|
|
||||||
func pop_screen() -> void:
|
|
||||||
if ui_stack.is_empty():
|
|
||||||
return
|
|
||||||
|
|
||||||
var top: Control = ui_stack.pop_back()
|
|
||||||
top.hide()
|
|
||||||
top.set_process_input(false)
|
|
||||||
screen_popped.emit(top)
|
|
||||||
top.accept_event()
|
|
||||||
|
|
||||||
if not ui_stack.is_empty():
|
|
||||||
ui_stack.back().grab_focus()
|
|
||||||
|
|
||||||
|
|
||||||
func top_screen() -> Control:
|
|
||||||
return ui_stack.back() if not ui_stack.is_empty() else null
|
|
||||||
|
|
||||||
|
|
||||||
func is_screen_on_top(screen: Control) -> bool:
|
|
||||||
return not ui_stack.is_empty() and ui_stack.back() == screen
|
|
||||||
|
|
||||||
|
|
||||||
func is_visible_on_stack(screen: Control) -> bool:
|
|
||||||
return ui_stack.has(screen) and screen.visible
|
|
||||||
|
|
||||||
|
|
||||||
func close_all() -> void:
|
|
||||||
while not ui_stack.is_empty():
|
|
||||||
pop_screen()
|
|
||||||
|
|
||||||
|
|
||||||
func hide_and_disable(screen: Control) -> void:
|
|
||||||
screen.hide()
|
|
||||||
screen.set_process_input(false)
|
|
@@ -1 +0,0 @@
|
|||||||
uid://vmhlsc3fu3bn
|
|
@@ -1,4 +1,4 @@
|
|||||||
[gd_scene load_steps=42 format=3 uid="uid://bqi5s710xb1ju"]
|
[gd_scene load_steps=48 format=3 uid="uid://bqi5s710xb1ju"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://csel4s0e4g5uf" path="res://scripts/components/PlayerController.cs" id="1_yysbb"]
|
[ext_resource type="Script" uid="uid://csel4s0e4g5uf" path="res://scripts/components/PlayerController.cs" id="1_yysbb"]
|
||||||
[ext_resource type="Shader" uid="uid://bs4xvm4qkurpr" path="res://shaders/hit_flash.tres" id="2_lgb3u"]
|
[ext_resource type="Shader" uid="uid://bs4xvm4qkurpr" path="res://shaders/hit_flash.tres" id="2_lgb3u"]
|
||||||
@@ -21,7 +21,13 @@
|
|||||||
[ext_resource type="AudioStream" uid="uid://duj2q0rqytaxg" path="res://sfx/jump.wav" id="18_pysae"]
|
[ext_resource type="AudioStream" uid="uid://duj2q0rqytaxg" path="res://sfx/jump.wav" id="18_pysae"]
|
||||||
[ext_resource type="AudioStream" uid="uid://bmfn6p88gy575" path="res://sfx/player_hurt.wav" id="19_7anly"]
|
[ext_resource type="AudioStream" uid="uid://bmfn6p88gy575" path="res://sfx/player_hurt.wav" id="19_7anly"]
|
||||||
[ext_resource type="Script" uid="uid://dlh5xcv2sy82s" path="res://scripts/components/SkillUnlockedComponent.cs" id="19_gwc8i"]
|
[ext_resource type="Script" uid="uid://dlh5xcv2sy82s" path="res://scripts/components/SkillUnlockedComponent.cs" id="19_gwc8i"]
|
||||||
|
[ext_resource type="Script" uid="uid://d4crrfmbgxnqf" path="res://scripts/Resources/SkillData.cs" id="19_yysbb"]
|
||||||
[ext_resource type="AudioStream" uid="uid://ycgtf6wj7mto" path="res://sfx/heal.wav" id="20_bptj5"]
|
[ext_resource type="AudioStream" uid="uid://ycgtf6wj7mto" path="res://sfx/heal.wav" id="20_bptj5"]
|
||||||
|
[ext_resource type="Resource" uid="uid://dw5ee2lpeypnb" path="res://resources/skills/brick_throw.tres" id="20_o1ihh"]
|
||||||
|
[ext_resource type="Resource" uid="uid://cdp8sex36vdq2" path="res://resources/skills/explosive_brick.tres" id="21_ur2y5"]
|
||||||
|
[ext_resource type="Resource" uid="uid://cr5lo4h8wm0jc" path="res://resources/skills/fire_brick.tres" id="22_7til7"]
|
||||||
|
[ext_resource type="Resource" uid="uid://ceakv6oqob6m7" path="res://resources/skills/ice_brick.tres" id="23_e5pae"]
|
||||||
|
[ext_resource type="Resource" uid="uid://d3bjre2etov1n" path="res://resources/skills/magnetic.tres" id="24_xuhvf"]
|
||||||
[ext_resource type="Script" uid="uid://bo506l4x0808e" path="res://scripts/components/HitComponent.cs" id="26_6n1ss"]
|
[ext_resource type="Script" uid="uid://bo506l4x0808e" path="res://scripts/components/HitComponent.cs" id="26_6n1ss"]
|
||||||
[ext_resource type="Script" uid="uid://cjcc7fia15wu3" path="res://scripts/components/CanBeLaunchedComponent.cs" id="27_oefns"]
|
[ext_resource type="Script" uid="uid://cjcc7fia15wu3" path="res://scripts/components/CanBeLaunchedComponent.cs" id="27_oefns"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bg76mtpcmfm2j" path="res://objects/ui/charging_bar_layer.tscn" id="28_3f5nm"]
|
[ext_resource type="PackedScene" uid="uid://bg76mtpcmfm2j" path="res://objects/ui/charging_bar_layer.tscn" id="28_3f5nm"]
|
||||||
@@ -201,9 +207,11 @@ Root = NodePath("..")
|
|||||||
|
|
||||||
[node name="SkillManager" type="Node" parent="."]
|
[node name="SkillManager" type="Node" parent="."]
|
||||||
script = ExtResource("18_6lsog")
|
script = ExtResource("18_6lsog")
|
||||||
|
AvailableSkills = Array[ExtResource("19_yysbb")]([ExtResource("20_o1ihh"), ExtResource("21_ur2y5"), ExtResource("22_7til7"), ExtResource("23_e5pae"), ExtResource("24_xuhvf")])
|
||||||
|
|
||||||
[node name="SkillUnlockerComponent" type="Node" parent="."]
|
[node name="SkillUnlockerComponent" type="Node" parent="." node_paths=PackedStringArray("SkillManager")]
|
||||||
script = ExtResource("19_gwc8i")
|
script = ExtResource("19_gwc8i")
|
||||||
|
SkillManager = NodePath("../SkillManager")
|
||||||
|
|
||||||
[node name="HitComponent" type="Node" parent="." node_paths=PackedStringArray("Sprite", "Health", "HitFx")]
|
[node name="HitComponent" type="Node" parent="." node_paths=PackedStringArray("Sprite", "Health", "HitFx")]
|
||||||
script = ExtResource("26_6n1ss")
|
script = ExtResource("26_6n1ss")
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://coayig4dxelo2"]
|
[gd_scene load_steps=4 format=3 uid="uid://coayig4dxelo2"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cm06xg1l3xtw5" path="res://scripts/components/brick_throw.gd" id="1_hniwk"]
|
[ext_resource type="Script" uid="uid://b0bv8kw5w5037" path="res://scripts/components/BrickThrowComponent.cs" id="1_ogpnm"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bymro4t7angv5" path="res://objects/entities/brick.tscn" id="2_4txoq"]
|
[ext_resource type="PackedScene" uid="uid://bymro4t7angv5" path="res://objects/entities/brick.tscn" id="2_4txoq"]
|
||||||
[ext_resource type="Resource" uid="uid://br84dsfa3ti04" path="res://resources/throw_behaviors/tap_throw_input.tres" id="3_gxahf"]
|
[ext_resource type="Resource" uid="uid://br84dsfa3ti04" path="res://resources/throw_behaviors/tap_throw_input.tres" id="3_gxahf"]
|
||||||
|
|
||||||
[node name="BrickThrowComponent" type="Node"]
|
[node name="BrickThrowComponent" type="Node"]
|
||||||
script = ExtResource("1_hniwk")
|
script = ExtResource("1_ogpnm")
|
||||||
brick_scene = ExtResource("2_4txoq")
|
BrickScene = ExtResource("2_4txoq")
|
||||||
fire_rate = 0.3
|
FireRate = 0.3
|
||||||
throw_input_behavior = ExtResource("3_gxahf")
|
ThrowInputBehavior = ExtResource("3_gxahf")
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene load_steps=2 format=3 uid="uid://cunyndudjh2he"]
|
[gd_scene load_steps=2 format=3 uid="uid://cunyndudjh2he"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ce8w71vgv37pt" path="res://scripts/components/magnetic_skill.gd" id="1_lwbas"]
|
[ext_resource type="Script" uid="uid://bi5nx8s1gisbd" path="res://scripts/components/MagneticSkillComponent.cs" id="1_xua8f"]
|
||||||
|
|
||||||
[node name="MagneticSkill" type="Node"]
|
[node name="MagneticSkill" type="Node"]
|
||||||
script = ExtResource("1_lwbas")
|
script = ExtResource("1_xua8f")
|
||||||
|
@@ -1,7 +1,13 @@
|
|||||||
[gd_scene load_steps=6 format=3 uid="uid://dlm2ri562fynd"]
|
[gd_scene load_steps=12 format=3 uid="uid://dlm2ri562fynd"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://bnc16gndpl87i" path="res://scripts/UI/Marketplace.cs" id="1_li4x3"]
|
[ext_resource type="Script" uid="uid://bnc16gndpl87i" path="res://scripts/UI/Marketplace.cs" id="1_li4x3"]
|
||||||
|
[ext_resource type="Script" uid="uid://d4crrfmbgxnqf" path="res://scripts/Resources/SkillData.cs" id="2_c7w2b"]
|
||||||
[ext_resource type="FontFile" uid="uid://xm0vbusjr7b7" path="res://fonts/PressStart2P-Regular.ttf" id="2_ho1tm"]
|
[ext_resource type="FontFile" uid="uid://xm0vbusjr7b7" path="res://fonts/PressStart2P-Regular.ttf" id="2_ho1tm"]
|
||||||
|
[ext_resource type="Resource" uid="uid://dw5ee2lpeypnb" path="res://resources/skills/brick_throw.tres" id="3_1dl8j"]
|
||||||
|
[ext_resource type="Resource" uid="uid://cdp8sex36vdq2" path="res://resources/skills/explosive_brick.tres" id="4_qdv1c"]
|
||||||
|
[ext_resource type="Resource" uid="uid://cr5lo4h8wm0jc" path="res://resources/skills/fire_brick.tres" id="5_4m43l"]
|
||||||
|
[ext_resource type="Resource" uid="uid://ceakv6oqob6m7" path="res://resources/skills/ice_brick.tres" id="6_ialmx"]
|
||||||
|
[ext_resource type="Resource" uid="uid://d3bjre2etov1n" path="res://resources/skills/magnetic.tres" id="7_cycc1"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dtl03rod7l2t0" path="res://objects/ui/marketplace_button.tscn" id="9_ode10"]
|
[ext_resource type="PackedScene" uid="uid://dtl03rod7l2t0" path="res://objects/ui/marketplace_button.tscn" id="9_ode10"]
|
||||||
[ext_resource type="PackedScene" uid="uid://ceqjwmihj70lt" path="res://objects/ui/skill_button.tscn" id="10_c7w2b"]
|
[ext_resource type="PackedScene" uid="uid://ceqjwmihj70lt" path="res://objects/ui/skill_button.tscn" id="10_c7w2b"]
|
||||||
|
|
||||||
@@ -16,6 +22,7 @@ anchor_bottom = 1.0
|
|||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
script = ExtResource("1_li4x3")
|
script = ExtResource("1_li4x3")
|
||||||
|
Skills = Array[ExtResource("2_c7w2b")]([ExtResource("3_1dl8j"), ExtResource("4_qdv1c"), ExtResource("5_4m43l"), ExtResource("6_ialmx"), ExtResource("7_cycc1")])
|
||||||
ToUnlockGrid = NodePath("PanelContainer/MarginContainer/VBoxContainer/ToUnlockGridContainer")
|
ToUnlockGrid = NodePath("PanelContainer/MarginContainer/VBoxContainer/ToUnlockGridContainer")
|
||||||
UnlockedGrid = NodePath("PanelContainer/MarginContainer/VBoxContainer/UnlockedGridContainer")
|
UnlockedGrid = NodePath("PanelContainer/MarginContainer/VBoxContainer/UnlockedGridContainer")
|
||||||
Font = ExtResource("2_ho1tm")
|
Font = ExtResource("2_ho1tm")
|
||||||
|
@@ -32,13 +32,9 @@ config/icon="uid://jix7wdn0isr3"
|
|||||||
GameManager="*res://objects/game_manager.tscn"
|
GameManager="*res://objects/game_manager.tscn"
|
||||||
PhantomCameraManager="*res://addons/phantom_camera/scripts/managers/phantom_camera_manager.gd"
|
PhantomCameraManager="*res://addons/phantom_camera/scripts/managers/phantom_camera_manager.gd"
|
||||||
AudioController="*res://objects/audio_controller.tscn"
|
AudioController="*res://objects/audio_controller.tscn"
|
||||||
SteamIntegrationNode="*res://objects/steam_integration.tscn"
|
|
||||||
SteamControllerInput="*res://autoloads/steam_controller_input.gd"
|
|
||||||
AchievementsManager="*res://objects/achievements.tscn"
|
|
||||||
UIManager="*res://Autoloads/UIManager.cs"
|
UIManager="*res://Autoloads/UIManager.cs"
|
||||||
ConfigFileHandler="*res://Autoloads/ConfigFileHandler.cs"
|
ConfigFileHandler="*res://Autoloads/ConfigFileHandler.cs"
|
||||||
SaveSystem="*res://Autoloads/SaveSystem.cs"
|
SaveSystem="*res://Autoloads/SaveSystem.cs"
|
||||||
Console="*res://addons/console/console.gd"
|
|
||||||
|
|
||||||
[debug]
|
[debug]
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
[gd_resource type="Resource" load_steps=4 format=3 uid="uid://dw5ee2lpeypnb"]
|
[gd_resource type="Resource" load_steps=5 format=3 uid="uid://dw5ee2lpeypnb"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="1_5gnea"]
|
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="1_5gnea"]
|
||||||
|
[ext_resource type="Resource" uid="uid://br84dsfa3ti04" path="res://resources/throw_behaviors/tap_throw_input.tres" id="1_yimbq"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dxtdwgg3po0eg" path="res://sprites/brick_power_Skill_icon.png" id="2_yimbq"]
|
[ext_resource type="Texture2D" uid="uid://dxtdwgg3po0eg" path="res://sprites/brick_power_Skill_icon.png" id="2_yimbq"]
|
||||||
[ext_resource type="Script" uid="uid://d4crrfmbgxnqf" path="res://scripts/Resources/SkillData.cs" id="3_yimbq"]
|
[ext_resource type="Script" uid="uid://d4crrfmbgxnqf" path="res://scripts/Resources/SkillData.cs" id="3_yimbq"]
|
||||||
|
|
||||||
@@ -11,7 +12,7 @@ Description = "BRICK_POWER_DESCRIPTION"
|
|||||||
Config = Dictionary[String, Variant]({
|
Config = Dictionary[String, Variant]({
|
||||||
"fire_rate": 0.6,
|
"fire_rate": 0.6,
|
||||||
"player_controller": NodePath("."),
|
"player_controller": NodePath("."),
|
||||||
"throw_input_behavior": null,
|
"throw_input_behavior": ExtResource("1_yimbq"),
|
||||||
"timer": NodePath("ThrowTimer")
|
"timer": NodePath("ThrowTimer")
|
||||||
})
|
})
|
||||||
Cost = 50
|
Cost = 50
|
||||||
|
@@ -1,25 +1,25 @@
|
|||||||
[gd_resource type="Resource" script_class="SkillData" load_steps=6 format=3 uid="uid://cdp8sex36vdq2"]
|
[gd_resource type="Resource" load_steps=6 format=3 uid="uid://cdp8sex36vdq2"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://5surx230gfw3" path="res://objects/entities/exploding_brick.tscn" id="1_6pfoa"]
|
[ext_resource type="PackedScene" uid="uid://5surx230gfw3" path="res://objects/entities/exploding_brick.tscn" id="1_6pfoa"]
|
||||||
[ext_resource type="Resource" uid="uid://diuv6pr6a0dup" path="res://resources/throw_behaviors/charge_throw_input.tres" id="2_87gkt"]
|
[ext_resource type="Resource" uid="uid://diuv6pr6a0dup" path="res://resources/throw_behaviors/charge_throw_input.tres" id="2_87gkt"]
|
||||||
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="2_e0o8w"]
|
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="2_e0o8w"]
|
||||||
[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="3_cgsq1"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://c0xtjfpmkfolk" path="res://sprites/explosive_brick_skill_icon.png" id="3_wkqmb"]
|
[ext_resource type="Texture2D" uid="uid://c0xtjfpmkfolk" path="res://sprites/explosive_brick_skill_icon.png" id="3_wkqmb"]
|
||||||
|
[ext_resource type="Script" uid="uid://d4crrfmbgxnqf" path="res://scripts/Resources/SkillData.cs" id="5_wkqmb"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("3_cgsq1")
|
script = ExtResource("5_wkqmb")
|
||||||
name = "EXPLOSIVE_BRICK"
|
Name = "EXPLOSIVE_BRICK"
|
||||||
description = "EXPLOSIVE_BRICK_DESCRIPTION"
|
Description = "EXPLOSIVE_BRICK_DESCRIPTION"
|
||||||
node = ExtResource("2_e0o8w")
|
Config = Dictionary[String, Variant]({
|
||||||
config = {
|
|
||||||
"brick_scene": ExtResource("1_6pfoa"),
|
"brick_scene": ExtResource("1_6pfoa"),
|
||||||
"player_controller": NodePath("."),
|
"player_controller": NodePath("."),
|
||||||
"throw_input_behavior": ExtResource("2_87gkt"),
|
"throw_input_behavior": ExtResource("2_87gkt"),
|
||||||
"timer": NodePath("ThrowTimer")
|
"timer": NodePath("ThrowTimer")
|
||||||
}
|
})
|
||||||
cost = 180
|
Cost = 180
|
||||||
icon = ExtResource("3_wkqmb")
|
Icon = ExtResource("3_wkqmb")
|
||||||
type = 1
|
IsActive = false
|
||||||
is_active = false
|
Level = 0
|
||||||
level = 0
|
MaxLevel = 1
|
||||||
max_level = 1
|
Type = 1
|
||||||
|
Node = ExtResource("2_e0o8w")
|
||||||
|
@@ -1,25 +1,25 @@
|
|||||||
[gd_resource type="Resource" script_class="SkillData" load_steps=6 format=3 uid="uid://2glvryih82t1"]
|
[gd_resource type="Resource" load_steps=6 format=3 uid="uid://cr5lo4h8wm0jc"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://daau4j5hbklk0" path="res://objects/entities/fire_brick.tscn" id="1_2g43l"]
|
[ext_resource type="PackedScene" uid="uid://daau4j5hbklk0" path="res://objects/entities/fire_brick.tscn" id="1_2g43l"]
|
||||||
[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="1_2j5ko"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="1_g53fp"]
|
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="1_g53fp"]
|
||||||
[ext_resource type="Resource" uid="uid://br84dsfa3ti04" path="res://resources/throw_behaviors/tap_throw_input.tres" id="2_dm5pj"]
|
[ext_resource type="Resource" uid="uid://br84dsfa3ti04" path="res://resources/throw_behaviors/tap_throw_input.tres" id="2_dm5pj"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cocbnr38qsikt" path="res://sprites/fire_brick_skill_icon.png" id="3_w87qb"]
|
[ext_resource type="Texture2D" uid="uid://cocbnr38qsikt" path="res://sprites/fire_brick_skill_icon.png" id="3_w87qb"]
|
||||||
|
[ext_resource type="Script" uid="uid://d4crrfmbgxnqf" path="res://scripts/Resources/SkillData.cs" id="5_us7vb"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_2j5ko")
|
script = ExtResource("5_us7vb")
|
||||||
name = "FIRE_BRICK"
|
Name = "FIRE_BRICK"
|
||||||
description = "FIRE_BIRCK_DESCRIPTION"
|
Description = "FIRE_BIRCK_DESCRIPTION"
|
||||||
node = ExtResource("1_g53fp")
|
Config = Dictionary[String, Variant]({
|
||||||
config = {
|
|
||||||
"brick_scene": ExtResource("1_2g43l"),
|
"brick_scene": ExtResource("1_2g43l"),
|
||||||
"player_controller": NodePath("."),
|
"player_controller": NodePath("."),
|
||||||
"throw_input_behavior": ExtResource("2_dm5pj"),
|
"throw_input_behavior": ExtResource("2_dm5pj"),
|
||||||
"timer": NodePath("ThrowTimer")
|
"timer": NodePath("ThrowTimer")
|
||||||
}
|
})
|
||||||
cost = 150
|
Cost = 150
|
||||||
icon = ExtResource("3_w87qb")
|
Icon = ExtResource("3_w87qb")
|
||||||
type = 1
|
IsActive = false
|
||||||
is_active = false
|
Level = 0
|
||||||
level = 0
|
MaxLevel = 3
|
||||||
max_level = 3
|
Type = 1
|
||||||
|
Node = ExtResource("1_g53fp")
|
||||||
|
@@ -1,25 +1,25 @@
|
|||||||
[gd_resource type="Resource" script_class="SkillData" load_steps=6 format=3 uid="uid://cx5fsbexblp60"]
|
[gd_resource type="Resource" load_steps=6 format=3 uid="uid://ceakv6oqob6m7"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://bcmx07k12gcsc" path="res://objects/entities/ice_brick.tscn" id="1_ci3d1"]
|
[ext_resource type="PackedScene" uid="uid://bcmx07k12gcsc" path="res://objects/entities/ice_brick.tscn" id="1_ci3d1"]
|
||||||
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="1_rflri"]
|
[ext_resource type="PackedScene" uid="uid://coayig4dxelo2" path="res://objects/player_skills/brick_throw_skill.tscn" id="1_rflri"]
|
||||||
[ext_resource type="Resource" uid="uid://br84dsfa3ti04" path="res://resources/throw_behaviors/tap_throw_input.tres" id="2_hsgyv"]
|
[ext_resource type="Resource" uid="uid://br84dsfa3ti04" path="res://resources/throw_behaviors/tap_throw_input.tres" id="2_hsgyv"]
|
||||||
[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="2_pspkt"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://c1qaxspv8aemf" path="res://sprites/ice_brick_skill_icon.png" id="3_6btth"]
|
[ext_resource type="Texture2D" uid="uid://c1qaxspv8aemf" path="res://sprites/ice_brick_skill_icon.png" id="3_6btth"]
|
||||||
|
[ext_resource type="Script" uid="uid://d4crrfmbgxnqf" path="res://scripts/Resources/SkillData.cs" id="5_57pl3"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("2_pspkt")
|
script = ExtResource("5_57pl3")
|
||||||
name = "ICE_BRICK"
|
Name = "ICE_BRICK"
|
||||||
description = "ICE_BRICK_DESCRIPTION"
|
Description = "ICE_BRICK_DESCRIPTION"
|
||||||
node = ExtResource("1_rflri")
|
Config = Dictionary[String, Variant]({
|
||||||
config = {
|
|
||||||
"brick_scene": ExtResource("1_ci3d1"),
|
"brick_scene": ExtResource("1_ci3d1"),
|
||||||
"player_controller": NodePath("."),
|
"player_controller": NodePath("."),
|
||||||
"throw_input_behavior": ExtResource("2_hsgyv"),
|
"throw_input_behavior": ExtResource("2_hsgyv"),
|
||||||
"timer": NodePath("ThrowTimer")
|
"timer": NodePath("ThrowTimer")
|
||||||
}
|
})
|
||||||
cost = 150
|
Cost = 180
|
||||||
icon = ExtResource("3_6btth")
|
Icon = ExtResource("3_6btth")
|
||||||
type = 1
|
IsActive = false
|
||||||
is_active = false
|
Level = 0
|
||||||
level = 0
|
MaxLevel = 3
|
||||||
max_level = 3
|
Type = 1
|
||||||
|
Node = ExtResource("1_rflri")
|
||||||
|
@@ -1,22 +1,22 @@
|
|||||||
[gd_resource type="Resource" script_class="SkillData" load_steps=4 format=3 uid="uid://d3bjre2etov1n"]
|
[gd_resource type="Resource" load_steps=4 format=3 uid="uid://d3bjre2etov1n"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://cvhoq7aubxlmq" path="res://sprites/ui/magnetic_skill_icon.png" id="1_16qcg"]
|
[ext_resource type="Texture2D" uid="uid://cvhoq7aubxlmq" path="res://sprites/ui/magnetic_skill_icon.png" id="1_16qcg"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cunyndudjh2he" path="res://objects/player_skills/magnetic_skill.tscn" id="1_er41s"]
|
[ext_resource type="PackedScene" uid="uid://cunyndudjh2he" path="res://objects/player_skills/magnetic_skill.tscn" id="1_er41s"]
|
||||||
[ext_resource type="Script" uid="uid://bya240e627ti6" path="res://scripts/resources/skill_data.gd" id="1_r01oq"]
|
[ext_resource type="Script" uid="uid://d4crrfmbgxnqf" path="res://scripts/Resources/SkillData.cs" id="3_htb6q"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_r01oq")
|
script = ExtResource("3_htb6q")
|
||||||
name = "MAGNETIC"
|
Name = "MAGNETIC"
|
||||||
description = "MAGNETIC_DESCRIPTION"
|
Description = "MAGNETIC_DESCRIPTION"
|
||||||
node = ExtResource("1_er41s")
|
Config = Dictionary[String, Variant]({
|
||||||
config = {
|
|
||||||
"magnetic_area": NodePath("MagneticArea"),
|
"magnetic_area": NodePath("MagneticArea"),
|
||||||
"magnetic_move_duration": 1.25,
|
"magnetic_move_duration": 1.25,
|
||||||
"root": NodePath(".")
|
"root": NodePath(".")
|
||||||
}
|
})
|
||||||
cost = 70
|
Cost = 70
|
||||||
icon = ExtResource("1_16qcg")
|
Icon = ExtResource("1_16qcg")
|
||||||
type = 2
|
IsActive = false
|
||||||
is_active = false
|
Level = 1
|
||||||
level = 1
|
MaxLevel = 1
|
||||||
max_level = 1
|
Type = 2
|
||||||
|
Node = ExtResource("1_er41s")
|
||||||
|
@@ -173,6 +173,9 @@ position = Vector2(7146.51, 21.1388)
|
|||||||
|
|
||||||
[node name="Brick Player" parent="." instance=ExtResource("1_k3uyd")]
|
[node name="Brick Player" parent="." instance=ExtResource("1_k3uyd")]
|
||||||
|
|
||||||
|
[node name="SkillUnlockerComponent" parent="Brick Player" index="17" node_paths=PackedStringArray("SkillManager")]
|
||||||
|
SkillManager = NodePath("../SkillManager")
|
||||||
|
|
||||||
[node name="HitParticles" parent="Brick Player" index="27"]
|
[node name="HitParticles" parent="Brick Player" index="27"]
|
||||||
process_material = SubResource("ParticleProcessMaterial_lgb3u")
|
process_material = SubResource("ParticleProcessMaterial_lgb3u")
|
||||||
|
|
||||||
|
@@ -99,8 +99,8 @@ public partial class Marketplace : Control
|
|||||||
button.Pressed += () => OnUpgradeButtonPressed(skill);
|
button.Pressed += () => OnUpgradeButtonPressed(skill);
|
||||||
|
|
||||||
_unlockButtons.Add(button);
|
_unlockButtons.Add(button);
|
||||||
UnlockedGrid.AddChild(button);
|
ToUnlockGrid.AddChild(button);
|
||||||
UnlockedGrid.QueueSort();
|
ToUnlockGrid.QueueSort();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUpgradeButtonPressed(SkillData skill)
|
private void OnUpgradeButtonPressed(SkillData skill)
|
||||||
|
@@ -1,17 +0,0 @@
|
|||||||
class_name Achievements
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
func unlock_achievement(achievement_name: String) -> bool:
|
|
||||||
if not Steam.setAchievement(achievement_name):
|
|
||||||
print("Failed to unlock achievement: ", achievement_name)
|
|
||||||
return false
|
|
||||||
|
|
||||||
return true
|
|
||||||
|
|
||||||
|
|
||||||
func reset_achievement(achievement_name: String) -> bool:
|
|
||||||
if not Steam.clearAchievement(achievement_name):
|
|
||||||
print("Failed to reset achievement: ", achievement_name)
|
|
||||||
return false
|
|
||||||
|
|
||||||
return true
|
|
@@ -1 +0,0 @@
|
|||||||
uid://deguukal87gcb
|
|
@@ -1,138 +0,0 @@
|
|||||||
class_name ConsoleManagement
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export var player_health: HealthComponent
|
|
||||||
@export var skill_unlocker: SkillUnlockerComponent
|
|
||||||
@export var skill_manager: SkillManager
|
|
||||||
|
|
||||||
@onready var game_manager: GM = $"/root/GameManager"
|
|
||||||
@onready var achievements: Achievements = $"/root/AchievementsManager"
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
Console.pause_enabled = true
|
|
||||||
Console.add_command("add_coins", console_add_coins, ["amount"], 1, "Add coins to the player.")
|
|
||||||
Console.add_command("set_coins", console_set_coins, ["amount"], 1, "Set the player's coins.")
|
|
||||||
Console.add_command("set_lives", console_set_lives, ["amount"], 1, "Set the player's lives.")
|
|
||||||
Console.add_command("set_health", console_set_health, ["amount"], 1, "Set the player's health.")
|
|
||||||
Console.add_command("unlock_skill", console_unlock_skill, ["skill_name"], 1, "Unlock a skill for the player.")
|
|
||||||
Console.add_command("remove_skill", console_remove_skill, ["skill_name"], 1, "Remove a skill from the player.")
|
|
||||||
Console.add_command("remove_all_skills", console_remove_all_skills, [], 0, "Remove all skills from the player.")
|
|
||||||
Console.add_command("unlock_all_skills", console_unlock_all_skills, [], 0, "Unlock all skills for the player.")
|
|
||||||
Console.add_command("unlock_achievement", console_unlock_achievement, ["achievement_name"], 1, "Unlock an achievement for the player.")
|
|
||||||
Console.add_command("reset_achievement", console_reset_achievement, ["achievement_name"], 1, "Reset an achievement for the player.")
|
|
||||||
|
|
||||||
|
|
||||||
func console_add_coins(amount: Variant) -> void:
|
|
||||||
if not game_manager:
|
|
||||||
return
|
|
||||||
if not amount.is_valid_int():
|
|
||||||
Console.print_error("Invalid amount: " + str(amount))
|
|
||||||
return
|
|
||||||
game_manager.add_coins(int(amount))
|
|
||||||
Console.print_info("Added " + str(amount) + " coins.")
|
|
||||||
|
|
||||||
|
|
||||||
func console_set_coins(amount: Variant) -> void:
|
|
||||||
if not game_manager:
|
|
||||||
return
|
|
||||||
if not amount.is_valid_int():
|
|
||||||
Console.print_error("Invalid amount: " + str(amount))
|
|
||||||
return
|
|
||||||
game_manager.set_coins(int(amount))
|
|
||||||
Console.print_info("Set coins to " + str(amount))
|
|
||||||
|
|
||||||
|
|
||||||
func console_set_lives(amount: Variant) -> void:
|
|
||||||
if not game_manager:
|
|
||||||
return
|
|
||||||
if not amount.is_valid_int():
|
|
||||||
Console.print_error("Invalid amount: " + str(amount))
|
|
||||||
return
|
|
||||||
game_manager.set_lives(int(amount))
|
|
||||||
Console.print_info("Set lives to " + str(amount))
|
|
||||||
|
|
||||||
|
|
||||||
func console_set_health(amount: Variant) -> void:
|
|
||||||
if not player_health:
|
|
||||||
return
|
|
||||||
if not amount.is_valid_float():
|
|
||||||
Console.print_error("Invalid amount: " + str(amount))
|
|
||||||
return
|
|
||||||
player_health.set_health(float(amount))
|
|
||||||
Console.print_info("Set health to " + str(amount))
|
|
||||||
|
|
||||||
|
|
||||||
func console_unlock_skill(skill_name: Variant) -> void:
|
|
||||||
if not skill_manager or not skill_unlocker or not game_manager:
|
|
||||||
return
|
|
||||||
if not skill_name:
|
|
||||||
Console.print_error("Invalid skill name: " + str(skill_name))
|
|
||||||
return
|
|
||||||
|
|
||||||
var skill_data: SkillData = skill_manager.get_skill_by_name(skill_name)
|
|
||||||
skill_data.level = 1
|
|
||||||
|
|
||||||
if not skill_data:
|
|
||||||
Console.print_error("Skill not found: " + str(skill_name))
|
|
||||||
return
|
|
||||||
|
|
||||||
game_manager.unlock_skill(skill_data)
|
|
||||||
skill_manager.activate_skill(skill_data)
|
|
||||||
skill_unlocker.skill_unlocked.emit(skill_data)
|
|
||||||
Console.print_info("Unlocked skill: " + str(skill_name))
|
|
||||||
|
|
||||||
|
|
||||||
func console_unlock_all_skills() -> void:
|
|
||||||
if not skill_manager or not skill_unlocker or not game_manager:
|
|
||||||
return
|
|
||||||
|
|
||||||
skill_unlocker.unlock_all_skills()
|
|
||||||
Console.print_info("Unlocked all skills.")
|
|
||||||
|
|
||||||
|
|
||||||
func console_remove_skill(skill_name: Variant) -> void:
|
|
||||||
if not skill_manager or not skill_unlocker or not game_manager:
|
|
||||||
return
|
|
||||||
if not skill_name:
|
|
||||||
Console.print_error("Invalid skill name: " + str(skill_name))
|
|
||||||
return
|
|
||||||
|
|
||||||
game_manager.remove_skill(skill_name)
|
|
||||||
skill_manager.remove_skill(skill_name)
|
|
||||||
Console.print_info("Removed skill: " + str(skill_name))
|
|
||||||
|
|
||||||
|
|
||||||
func console_remove_all_skills() -> void:
|
|
||||||
if not skill_manager or not skill_unlocker or not game_manager:
|
|
||||||
return
|
|
||||||
|
|
||||||
for skill_name in skill_manager.active_components.keys():
|
|
||||||
game_manager.remove_skill(skill_name)
|
|
||||||
skill_manager.remove_skill(skill_name)
|
|
||||||
|
|
||||||
|
|
||||||
func console_unlock_achievement(achievement_name: Variant) -> void:
|
|
||||||
if not achievement_name:
|
|
||||||
Console.print_error("Invalid achievement name: " + str(achievement_name))
|
|
||||||
return
|
|
||||||
if not achievements:
|
|
||||||
Console.print_error("Achievements manager not found.")
|
|
||||||
return
|
|
||||||
if not achievements.unlock_achievement(achievement_name):
|
|
||||||
Console.print_error("Failed to unlock achievement: " + str(achievement_name))
|
|
||||||
|
|
||||||
Console.print_info("Unlocked achievement: " + str(achievement_name))
|
|
||||||
|
|
||||||
|
|
||||||
func console_reset_achievement(achievement_name: Variant) -> void:
|
|
||||||
if not achievement_name:
|
|
||||||
Console.print_error("Invalid achievement name: " + str(achievement_name))
|
|
||||||
return
|
|
||||||
if not achievements:
|
|
||||||
Console.print_error("Achievements manager not found.")
|
|
||||||
return
|
|
||||||
if not achievements.reset_achievement(achievement_name):
|
|
||||||
Console.print_error("Failed to reset achievement: " + str(achievement_name))
|
|
||||||
|
|
||||||
Console.print_info("Reset achievement: " + str(achievement_name))
|
|
@@ -1 +0,0 @@
|
|||||||
uid://8r1y8elyw7kt
|
|
@@ -1,231 +0,0 @@
|
|||||||
class_name GM
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export var level_scenes: Array[PackedScene]
|
|
||||||
|
|
||||||
@export var player_state := {
|
|
||||||
"coins": 0,
|
|
||||||
"lives": 3,
|
|
||||||
"unlocked_skills": [],
|
|
||||||
"current_level": 0,
|
|
||||||
"unlocked_levels": [0],
|
|
||||||
"completed_levels": [],
|
|
||||||
}
|
|
||||||
|
|
||||||
var nodes_in_scene := []
|
|
||||||
|
|
||||||
var current_session_state := {
|
|
||||||
"coins_collected": 0,
|
|
||||||
"skills_unlocked": [],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func _enter_tree() -> void:
|
|
||||||
get_tree().node_added.connect(on_node_added)
|
|
||||||
get_tree().node_removed.connect(on_node_removed)
|
|
||||||
|
|
||||||
|
|
||||||
func on_node_added(node: Node) -> void:
|
|
||||||
nodes_in_scene.append(node)
|
|
||||||
|
|
||||||
|
|
||||||
func on_node_removed(node: Node) -> void:
|
|
||||||
if node in nodes_in_scene:
|
|
||||||
nodes_in_scene.erase(node)
|
|
||||||
|
|
||||||
|
|
||||||
func get_colllectable_nodes() -> Array[CollectableComponent]:
|
|
||||||
var collectable_nodes: Array[CollectableComponent] = []
|
|
||||||
for node in nodes_in_scene:
|
|
||||||
var collectable_component: CollectableComponent = node.get_node_or_null("Collectable")
|
|
||||||
if not collectable_component:
|
|
||||||
collectable_component = node.get_node_or_null("CollectableComponent")
|
|
||||||
if not collectable_component:
|
|
||||||
continue
|
|
||||||
collectable_nodes.append(collectable_component)
|
|
||||||
return collectable_nodes
|
|
||||||
|
|
||||||
|
|
||||||
func get_coin_nodes() -> Array[CollectableComponent]:
|
|
||||||
var coin_nodes := []
|
|
||||||
for node in nodes_in_scene:
|
|
||||||
var collectable_component: CollectableComponent = node.get_node_or_null("Collectable")
|
|
||||||
if not collectable_component:
|
|
||||||
continue
|
|
||||||
if collectable_component.collectable_data.type == CollectableResource.CollectableType.COIN:
|
|
||||||
coin_nodes.append(collectable_component)
|
|
||||||
return coin_nodes
|
|
||||||
|
|
||||||
|
|
||||||
func get_kid_nodes() -> Array[CollectableComponent]:
|
|
||||||
var kid_nodes := []
|
|
||||||
for node in nodes_in_scene:
|
|
||||||
var collectable_component: CollectableComponent = node.get_node_or_null("Collectable")
|
|
||||||
if not collectable_component:
|
|
||||||
continue
|
|
||||||
if collectable_component.collectable_data.type == CollectableResource.CollectableType.KID:
|
|
||||||
kid_nodes.append(collectable_component)
|
|
||||||
return kid_nodes
|
|
||||||
|
|
||||||
|
|
||||||
func get_player_node() -> Node:
|
|
||||||
for node in nodes_in_scene:
|
|
||||||
if node is PlayerController:
|
|
||||||
return node
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
|
||||||
func add_coins(amount: int) -> void:
|
|
||||||
player_state["coins"] += amount
|
|
||||||
player_state["coins"] = max(0, player_state["coins"])
|
|
||||||
|
|
||||||
|
|
||||||
func set_coins(amount: int) -> void:
|
|
||||||
player_state["coins"] = amount
|
|
||||||
|
|
||||||
|
|
||||||
func get_coins() -> int:
|
|
||||||
return player_state["coins"] + current_session_state["coins_collected"]
|
|
||||||
|
|
||||||
|
|
||||||
func remove_coins(amount: int) -> void:
|
|
||||||
var session_coins = current_session_state["coins_collected"]
|
|
||||||
|
|
||||||
if amount <= session_coins:
|
|
||||||
current_session_state["coins_collected"] -= amount
|
|
||||||
else:
|
|
||||||
var remaining_amount = amount - session_coins
|
|
||||||
current_session_state["coins_collected"] = 0
|
|
||||||
player_state["coins"] = max(0, player_state["coins"] - remaining_amount)
|
|
||||||
|
|
||||||
player_state["coins"] = max(0, player_state["coins"])
|
|
||||||
|
|
||||||
|
|
||||||
func add_lives(amount: int) -> void:
|
|
||||||
player_state["lives"] += amount
|
|
||||||
|
|
||||||
|
|
||||||
func remove_lives(amount: int) -> void:
|
|
||||||
player_state["lives"] -= amount
|
|
||||||
|
|
||||||
|
|
||||||
func set_lives(amount: int) -> void:
|
|
||||||
player_state["lives"] = amount
|
|
||||||
|
|
||||||
|
|
||||||
func get_lives() -> int:
|
|
||||||
return player_state["lives"]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func is_skill_unlocked(skill: SkillData) -> bool:
|
|
||||||
return skill in player_state["unlocked_skills"] or skill in current_session_state["skills_unlocked"]
|
|
||||||
|
|
||||||
|
|
||||||
func unlock_skill(skill: SkillData) -> void:
|
|
||||||
if not is_skill_unlocked(skill):
|
|
||||||
player_state["unlocked_skills"].append(skill)
|
|
||||||
|
|
||||||
|
|
||||||
func remove_skill(skill: SkillData) -> void:
|
|
||||||
if is_skill_unlocked(skill):
|
|
||||||
player_state["unlocked_skills"].erase(skill)
|
|
||||||
|
|
||||||
|
|
||||||
func unlock_skills(skills: Array[SkillData]) -> void:
|
|
||||||
for skill in skills:
|
|
||||||
unlock_skill(skill)
|
|
||||||
|
|
||||||
|
|
||||||
func reset_player_state() -> void:
|
|
||||||
player_state = {
|
|
||||||
"coins": 0,
|
|
||||||
"lives": 3,
|
|
||||||
"unlocked_skills": [],
|
|
||||||
"current_level": 0,
|
|
||||||
"unlocked_levels": [0],
|
|
||||||
"completed_levels": [],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func unlock_level(level_index: int) -> void:
|
|
||||||
if level_index not in player_state["unlocked_levels"]: player_state["unlocked_levels"].append(level_index)
|
|
||||||
|
|
||||||
|
|
||||||
func try_to_go_to_next_level() -> void:
|
|
||||||
var next_level = player_state["current_level"] + 1
|
|
||||||
if next_level < level_scenes.size() and next_level in player_state["unlocked_levels"]:
|
|
||||||
player_state["current_level"] += 1
|
|
||||||
get_tree().change_scene_to_packed(level_scenes[next_level])
|
|
||||||
|
|
||||||
|
|
||||||
func mark_level_complete(level_index: int) -> void:
|
|
||||||
unlock_level(level_index + 1)
|
|
||||||
if level_index not in player_state["completed_levels"]: player_state["completed_levels"].append(level_index)
|
|
||||||
|
|
||||||
|
|
||||||
func reset_current_session_state() -> void:
|
|
||||||
current_session_state = {
|
|
||||||
"coins_collected": 0,
|
|
||||||
"skills_unlocked": [],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func restart_game() -> void:
|
|
||||||
reset_player_state()
|
|
||||||
reset_current_session_state()
|
|
||||||
get_tree().change_scene_to_packed(level_scenes[0])
|
|
||||||
SaveSystem.save_game()
|
|
||||||
|
|
||||||
|
|
||||||
func quit_game() -> void:
|
|
||||||
get_tree().quit()
|
|
||||||
|
|
||||||
|
|
||||||
func pause_game() -> void:
|
|
||||||
Engine.time_scale = 0
|
|
||||||
|
|
||||||
|
|
||||||
func resume_game() -> void:
|
|
||||||
Engine.time_scale = 1
|
|
||||||
|
|
||||||
|
|
||||||
func start_new_game() -> void:
|
|
||||||
reset_player_state()
|
|
||||||
reset_current_session_state()
|
|
||||||
get_tree().change_scene_to_packed(level_scenes[0])
|
|
||||||
SaveSystem.save_game()
|
|
||||||
|
|
||||||
|
|
||||||
func continue_game() -> void:
|
|
||||||
if not SaveSystem.load_game():
|
|
||||||
printerr("Failed to load game. Starting a new game instead.")
|
|
||||||
start_new_game()
|
|
||||||
return
|
|
||||||
|
|
||||||
if player_state["current_level"] < level_scenes.size():
|
|
||||||
get_tree().change_scene_to_packed(level_scenes[player_state["current_level"]])
|
|
||||||
else:
|
|
||||||
printerr("No levels unlocked to continue.")
|
|
||||||
|
|
||||||
|
|
||||||
func on_level_complete() -> void:
|
|
||||||
var level_index = player_state["current_level"]
|
|
||||||
mark_level_complete(level_index)
|
|
||||||
add_coins(current_session_state["coins_collected"])
|
|
||||||
for skill in current_session_state["skills_unlocked"]:
|
|
||||||
unlock_skill(skill)
|
|
||||||
|
|
||||||
reset_current_session_state()
|
|
||||||
try_to_go_to_next_level()
|
|
||||||
SaveSystem.save_game()
|
|
||||||
|
|
||||||
|
|
||||||
func get_unlocked_skills() -> Array:
|
|
||||||
var skills_unlocked = player_state.get("unlocked_skills", [])
|
|
||||||
var skills_current_session = current_session_state.get("skills_unlocked", [])
|
|
||||||
if not skills_current_session:
|
|
||||||
return skills_unlocked
|
|
||||||
if not skills_unlocked:
|
|
||||||
return skills_current_session
|
|
||||||
return skills_unlocked + skills_current_session
|
|
@@ -1 +0,0 @@
|
|||||||
uid://dd30bgqiagi25
|
|
@@ -1,64 +0,0 @@
|
|||||||
class_name PlayerController
|
|
||||||
extends CharacterBody2D
|
|
||||||
|
|
||||||
@export var default_movement_type: String = "platform"
|
|
||||||
@export var movement_types: Dictionary = {}
|
|
||||||
@export var ship_sprite: Sprite2D
|
|
||||||
|
|
||||||
var current_movement: PlayerMovement = null
|
|
||||||
signal movement_switched(movement_type: String)
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
for movement_type in movement_types:
|
|
||||||
var movement_node: Node = get_node_or_null(movement_types[movement_type])
|
|
||||||
if movement_node and movement_node is PlayerMovement:
|
|
||||||
movement_node.enabled = false
|
|
||||||
|
|
||||||
switch_movement(default_movement_type)
|
|
||||||
|
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
|
||||||
if event is InputEventKey:
|
|
||||||
if event.is_action_pressed("switch_movement"):
|
|
||||||
var next_movement_type: String = get_next_movement_type()
|
|
||||||
switch_movement(next_movement_type)
|
|
||||||
|
|
||||||
|
|
||||||
func switch_movement(movement_type: String) -> void:
|
|
||||||
if current_movement:
|
|
||||||
current_movement.enabled = false
|
|
||||||
|
|
||||||
if movement_type in movement_types:
|
|
||||||
current_movement = get_node_or_null(movement_types[movement_type])
|
|
||||||
if not current_movement:
|
|
||||||
push_error("Movement type '%s' not found in movement_types." % movement_type)
|
|
||||||
return
|
|
||||||
current_movement.enabled = true
|
|
||||||
movement_switched.emit(current_movement.type)
|
|
||||||
else:
|
|
||||||
push_error("Movement type '%s' not found in movement_types." % movement_type)
|
|
||||||
|
|
||||||
if not current_movement:
|
|
||||||
push_error("No current movement set after switching.")
|
|
||||||
|
|
||||||
|
|
||||||
func get_next_movement_type() -> String:
|
|
||||||
var keys: Array = movement_types.keys()
|
|
||||||
var current_index: int = keys.find(current_movement.type)
|
|
||||||
if current_index == -1:
|
|
||||||
return default_movement_type
|
|
||||||
|
|
||||||
current_index = (current_index + 1) % keys.size()
|
|
||||||
return keys[current_index]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func on_spaceship_entered() -> void:
|
|
||||||
switch_movement("ship")
|
|
||||||
ship_sprite.visible = true
|
|
||||||
|
|
||||||
|
|
||||||
func on_spaceship_exited() -> void:
|
|
||||||
switch_movement(default_movement_type)
|
|
||||||
ship_sprite.visible = false
|
|
@@ -1 +0,0 @@
|
|||||||
uid://ccuddyoakg04u
|
|
@@ -1,8 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
|
||||||
if OS.is_debug_build() and Input.is_action_just_pressed("screenshot"):
|
|
||||||
var img := get_viewport().get_texture().get_image()
|
|
||||||
var id := OS.get_unique_id() + "_" + Time.get_datetime_string_from_system()
|
|
||||||
var path := "user://screenshot_" + str(id) + ".png"
|
|
||||||
img.save_png(path)
|
|
@@ -1 +0,0 @@
|
|||||||
uid://bydv4g1n5s3nf
|
|
@@ -1,103 +0,0 @@
|
|||||||
class_name SkillManager
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export var available_skills: Array[SkillData] = []
|
|
||||||
|
|
||||||
@onready var gm: GM = $"/root/GameManager"
|
|
||||||
|
|
||||||
var active_components: Dictionary = {}
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
apply_unlocked_skills()
|
|
||||||
|
|
||||||
|
|
||||||
func add_skill(skill_data: SkillData) -> void:
|
|
||||||
if active_components.has(skill_data.name):
|
|
||||||
return
|
|
||||||
|
|
||||||
if skill_data.type == SkillData.SkillType.THROW:
|
|
||||||
var unlocked_skills: Array = gm.get_unlocked_skills()
|
|
||||||
for skill in unlocked_skills:
|
|
||||||
var data = null
|
|
||||||
for s in available_skills:
|
|
||||||
if s == skill:
|
|
||||||
data = s
|
|
||||||
break
|
|
||||||
if data and data.type == SkillData.SkillType.THROW:
|
|
||||||
remove_skill(data.name)
|
|
||||||
|
|
||||||
var skill_instance := skill_data.node.instantiate()
|
|
||||||
for key in skill_data.config.keys():
|
|
||||||
if key in skill_instance:
|
|
||||||
var value = skill_data.config[key]
|
|
||||||
var parent := get_parent()
|
|
||||||
|
|
||||||
if value is NodePath:
|
|
||||||
if parent.has_node(value):
|
|
||||||
value = parent.get_node(value)
|
|
||||||
elif skill_instance.has_node(value):
|
|
||||||
value = skill_instance.get_node(value)
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
|
|
||||||
skill_instance[key] = value
|
|
||||||
|
|
||||||
owner.add_child(skill_instance)
|
|
||||||
active_components[skill_data.name] = skill_instance
|
|
||||||
|
|
||||||
|
|
||||||
func remove_skill(skill_name: String) -> void:
|
|
||||||
if not active_components.has(skill_name):
|
|
||||||
return
|
|
||||||
|
|
||||||
var skill_instance = active_components[skill_name]
|
|
||||||
if is_instance_valid(skill_instance):
|
|
||||||
skill_instance.queue_free()
|
|
||||||
|
|
||||||
var skills: Array = gm.get_unlocked_skills()
|
|
||||||
for s in skills:
|
|
||||||
if s.name == skill_name:
|
|
||||||
s.is_active = false
|
|
||||||
break
|
|
||||||
active_components.erase(skill_name)
|
|
||||||
|
|
||||||
|
|
||||||
func apply_unlocked_skills() -> void:
|
|
||||||
for skill_data in available_skills:
|
|
||||||
if gm.is_skill_unlocked(skill_data):
|
|
||||||
print("Applying skill: ", skill_data.name)
|
|
||||||
call_deferred("add_skill", skill_data)
|
|
||||||
else:
|
|
||||||
remove_skill(skill_data.name)
|
|
||||||
|
|
||||||
|
|
||||||
func get_skill_by_name(skill_name: String) -> SkillData:
|
|
||||||
for skill_data in available_skills:
|
|
||||||
if skill_data.name == skill_name:
|
|
||||||
return skill_data
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
|
||||||
func activate_skill(skill: SkillData) -> void:
|
|
||||||
if not active_components.has(skill.name):
|
|
||||||
if skill:
|
|
||||||
add_skill(skill)
|
|
||||||
skill.is_active = true
|
|
||||||
|
|
||||||
|
|
||||||
func deactivate_skill(skill: SkillData) -> void:
|
|
||||||
if active_components.has(skill.name):
|
|
||||||
remove_skill(skill.name)
|
|
||||||
if skill:
|
|
||||||
skill.is_active = false
|
|
||||||
|
|
||||||
|
|
||||||
func toggle_skill_activation(skill: SkillData) -> void:
|
|
||||||
if not skill:
|
|
||||||
return
|
|
||||||
|
|
||||||
if active_components.has(skill.name):
|
|
||||||
deactivate_skill(skill)
|
|
||||||
else:
|
|
||||||
activate_skill(skill)
|
|
@@ -1 +0,0 @@
|
|||||||
uid://cjqe428jwip6b
|
|
@@ -1,33 +0,0 @@
|
|||||||
class_name SteamIntegration
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
var app_id: String = "3575090"
|
|
||||||
var is_on_steam_deck: bool = false
|
|
||||||
var is_online: bool = false
|
|
||||||
var has_bought_game: bool = false
|
|
||||||
|
|
||||||
|
|
||||||
func _init() -> void:
|
|
||||||
OS.set_environment("SteamAppId", app_id)
|
|
||||||
OS.set_environment("SteamGameId", app_id)
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
Steam.steamInit()
|
|
||||||
Steam.enableDeviceCallbacks()
|
|
||||||
SteamControllerInput.init()
|
|
||||||
var is_running := Steam.isSteamRunning()
|
|
||||||
|
|
||||||
if !is_running:
|
|
||||||
print("Steam is not running.")
|
|
||||||
return
|
|
||||||
|
|
||||||
print("Steam is running.")
|
|
||||||
|
|
||||||
is_on_steam_deck = Steam.isSteamRunningOnSteamDeck()
|
|
||||||
is_online = Steam.loggedOn()
|
|
||||||
has_bought_game = Steam.isSubscribed()
|
|
||||||
|
|
||||||
if not has_bought_game:
|
|
||||||
print("You have not bought the game.")
|
|
||||||
|
|
@@ -1 +0,0 @@
|
|||||||
uid://f4y8evisxgnc
|
|
@@ -1,104 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
@export var master_volume_slider: Slider
|
|
||||||
@export var music_volume_slider: Slider
|
|
||||||
@export var sfx_volume_slider: Slider
|
|
||||||
@export var audio_settings_control: Control
|
|
||||||
@export var mute_treshold: float = -20.0
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
initialize()
|
|
||||||
if master_volume_slider:
|
|
||||||
master_volume_slider.value_changed.connect(_on_master_volume_slider_value_changed)
|
|
||||||
if music_volume_slider:
|
|
||||||
music_volume_slider.value_changed.connect(_on_music_volume_slider_value_changed)
|
|
||||||
if sfx_volume_slider:
|
|
||||||
sfx_volume_slider.value_changed.connect(_on_sfx_volume_slider_value_changed)
|
|
||||||
|
|
||||||
load_settings()
|
|
||||||
|
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
|
||||||
if event.is_action_pressed("ui_cancel"):
|
|
||||||
if UiManager.is_screen_on_top(audio_settings_control):
|
|
||||||
save_settings()
|
|
||||||
UiManager.pop_screen()
|
|
||||||
|
|
||||||
|
|
||||||
func initialize() -> void:
|
|
||||||
if master_volume_slider:
|
|
||||||
var volume_db: float = AudioServer.get_bus_volume_db(AudioServer.get_bus_index("Master"))
|
|
||||||
master_volume_slider.value = volume_db
|
|
||||||
master_volume_slider.min_value = mute_treshold
|
|
||||||
master_volume_slider.max_value = 0.0
|
|
||||||
if music_volume_slider:
|
|
||||||
var music_volume_db: float = AudioServer.get_bus_volume_db(AudioServer.get_bus_index("music"))
|
|
||||||
music_volume_slider.value = music_volume_db
|
|
||||||
music_volume_slider.min_value = mute_treshold
|
|
||||||
music_volume_slider.max_value = 0.0
|
|
||||||
if sfx_volume_slider:
|
|
||||||
var sfx_volume_db: float = AudioServer.get_bus_volume_db(AudioServer.get_bus_index("sfx"))
|
|
||||||
sfx_volume_slider.value = sfx_volume_db
|
|
||||||
sfx_volume_slider.min_value = mute_treshold
|
|
||||||
sfx_volume_slider.max_value = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
func _handle_mute(bus_index: int, value: float) -> void:
|
|
||||||
if AudioServer:
|
|
||||||
if value == mute_treshold:
|
|
||||||
AudioServer.set_bus_mute(bus_index, true)
|
|
||||||
else:
|
|
||||||
AudioServer.set_bus_mute(bus_index, false)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_master_volume_slider_value_changed(value: float) -> void:
|
|
||||||
if AudioServer:
|
|
||||||
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), value)
|
|
||||||
_handle_mute(AudioServer.get_bus_index("Master"), value)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_music_volume_slider_value_changed(value: float) -> void:
|
|
||||||
if AudioServer:
|
|
||||||
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("music"), value)
|
|
||||||
_handle_mute(AudioServer.get_bus_index("music"), value)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_sfx_volume_slider_value_changed(value: float) -> void:
|
|
||||||
if AudioServer:
|
|
||||||
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("sfx"), value)
|
|
||||||
_handle_mute(AudioServer.get_bus_index("sfx"), value)
|
|
||||||
|
|
||||||
|
|
||||||
func save_settings() -> void:
|
|
||||||
if not AudioServer:
|
|
||||||
return
|
|
||||||
|
|
||||||
var settings_config := ConfigFileHandler.settings_config
|
|
||||||
settings_config.set_value("audio_settings", "master_volume", master_volume_slider.value)
|
|
||||||
settings_config.set_value("audio_settings", "music_volume", music_volume_slider.value)
|
|
||||||
settings_config.set_value("audio_settings", "sfx_volume", sfx_volume_slider.value)
|
|
||||||
settings_config.set_value("audio_settings", "mute_treshold", mute_treshold)
|
|
||||||
settings_config.save(ConfigFileHandler.SETTINGS_PATH)
|
|
||||||
|
|
||||||
|
|
||||||
func load_settings() -> void:
|
|
||||||
if not AudioServer:
|
|
||||||
return
|
|
||||||
|
|
||||||
var settings_config := ConfigFileHandler.settings_config
|
|
||||||
if not settings_config.has_section("audio_settings"):
|
|
||||||
print("Audio settings section not found in config file.")
|
|
||||||
return
|
|
||||||
|
|
||||||
var master_volume: float = settings_config.get_value("audio_settings", "master_volume", 0.0)
|
|
||||||
var music_volume: float = settings_config.get_value("audio_settings", "music_volume", 0.0)
|
|
||||||
var sfx_volume: float = settings_config.get_value("audio_settings", "sfx_volume", 0.0)
|
|
||||||
|
|
||||||
if master_volume_slider:
|
|
||||||
master_volume_slider.value = master_volume
|
|
||||||
if music_volume_slider:
|
|
||||||
music_volume_slider.value = music_volume
|
|
||||||
if sfx_volume_slider:
|
|
||||||
sfx_volume_slider.value = sfx_volume
|
|
||||||
mute_treshold = settings_config.get_value("audio_settings", "mute_treshold", -20.0)
|
|
@@ -1 +0,0 @@
|
|||||||
uid://dujk6pnftm7ra
|
|
@@ -1,81 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
@export var progress_bar: ProgressBar
|
|
||||||
@export var brick_throw_component: BrickThrowComponent
|
|
||||||
|
|
||||||
var throw_input: ChargeThrowInputResource
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
owner.child_entered_tree.connect(on_nodes_changed)
|
|
||||||
|
|
||||||
if progress_bar:
|
|
||||||
progress_bar.hide()
|
|
||||||
|
|
||||||
setup_dependencies()
|
|
||||||
|
|
||||||
|
|
||||||
func on_charge_updated(charge_ratio: float) -> void:
|
|
||||||
if not progress_bar:
|
|
||||||
return
|
|
||||||
|
|
||||||
progress_bar.value = charge_ratio
|
|
||||||
progress_bar.show()
|
|
||||||
|
|
||||||
|
|
||||||
func on_charge_stopped() -> void:
|
|
||||||
if not progress_bar:
|
|
||||||
return
|
|
||||||
|
|
||||||
progress_bar.hide()
|
|
||||||
|
|
||||||
|
|
||||||
func on_charge_started() -> void:
|
|
||||||
if not progress_bar:
|
|
||||||
return
|
|
||||||
|
|
||||||
progress_bar.show()
|
|
||||||
|
|
||||||
|
|
||||||
func setup_progress_bar() -> void:
|
|
||||||
if not progress_bar:
|
|
||||||
return
|
|
||||||
|
|
||||||
progress_bar.min_value = throw_input.min_power
|
|
||||||
progress_bar.max_value = throw_input.max_power
|
|
||||||
progress_bar.value = throw_input.min_power
|
|
||||||
progress_bar.step = 0.01
|
|
||||||
progress_bar.hide()
|
|
||||||
|
|
||||||
|
|
||||||
func setup_dependencies() -> void:
|
|
||||||
if not brick_throw_component:
|
|
||||||
return
|
|
||||||
|
|
||||||
if brick_throw_component.throw_input_behavior is ChargeThrowInputResource:
|
|
||||||
throw_input = brick_throw_component.throw_input_behavior as ChargeThrowInputResource
|
|
||||||
else:
|
|
||||||
throw_input = null
|
|
||||||
|
|
||||||
if not throw_input:
|
|
||||||
return
|
|
||||||
|
|
||||||
if not progress_bar:
|
|
||||||
return
|
|
||||||
|
|
||||||
if not throw_input.supports_charging():
|
|
||||||
progress_bar.hide()
|
|
||||||
return
|
|
||||||
|
|
||||||
setup_progress_bar()
|
|
||||||
|
|
||||||
throw_input.charge_started.connect(on_charge_started)
|
|
||||||
throw_input.charge_updated.connect(on_charge_updated)
|
|
||||||
throw_input.charge_stopped.connect(on_charge_stopped)
|
|
||||||
|
|
||||||
|
|
||||||
func on_nodes_changed(node: Node) -> void:
|
|
||||||
if node is BrickThrowComponent and brick_throw_component == null:
|
|
||||||
brick_throw_component = node as BrickThrowComponent
|
|
||||||
setup_dependencies()
|
|
||||||
return
|
|
@@ -1 +0,0 @@
|
|||||||
uid://q32rtephu1t1
|
|
@@ -1,6 +0,0 @@
|
|||||||
extends Control
|
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
|
||||||
if event.is_action_pressed("ui_cancel"):
|
|
||||||
if UiManager.is_screen_on_top(self):
|
|
||||||
UiManager.pop_screen()
|
|
@@ -1 +0,0 @@
|
|||||||
uid://dtjgndehihl6d
|
|
@@ -1,62 +0,0 @@
|
|||||||
class_name DeathScreen
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export var death_screen_root: Control
|
|
||||||
@export var current_level: LevelResource
|
|
||||||
@export var current_level_label: Label
|
|
||||||
@export var lives_left_label: Label
|
|
||||||
@export var timeout_time: float = 2.0
|
|
||||||
@export var nodes_to_disable: Array[Node] = []
|
|
||||||
|
|
||||||
@onready var gm: GM = $"/root/GameManager"
|
|
||||||
|
|
||||||
var timer: Timer
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
set_lables()
|
|
||||||
|
|
||||||
|
|
||||||
func set_lables() -> void:
|
|
||||||
if not gm:
|
|
||||||
return
|
|
||||||
|
|
||||||
current_level_label.text = current_level.level_name
|
|
||||||
lives_left_label.text = " x " + str(gm.get_lives())
|
|
||||||
|
|
||||||
|
|
||||||
func setup_timer() -> void:
|
|
||||||
timer = Timer.new()
|
|
||||||
timer.wait_time = timeout_time
|
|
||||||
timer.one_shot = true
|
|
||||||
timer.timeout.connect(on_timeout)
|
|
||||||
add_child(timer)
|
|
||||||
timer.start()
|
|
||||||
|
|
||||||
|
|
||||||
func toggle_nodes() -> void:
|
|
||||||
for node in nodes_to_disable:
|
|
||||||
if node.process_mode == PROCESS_MODE_DISABLED:
|
|
||||||
node.process_mode = PROCESS_MODE_INHERIT
|
|
||||||
else:
|
|
||||||
node.process_mode = PROCESS_MODE_DISABLED
|
|
||||||
|
|
||||||
|
|
||||||
func on_player_death() -> void:
|
|
||||||
if not gm:
|
|
||||||
return
|
|
||||||
|
|
||||||
toggle_nodes()
|
|
||||||
set_lables()
|
|
||||||
death_screen_root.show()
|
|
||||||
setup_timer()
|
|
||||||
|
|
||||||
|
|
||||||
func on_timeout() -> void:
|
|
||||||
if not gm:
|
|
||||||
return
|
|
||||||
|
|
||||||
if gm.get_lives() == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
get_tree().reload_current_scene()
|
|
@@ -1 +0,0 @@
|
|||||||
uid://b3d1p21sviww4
|
|
@@ -1,40 +0,0 @@
|
|||||||
class_name GameOverScreen
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export var game_over_screen: Control
|
|
||||||
@export var restart_button: Button
|
|
||||||
@export var main_menu_button: Button
|
|
||||||
@export var main_menu_scene: PackedScene
|
|
||||||
|
|
||||||
@onready var gm: GM = $"/root/GameManager"
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if not gm:
|
|
||||||
return
|
|
||||||
|
|
||||||
game_over_screen.hide()
|
|
||||||
restart_button.pressed.connect(on_restart_button_pressed)
|
|
||||||
main_menu_button.pressed.connect(on_main_menu_button_pressed)
|
|
||||||
|
|
||||||
|
|
||||||
func on_restart_button_pressed() -> void:
|
|
||||||
if not gm:
|
|
||||||
return
|
|
||||||
|
|
||||||
gm.restart_game()
|
|
||||||
|
|
||||||
|
|
||||||
func on_main_menu_button_pressed() -> void:
|
|
||||||
if not gm or not main_menu_scene:
|
|
||||||
return
|
|
||||||
|
|
||||||
gm.reset_player_state()
|
|
||||||
get_tree().change_scene_to(main_menu_scene)
|
|
||||||
|
|
||||||
|
|
||||||
func on_player_death() -> void:
|
|
||||||
if not gm or not gm.get_lives() == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
game_over_screen.show()
|
|
@@ -1 +0,0 @@
|
|||||||
uid://bkd7o2u4psu4p
|
|
@@ -1,51 +0,0 @@
|
|||||||
class_name Hud
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export var player_health: HealthComponent
|
|
||||||
@export var coins_label: Label
|
|
||||||
@export var health_progressbar: ProgressBar
|
|
||||||
@export var lives_label: Label
|
|
||||||
|
|
||||||
@onready var game_manager: GM = $"/root/GameManager"
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if not player_health:
|
|
||||||
var nodes := get_tree().get_nodes_in_group("player")
|
|
||||||
for node in nodes:
|
|
||||||
player_health = node.get_node_or_null("HealthComponent")
|
|
||||||
if player_health:
|
|
||||||
break
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
|
||||||
if not game_manager:
|
|
||||||
return
|
|
||||||
|
|
||||||
set_health_progressbar()
|
|
||||||
set_lives_label()
|
|
||||||
set_coins_label()
|
|
||||||
|
|
||||||
|
|
||||||
func set_coins_label() -> void:
|
|
||||||
if not game_manager:
|
|
||||||
return
|
|
||||||
|
|
||||||
#todo: set internationalized text
|
|
||||||
coins_label.text = tr("COINS_LABEL") + ":" + str(game_manager.get_coins())
|
|
||||||
|
|
||||||
|
|
||||||
func set_lives_label() -> void:
|
|
||||||
if not game_manager:
|
|
||||||
return
|
|
||||||
|
|
||||||
lives_label.text = tr("LIVES_LABEL") + ":" + str(game_manager.get_lives())
|
|
||||||
|
|
||||||
|
|
||||||
func set_health_progressbar() -> void:
|
|
||||||
if not player_health:
|
|
||||||
return
|
|
||||||
|
|
||||||
health_progressbar.value = player_health.health
|
|
||||||
health_progressbar.max_value = player_health.max_health
|
|
@@ -1 +0,0 @@
|
|||||||
uid://c3pde84b3kdco
|
|
@@ -1,115 +0,0 @@
|
|||||||
class_name InputSettings
|
|
||||||
extends Control
|
|
||||||
|
|
||||||
@export var input_button_scene: PackedScene = preload("res://objects/ui/input_button.tscn")
|
|
||||||
@export var action_list: Container
|
|
||||||
@export var reset_to_default_button: Button
|
|
||||||
|
|
||||||
@export var input_actions: Dictionary = {
|
|
||||||
'left': 'Move left',
|
|
||||||
'right': 'Move right',
|
|
||||||
'up': 'Move up',
|
|
||||||
'down': 'Move down',
|
|
||||||
'jump': 'Jump',
|
|
||||||
'attack': 'Attack',
|
|
||||||
'show_marketplace': "Toggle marketplace",
|
|
||||||
}
|
|
||||||
|
|
||||||
var is_remapping: bool = false
|
|
||||||
var action_to_remap = null
|
|
||||||
var remapping_button = null
|
|
||||||
var buttons: Array[Button] = []
|
|
||||||
|
|
||||||
@onready var config_file_handler = $'/root/ConfigFileHandler'
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
create_action_list()
|
|
||||||
|
|
||||||
if buttons.size() > 0:
|
|
||||||
buttons[0].grab_focus()
|
|
||||||
|
|
||||||
if reset_to_default_button:
|
|
||||||
reset_to_default_button.pressed.connect(on_reset_button_pressed)
|
|
||||||
|
|
||||||
|
|
||||||
func _input(event: InputEvent) -> void:
|
|
||||||
if is_remapping:
|
|
||||||
if event is InputEventKey or (event is InputEventMouseButton and event.pressed) or event is InputEventJoypadButton:
|
|
||||||
if event is InputEventMouseButton and event.double_click:
|
|
||||||
event.double_click = false
|
|
||||||
|
|
||||||
InputMap.action_erase_events(action_to_remap)
|
|
||||||
InputMap.action_add_event(action_to_remap, event)
|
|
||||||
update_action_list(remapping_button, event)
|
|
||||||
|
|
||||||
is_remapping = false
|
|
||||||
action_to_remap = null
|
|
||||||
remapping_button = null
|
|
||||||
|
|
||||||
accept_event()
|
|
||||||
|
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
|
||||||
if event.is_action_pressed("ui_cancel"):
|
|
||||||
if UiManager.is_screen_on_top(self):
|
|
||||||
UiManager.pop_screen()
|
|
||||||
save_settings()
|
|
||||||
load_settings()
|
|
||||||
|
|
||||||
|
|
||||||
func create_action_list() -> void:
|
|
||||||
InputMap.load_from_project_settings()
|
|
||||||
for item in action_list.get_children():
|
|
||||||
item.queue_free()
|
|
||||||
|
|
||||||
for action in input_actions:
|
|
||||||
var button := input_button_scene.instantiate() as Button
|
|
||||||
var action_label := button.find_child("LabelAction") as Label
|
|
||||||
var input_label := button.find_child("LabelInput") as Label
|
|
||||||
action_label.text = input_actions[action]
|
|
||||||
|
|
||||||
var events := InputMap.action_get_events(action)
|
|
||||||
if events.size() > 0:
|
|
||||||
input_label.text = events[0].as_text().trim_suffix(" (Physical)")
|
|
||||||
else:
|
|
||||||
input_label.text = "None"
|
|
||||||
|
|
||||||
action_list.add_child(button)
|
|
||||||
button.pressed.connect(on_input_button_pressed.bind(button, action))
|
|
||||||
buttons.append(button)
|
|
||||||
|
|
||||||
|
|
||||||
func on_input_button_pressed(button: Button, action) -> void:
|
|
||||||
if is_remapping:
|
|
||||||
return
|
|
||||||
|
|
||||||
is_remapping = true
|
|
||||||
action_to_remap = action
|
|
||||||
remapping_button = button
|
|
||||||
button.find_child("LabelInput").text = "Press any key..."
|
|
||||||
|
|
||||||
|
|
||||||
func update_action_list(button: Button, event: InputEvent) -> void:
|
|
||||||
button.find_child("LabelInput").text = event.as_text().trim_suffix(" (Physical)")
|
|
||||||
|
|
||||||
|
|
||||||
func on_reset_button_pressed() -> void:
|
|
||||||
create_action_list()
|
|
||||||
|
|
||||||
|
|
||||||
func save_settings() -> void:
|
|
||||||
config_file_handler.settings_config.set_value("input_settings", "input_actions", input_actions)
|
|
||||||
config_file_handler.settings_config.save(config_file_handler.SETTINGS_PATH)
|
|
||||||
|
|
||||||
|
|
||||||
func load_settings() -> void:
|
|
||||||
if not config_file_handler.settings_config.has_section("input_settings"):
|
|
||||||
return
|
|
||||||
|
|
||||||
var actions = config_file_handler.settings_config.get_value("input_settings", "input_actions", {})
|
|
||||||
if not actions:
|
|
||||||
return
|
|
||||||
|
|
||||||
input_actions = actions
|
|
||||||
create_action_list()
|
|
@@ -1 +0,0 @@
|
|||||||
uid://dppwl7xie2mh
|
|
@@ -1,64 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
@export var main_menu_control: Control
|
|
||||||
@export var new_game_button: Button
|
|
||||||
@export var continue_button: Button
|
|
||||||
@export var settings_button: Button
|
|
||||||
@export var credits_button: Button
|
|
||||||
@export var exit_button: Button
|
|
||||||
@export var version_label: Label
|
|
||||||
@export var settings_control: Control
|
|
||||||
@export var credits_control: Control
|
|
||||||
|
|
||||||
@onready var gm: GM = $"/root/GameManager"
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if new_game_button:
|
|
||||||
new_game_button.pressed.connect(_on_new_game_button_pressed)
|
|
||||||
if continue_button:
|
|
||||||
continue_button.pressed.connect(_on_continue_button_pressed)
|
|
||||||
if settings_button:
|
|
||||||
settings_button.pressed.connect(_on_settings_button_pressed)
|
|
||||||
if credits_button:
|
|
||||||
credits_button.pressed.connect(_on_credits_button_pressed)
|
|
||||||
if exit_button:
|
|
||||||
exit_button.pressed.connect(quit_game)
|
|
||||||
if version_label:
|
|
||||||
version_label.text = "v. " + ProjectSettings.get_setting("application/config/version")
|
|
||||||
|
|
||||||
if not SaveSystem.check_save_exists() and continue_button:
|
|
||||||
continue_button.disabled = true
|
|
||||||
else:
|
|
||||||
continue_button.disabled = false
|
|
||||||
|
|
||||||
continue_button.grab_focus()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_new_game_button_pressed() -> void:
|
|
||||||
if gm:
|
|
||||||
gm.start_new_game()
|
|
||||||
else:
|
|
||||||
printerr("GameManager not found. Cannot start new game.")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_continue_button_pressed() -> void:
|
|
||||||
if gm:
|
|
||||||
gm.continue_game()
|
|
||||||
else:
|
|
||||||
printerr("GameManager not found. Cannot continue game.")
|
|
||||||
|
|
||||||
|
|
||||||
func quit_game() -> void:
|
|
||||||
if gm:
|
|
||||||
gm.quit_game()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_settings_button_pressed() -> void:
|
|
||||||
if settings_control:
|
|
||||||
UiManager.push_screen(settings_control)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_credits_button_pressed() -> void:
|
|
||||||
if credits_control:
|
|
||||||
UiManager.push_screen(credits_control)
|
|
@@ -1 +0,0 @@
|
|||||||
uid://hyfvthdbgjbc
|
|
@@ -1,126 +0,0 @@
|
|||||||
class_name Marketplace
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export var root: Control
|
|
||||||
@export var skill_data: Array[SkillData] = []
|
|
||||||
@export var to_unlock_grid: GridContainer
|
|
||||||
@export var unlocked_grid: GridContainer
|
|
||||||
@export var font: Font
|
|
||||||
@export var skill_unlocker: SkillUnlockerComponent
|
|
||||||
@export var components_to_disable: Array[Node] = []
|
|
||||||
@export var marketplace_button: PackedScene
|
|
||||||
@export var skill_button: PackedScene
|
|
||||||
|
|
||||||
@onready var game_manager: GM = $"/root/GameManager"
|
|
||||||
|
|
||||||
var unlock_buttons: Array[Button] = []
|
|
||||||
var skill_buttons: Array[SkillButton] = []
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if not skill_unlocker:
|
|
||||||
return
|
|
||||||
|
|
||||||
var skills_to_unlock: Array[SkillData] = []
|
|
||||||
|
|
||||||
for skill in skill_data:
|
|
||||||
skills_to_unlock.append(skill)
|
|
||||||
|
|
||||||
for skill in skills_to_unlock:
|
|
||||||
create_upgrade_button(skill)
|
|
||||||
|
|
||||||
var unlocked_skills := game_manager.get_unlocked_skills()
|
|
||||||
for skill in unlocked_skills:
|
|
||||||
create_skill_button(skill)
|
|
||||||
|
|
||||||
skill_unlocker.skill_unlocked.connect(on_skill_unlocked)
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
|
||||||
for btn in skill_buttons:
|
|
||||||
if not btn.skill_data:
|
|
||||||
continue
|
|
||||||
if btn.skill_data.is_active:
|
|
||||||
btn.activate()
|
|
||||||
else:
|
|
||||||
btn.deactivate()
|
|
||||||
|
|
||||||
func _input(event: InputEvent) -> void:
|
|
||||||
if event.is_action_pressed("show_marketplace"):
|
|
||||||
if root.is_visible():
|
|
||||||
root.hide()
|
|
||||||
for component in components_to_disable:
|
|
||||||
component.process_mode = PROCESS_MODE_INHERIT
|
|
||||||
else:
|
|
||||||
root.show()
|
|
||||||
for component in components_to_disable:
|
|
||||||
component.process_mode = PROCESS_MODE_DISABLED
|
|
||||||
|
|
||||||
|
|
||||||
func get_button_text(skill: SkillData) -> String:
|
|
||||||
return tr(skill.name) + " " + str(skill.cost)
|
|
||||||
|
|
||||||
|
|
||||||
func create_upgrade_button(skill: SkillData) -> void:
|
|
||||||
var button := marketplace_button.instantiate() as MarketplaceButton
|
|
||||||
button.text = get_button_text(skill)
|
|
||||||
button.icon = skill.icon
|
|
||||||
button.skill_data = skill
|
|
||||||
|
|
||||||
button.pressed.connect(func () -> void: _on_button_pressed(skill))
|
|
||||||
|
|
||||||
unlock_buttons.append(button)
|
|
||||||
to_unlock_grid.add_child(button)
|
|
||||||
to_unlock_grid.queue_sort()
|
|
||||||
|
|
||||||
|
|
||||||
func create_skill_button(skill: SkillData) -> void:
|
|
||||||
var button := skill_button.instantiate() as SkillButton
|
|
||||||
button.skill_data = skill
|
|
||||||
button.setup()
|
|
||||||
button.pressed.connect(func() -> void: on_skill_button_pressed(button))
|
|
||||||
button.activate()
|
|
||||||
|
|
||||||
skill_buttons.append(button)
|
|
||||||
unlocked_grid.add_child(button)
|
|
||||||
unlocked_grid.queue_sort()
|
|
||||||
|
|
||||||
|
|
||||||
func remove_button(skill: SkillData):
|
|
||||||
for child in to_unlock_grid.get_children():
|
|
||||||
if child.text == get_button_text(skill):
|
|
||||||
child.queue_free()
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
func _on_button_pressed(skill: SkillData) -> void:
|
|
||||||
if not skill_unlocker:
|
|
||||||
return
|
|
||||||
|
|
||||||
if game_manager.is_skill_unlocked(skill):
|
|
||||||
if skill.level < skill.max_level:
|
|
||||||
skill_unlocker.try_upgrade_skill(skill)
|
|
||||||
if not skill.is_active:
|
|
||||||
skill_unlocker.skill_manager.toggle_skill_activation(skill)
|
|
||||||
else:
|
|
||||||
skill_unlocker.skill_manager.toggle_skill_activation(skill)
|
|
||||||
else:
|
|
||||||
skill_unlocker.try_unlock_skill(skill)
|
|
||||||
|
|
||||||
|
|
||||||
func on_skill_unlocked(skill: SkillData) -> void:
|
|
||||||
if not skill:
|
|
||||||
return
|
|
||||||
|
|
||||||
for btn in skill_buttons:
|
|
||||||
if btn.skill_data and btn.skill_data.name == skill.name:
|
|
||||||
return
|
|
||||||
|
|
||||||
create_skill_button(skill)
|
|
||||||
|
|
||||||
|
|
||||||
func on_skill_button_pressed(button: SkillButton) -> void:
|
|
||||||
if not skill_unlocker or not button.skill_data:
|
|
||||||
return
|
|
||||||
|
|
||||||
skill_unlocker.skill_manager.toggle_skill_activation(button.skill_data)
|
|
||||||
|
|
@@ -1 +0,0 @@
|
|||||||
uid://duifmqjarjpuv
|
|
@@ -1,48 +0,0 @@
|
|||||||
class_name MarketplaceButton
|
|
||||||
extends Button
|
|
||||||
|
|
||||||
@export var skill_data: SkillData
|
|
||||||
@export var unlocked_skill_icon: Texture2D
|
|
||||||
@export var locked_skill_icon: Texture2D
|
|
||||||
@export var skill_level_container: Container
|
|
||||||
|
|
||||||
@onready var gm: GM = $"/root/GameManager"
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if not skill_data:
|
|
||||||
printerr("MarketplaceButton: skill_data is not set.")
|
|
||||||
if not unlocked_skill_icon or not locked_skill_icon:
|
|
||||||
printerr("MarketplaceButton: unlocked_skill_icon or locked_skill_icon is not set.")
|
|
||||||
return
|
|
||||||
if not skill_level_container:
|
|
||||||
printerr("MarketplaceButton: skill_level_container is not set.")
|
|
||||||
return
|
|
||||||
|
|
||||||
setup()
|
|
||||||
|
|
||||||
var player := gm.get_player_node()
|
|
||||||
var skill_unlocker_component := player.get_node_or_null("SkillUnlockerComponent") as SkillUnlockerComponent
|
|
||||||
if skill_unlocker_component:
|
|
||||||
skill_unlocker_component.skill_unlocked.connect(_on_skill_unlock)
|
|
||||||
|
|
||||||
|
|
||||||
func setup() -> void:
|
|
||||||
if not skill_data:
|
|
||||||
return
|
|
||||||
|
|
||||||
for i in range(skill_data.max_level):
|
|
||||||
var _icon := TextureRect.new()
|
|
||||||
_icon.texture = unlocked_skill_icon if i < skill_data.level else locked_skill_icon
|
|
||||||
skill_level_container.add_child(_icon)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_skill_unlock(skill: SkillData) -> void:
|
|
||||||
if skill.name == skill_data.name:
|
|
||||||
for i in range(skill_data.max_level):
|
|
||||||
var icon := skill_level_container.get_child(i) as TextureRect
|
|
||||||
if i < skill.level:
|
|
||||||
icon.texture = unlocked_skill_icon
|
|
||||||
else:
|
|
||||||
icon.texture = locked_skill_icon
|
|
||||||
disabled = skill.level >= skill_data.max_level
|
|
@@ -1 +0,0 @@
|
|||||||
uid://dx8lex40lotr5
|
|
@@ -1,90 +0,0 @@
|
|||||||
class_name PauseMenu
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export var pause_menu_control: Control
|
|
||||||
@export var resume_button: Button
|
|
||||||
@export var quit_button: Button
|
|
||||||
@export var settings_button: Button
|
|
||||||
@export var exit_to_menu_button: Button
|
|
||||||
@export var settings_menu: Control
|
|
||||||
@export var exit_to_menu_scene: PackedScene
|
|
||||||
|
|
||||||
@onready var gm: GM = $"/root/GameManager"
|
|
||||||
|
|
||||||
var is_console_open: bool = false
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if not pause_menu_control:
|
|
||||||
printerr("PauseMenu: Pause menu control not set.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if not resume_button:
|
|
||||||
printerr("PauseMenu: Resume button not set.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if not quit_button:
|
|
||||||
printerr("PauseMenu: Quit button not set.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if not settings_button:
|
|
||||||
printerr("PauseMenu: Settings button not set.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if not exit_to_menu_button:
|
|
||||||
printerr("PauseMenu: Exit to menu button not set.")
|
|
||||||
return
|
|
||||||
|
|
||||||
pause_menu_control.hide()
|
|
||||||
|
|
||||||
resume_button.pressed.connect(_on_resume_button_pressed)
|
|
||||||
quit_button.pressed.connect(_on_quit_button_pressed)
|
|
||||||
settings_button.pressed.connect(_on_settings_button_pressed)
|
|
||||||
exit_to_menu_button.pressed.connect(_on_exit_to_menu_button_pressed)
|
|
||||||
Console.console_opened.connect(_on_console_open)
|
|
||||||
Console.console_closed.connect(_on_console_close)
|
|
||||||
|
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
|
||||||
if event.is_action_pressed("pause") and not is_console_open:
|
|
||||||
if UiManager.is_visible_on_stack(pause_menu_control):
|
|
||||||
_on_resume_button_pressed()
|
|
||||||
else:
|
|
||||||
UiManager.push_screen(pause_menu_control)
|
|
||||||
gm.pause_game()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_resume_button_pressed() -> void:
|
|
||||||
UiManager.pop_screen()
|
|
||||||
gm.resume_game()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_quit_button_pressed() -> void:
|
|
||||||
gm.quit_game()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_settings_button_pressed() -> void:
|
|
||||||
if not settings_menu:
|
|
||||||
printerr("PauseMenu: Settings menu scene not set.")
|
|
||||||
return
|
|
||||||
|
|
||||||
UiManager.push_screen(settings_menu)
|
|
||||||
gm.pause_game()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_exit_to_menu_button_pressed() -> void:
|
|
||||||
if not exit_to_menu_scene:
|
|
||||||
printerr("PauseMenu: Exit to menu scene not set.")
|
|
||||||
return
|
|
||||||
|
|
||||||
gm.resume_game()
|
|
||||||
gm.reset_current_session_state()
|
|
||||||
get_tree().change_scene_to_packed(exit_to_menu_scene)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_console_open():
|
|
||||||
is_console_open = true
|
|
||||||
|
|
||||||
|
|
||||||
func _on_console_close():
|
|
||||||
is_console_open = false
|
|
@@ -1 +0,0 @@
|
|||||||
uid://cugifchx6jhuk
|
|
@@ -1,70 +0,0 @@
|
|||||||
class_name SettingsMenu
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export var input_settings: Control
|
|
||||||
@export var audio_settings: Control
|
|
||||||
@export var display_settings: Control
|
|
||||||
@export var gameplay_settings: Control
|
|
||||||
@export var settings_menu_control: Control
|
|
||||||
@export var input_settings_button: Button
|
|
||||||
@export var audio_settings_button: Button
|
|
||||||
@export var display_settings_button: Button
|
|
||||||
@export var gameplay_settings_button: Button
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if not settings_menu_control or not input_settings_button or not audio_settings_button or not display_settings_button or not gameplay_settings_button:
|
|
||||||
printerr("No settings menu control or buttons found.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if input_settings:
|
|
||||||
input_settings_button.pressed.connect(_on_input_settings_button_pressed)
|
|
||||||
input_settings.hide()
|
|
||||||
|
|
||||||
if audio_settings:
|
|
||||||
audio_settings_button.pressed.connect(_on_audio_settings_button_pressed)
|
|
||||||
audio_settings.hide()
|
|
||||||
|
|
||||||
if display_settings:
|
|
||||||
display_settings_button.pressed.connect(_on_display_settings_button_pressed)
|
|
||||||
display_settings.hide()
|
|
||||||
|
|
||||||
if gameplay_settings:
|
|
||||||
gameplay_settings_button.pressed.connect(_on_gameplay_settings_button_pressed)
|
|
||||||
gameplay_settings.hide()
|
|
||||||
|
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
|
||||||
if event.is_action_pressed("ui_cancel"):
|
|
||||||
if UiManager.is_screen_on_top(settings_menu_control):
|
|
||||||
UiManager.pop_screen()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_input_settings_button_pressed() -> void:
|
|
||||||
if not input_settings:
|
|
||||||
return
|
|
||||||
|
|
||||||
UiManager.push_screen(input_settings)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_audio_settings_button_pressed() -> void:
|
|
||||||
if not audio_settings:
|
|
||||||
return
|
|
||||||
|
|
||||||
UiManager.push_screen(audio_settings)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_display_settings_button_pressed() -> void:
|
|
||||||
if not display_settings:
|
|
||||||
return
|
|
||||||
|
|
||||||
UiManager.push_screen(display_settings)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_gameplay_settings_button_pressed() -> void:
|
|
||||||
if not gameplay_settings:
|
|
||||||
return
|
|
||||||
|
|
||||||
UiManager.push_screen(gameplay_settings)
|
|
||||||
|
|
||||||
|
|
@@ -1 +0,0 @@
|
|||||||
uid://c506rigcjlm6x
|
|
@@ -1,22 +0,0 @@
|
|||||||
class_name SkillButton
|
|
||||||
extends Button
|
|
||||||
|
|
||||||
@export var skill_data: SkillData
|
|
||||||
|
|
||||||
|
|
||||||
func setup() -> void:
|
|
||||||
if not skill_data:
|
|
||||||
return
|
|
||||||
|
|
||||||
icon = skill_data.icon
|
|
||||||
text = tr(skill_data.name)
|
|
||||||
|
|
||||||
|
|
||||||
func activate() -> void:
|
|
||||||
set("theme_override_colors/font_color", Color("#49aa10"))
|
|
||||||
|
|
||||||
|
|
||||||
func deactivate() -> void:
|
|
||||||
set("theme_override_colors/font_color", Color("#ffffff"))
|
|
||||||
|
|
||||||
|
|
@@ -1 +0,0 @@
|
|||||||
uid://0obbehfd8fki
|
|
Reference in New Issue
Block a user