Compare commits
6 Commits
clean-code
...
54ffa8a42c
Author | SHA1 | Date | |
---|---|---|---|
54ffa8a42c | |||
ac477115c5 | |||
99473d1295 | |||
5dbf04cc5f | |||
4098d192af | |||
8467f67090 |
@@ -5,9 +5,7 @@ namespace Mr.BrickAdventures.Autoloads;
|
||||
public partial class ConfigFileHandler : Node
|
||||
{
|
||||
private ConfigFile _settingsConfig = new();
|
||||
public const string SettingsPath = "user://settings.ini";
|
||||
|
||||
public ConfigFile SettingsConfig => _settingsConfig;
|
||||
private const string SettingsPath = "user://settings.ini";
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
|
@@ -1 +0,0 @@
|
||||
uid://8cyvbeyd13cj
|
@@ -1,8 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Mr.BrickAdventures.scripts.components;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.Autoloads;
|
||||
@@ -10,10 +7,6 @@ namespace Mr.BrickAdventures.Autoloads;
|
||||
public partial class GameManager : Node
|
||||
{
|
||||
[Export] public Array<PackedScene> LevelScenes { get; set; } = new();
|
||||
|
||||
public PlayerController Player { get; set; }
|
||||
|
||||
private List<Node> _sceneNodes = new();
|
||||
|
||||
public Dictionary PlayerState { get; set; } = new()
|
||||
{
|
||||
@@ -25,35 +18,12 @@ public partial class GameManager : Node
|
||||
{ "unlocked_skills", new Array<SkillData>() }
|
||||
};
|
||||
|
||||
public Dictionary CurrentSessionState { get; private set; } = new()
|
||||
private Dictionary _currentSessionState = new()
|
||||
{
|
||||
{ "coins_collected", 0 },
|
||||
{ "skills_unlocked", new Array<SkillData>() }
|
||||
};
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
GetTree().NodeAdded += OnNodeAdded;
|
||||
GetTree().NodeRemoved += OnNodeRemoved;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
GetTree().NodeAdded -= OnNodeAdded;
|
||||
GetTree().NodeRemoved -= OnNodeRemoved;
|
||||
_sceneNodes.Clear();
|
||||
}
|
||||
|
||||
private void OnNodeAdded(Node node)
|
||||
{
|
||||
_sceneNodes.Add(node);
|
||||
}
|
||||
|
||||
private void OnNodeRemoved(Node node)
|
||||
{
|
||||
_sceneNodes.Remove(node);
|
||||
}
|
||||
|
||||
public void AddCoins(int amount)
|
||||
{
|
||||
PlayerState["coins"] = Mathf.Max(0, (int)PlayerState["coins"] + amount);
|
||||
@@ -61,19 +31,19 @@ public partial class GameManager : Node
|
||||
|
||||
public void SetCoins(int amount) => PlayerState["coins"] = Mathf.Max(0, amount);
|
||||
|
||||
public int GetCoins() => (int)PlayerState["coins"] + (int)CurrentSessionState["coins_collected"];
|
||||
public int GetCoins() => (int)PlayerState["coins"] + (int)_currentSessionState["coins_collected"];
|
||||
|
||||
public void RemoveCoins(int amount)
|
||||
{
|
||||
var sessionCoins = (int)CurrentSessionState["coins_collected"];
|
||||
var sessionCoins = (int)_currentSessionState["coins_collected"];
|
||||
if (amount <= sessionCoins)
|
||||
{
|
||||
CurrentSessionState["coins_collected"] = sessionCoins - amount;
|
||||
_currentSessionState["coins_collected"] = sessionCoins - amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
var remaining = amount - sessionCoins;
|
||||
CurrentSessionState["coins_collected"] = 0;
|
||||
_currentSessionState["coins_collected"] = 0;
|
||||
PlayerState["coins"] = Mathf.Max(0, (int)PlayerState["coins"] - remaining);
|
||||
}
|
||||
PlayerState["coins"] = Mathf.Max(0, (int)PlayerState["coins"]);
|
||||
@@ -87,7 +57,7 @@ public partial class GameManager : Node
|
||||
public bool IsSkillUnlocked(SkillData skill)
|
||||
{
|
||||
return ((Array)PlayerState["unlocked_skills"]).Contains(skill)
|
||||
|| ((Array)CurrentSessionState["skills_unlocked"]).Contains(skill);
|
||||
|| ((Array)_currentSessionState["skills_unlocked"]).Contains(skill);
|
||||
}
|
||||
|
||||
public void UnlockSkill(SkillData skill)
|
||||
@@ -153,7 +123,7 @@ public partial class GameManager : Node
|
||||
|
||||
public void ResetCurrentSessionState()
|
||||
{
|
||||
CurrentSessionState = new Dictionary
|
||||
_currentSessionState = new Dictionary
|
||||
{
|
||||
{ "coins_collected", 0 },
|
||||
{ "skills_unlocked", new Array<SkillData>() }
|
||||
@@ -202,8 +172,8 @@ public partial class GameManager : Node
|
||||
{
|
||||
var levelIndex = (int)PlayerState["current_level"];
|
||||
MarkLevelComplete(levelIndex);
|
||||
AddCoins((int)CurrentSessionState["coins_collected"]);
|
||||
foreach (var s in (Array)CurrentSessionState["skills_unlocked"])
|
||||
AddCoins((int)_currentSessionState["coins_collected"]);
|
||||
foreach (var s in (Array)_currentSessionState["skills_unlocked"])
|
||||
UnlockSkill((SkillData)s);
|
||||
|
||||
ResetCurrentSessionState();
|
||||
@@ -211,31 +181,15 @@ public partial class GameManager : Node
|
||||
GetNode<SaveSystem>("/root/SaveSystem").SaveGame();
|
||||
}
|
||||
|
||||
public Array<SkillData> GetUnlockedSkills()
|
||||
public Array GetUnlockedSkills()
|
||||
{
|
||||
var unlocked = (Array<SkillData>)PlayerState["unlocked_skills"];
|
||||
var session = (Array<SkillData>)CurrentSessionState["skills_unlocked"];
|
||||
if (session!.Count == 0) return unlocked;
|
||||
if (unlocked!.Count == 0) return session;
|
||||
var joined = new Array<SkillData>();
|
||||
joined.AddRange(unlocked);
|
||||
joined.AddRange(session);
|
||||
var session = (Array<SkillData>)_currentSessionState["skills_unlocked"];
|
||||
if ((((Array)session)!).Count == 0) return (Array)unlocked;
|
||||
if ((((Array)unlocked)!).Count == 0) return (Array)session;
|
||||
var joined = new Array();
|
||||
joined.AddRange((Array)unlocked ?? new Array());
|
||||
joined.AddRange((Array)session ?? new Array());
|
||||
return joined;
|
||||
}
|
||||
|
||||
public PlayerController GetPlayer()
|
||||
{
|
||||
if (Player != null) return Player;
|
||||
|
||||
foreach (var node in _sceneNodes)
|
||||
{
|
||||
if (node is not PlayerController player) continue;
|
||||
|
||||
Player = player;
|
||||
return Player;
|
||||
}
|
||||
|
||||
GD.PrintErr("PlayerController not found in the scene tree.");
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://c6eoi3ymefc0x
|
@@ -1,6 +1,5 @@
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.Autoloads;
|
||||
|
||||
@@ -9,28 +8,22 @@ public partial class SaveSystem : Node
|
||||
[Export] public string SavePath { get; set; } = "user://savegame.save";
|
||||
[Export] public int Version { get; set; } = 1;
|
||||
|
||||
private GameManager _gameManager;
|
||||
//private GM _gm;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_gameManager = GetNode<GameManager>("/root/GameManager");
|
||||
//_gm = GetNode<GM>("/root/GameManager");
|
||||
}
|
||||
|
||||
public void SaveGame()
|
||||
{
|
||||
var saveData = new Dictionary
|
||||
{
|
||||
{ "player_state", _gameManager.PlayerState},
|
||||
{ "version", Version}
|
||||
};
|
||||
|
||||
using var file = FileAccess.Open(SavePath, FileAccess.ModeFlags.Write);
|
||||
file.StoreVar(saveData);
|
||||
GD.Print("Game state saved to: ", SavePath);
|
||||
//TODO: Implement saving logic
|
||||
}
|
||||
|
||||
public bool LoadGame()
|
||||
{
|
||||
//TODO: Implement loading logic
|
||||
|
||||
if (!FileAccess.FileExists(SavePath))
|
||||
return false;
|
||||
|
||||
@@ -45,15 +38,7 @@ public partial class SaveSystem : Node
|
||||
|
||||
GD.Print("Game state loaded from: ", SavePath);
|
||||
GD.Print("Player state: ", saveDataObj["player_state"]);
|
||||
_gameManager.PlayerState = (Dictionary)saveDataObj["player_state"];
|
||||
|
||||
var skills = new Array<SkillData>();
|
||||
foreach (var skill in (Array<SkillData>)_gameManager.PlayerState["unlocked_skills"])
|
||||
{
|
||||
skills.Add(skill);
|
||||
}
|
||||
|
||||
_gameManager.UnlockSkills(skills);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -1 +0,0 @@
|
||||
uid://bh20fqbyifidc
|
@@ -1 +0,0 @@
|
||||
uid://c3ldmnrwperr4
|
@@ -5,9 +5,139 @@
|
||||
<RootNamespace>Mr.BrickAdventures</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Chickensoft.AutoInject" Version="2.8.21" />
|
||||
<PackageReference Include="Chickensoft.GodotNodeInterfaces" Version="2.4.31" />
|
||||
<PackageReference Include="Chickensoft.Introspection" Version="3.0.2" />
|
||||
<PackageReference Include="Chickensoft.Introspection.Generator" Version="3.0.2" PrivateAssets="all" OutputItemType="analyzer" />
|
||||
<Content Include="scripts\components\.idea\.gitignore" />
|
||||
<Content Include="scripts\components\.idea\encodings.xml" />
|
||||
<Content Include="scripts\components\.idea\indexLayout.xml" />
|
||||
<Content Include="scripts\components\.idea\inspectionProfiles\Project_Default.xml" />
|
||||
<Content Include="scripts\components\.idea\projectSettingsUpdater.xml" />
|
||||
<Content Include="scripts\components\.idea\vcs.xml" />
|
||||
<Content Include="scripts\components\.idea\workspace.xml" />
|
||||
<Content Include="scripts\components\BeamComponent.cs.uid" />
|
||||
<Content Include="scripts\components\beam_component.gd" />
|
||||
<Content Include="scripts\components\beam_component.gd.uid" />
|
||||
<Content Include="scripts\components\brick_throw.gd" />
|
||||
<Content Include="scripts\components\brick_throw.gd.uid" />
|
||||
<Content Include="scripts\components\bullet_component.gd" />
|
||||
<Content Include="scripts\components\bullet_component.gd.uid" />
|
||||
<Content Include="scripts\components\cage_component.gd" />
|
||||
<Content Include="scripts\components\cage_component.gd.uid" />
|
||||
<Content Include="scripts\components\cannot_stomp_component.gd" />
|
||||
<Content Include="scripts\components\cannot_stomp_component.gd.uid" />
|
||||
<Content Include="scripts\components\can_be_launched_component.gd" />
|
||||
<Content Include="scripts\components\can_be_launched_component.gd.uid" />
|
||||
<Content Include="scripts\components\can_pickup.gd" />
|
||||
<Content Include="scripts\components\can_pickup.gd.uid" />
|
||||
<Content Include="scripts\components\charge_throw_component.gd" />
|
||||
<Content Include="scripts\components\charge_throw_component.gd.uid" />
|
||||
<Content Include="scripts\components\chase_level_component.gd" />
|
||||
<Content Include="scripts\components\chase_level_component.gd.uid" />
|
||||
<Content Include="scripts\components\cleanup_component.gd" />
|
||||
<Content Include="scripts\components\cleanup_component.gd.uid" />
|
||||
<Content Include="scripts\components\collapsable.gd" />
|
||||
<Content Include="scripts\components\collapsable.gd.uid" />
|
||||
<Content Include="scripts\components\collectable.gd" />
|
||||
<Content Include="scripts\components\collectable.gd.uid" />
|
||||
<Content Include="scripts\components\damage_component.gd" />
|
||||
<Content Include="scripts\components\damage_component.gd.uid" />
|
||||
<Content Include="scripts\components\destroyable_component.gd" />
|
||||
<Content Include="scripts\components\destroyable_component.gd.uid" />
|
||||
<Content Include="scripts\components\effect_inflictor_component.gd" />
|
||||
<Content Include="scripts\components\effect_inflictor_component.gd.uid" />
|
||||
<Content Include="scripts\components\enemy_death.gd" />
|
||||
<Content Include="scripts\components\enemy_death.gd.uid" />
|
||||
<Content Include="scripts\components\enemy_wave_trigger.gd" />
|
||||
<Content Include="scripts\components\enemy_wave_trigger.gd.uid" />
|
||||
<Content Include="scripts\components\exit_door_component.gd" />
|
||||
<Content Include="scripts\components\exit_door_component.gd.uid" />
|
||||
<Content Include="scripts\components\explosive_component.gd" />
|
||||
<Content Include="scripts\components\explosive_component.gd.uid" />
|
||||
<Content Include="scripts\components\fade_away.gd" />
|
||||
<Content Include="scripts\components\fade_away.gd.uid" />
|
||||
<Content Include="scripts\components\fire_effect_component.gd" />
|
||||
<Content Include="scripts\components\fire_effect_component.gd.uid" />
|
||||
<Content Include="scripts\components\flashing_component.gd" />
|
||||
<Content Include="scripts\components\flashing_component.gd.uid" />
|
||||
<Content Include="scripts\components\flip_player.gd" />
|
||||
<Content Include="scripts\components\flip_player.gd.uid" />
|
||||
<Content Include="scripts\components\gravity_motion_component.gd" />
|
||||
<Content Include="scripts\components\gravity_motion_component.gd.uid" />
|
||||
<Content Include="scripts\components\health.gd" />
|
||||
<Content Include="scripts\components\health.gd.uid" />
|
||||
<Content Include="scripts\components\heal_component.gd" />
|
||||
<Content Include="scripts\components\heal_component.gd.uid" />
|
||||
<Content Include="scripts\components\hit_component.gd" />
|
||||
<Content Include="scripts\components\hit_component.gd.uid" />
|
||||
<Content Include="scripts\components\homing_missile_motion.gd" />
|
||||
<Content Include="scripts\components\homing_missile_motion.gd.uid" />
|
||||
<Content Include="scripts\components\ice_effect_component.gd" />
|
||||
<Content Include="scripts\components\ice_effect_component.gd.uid" />
|
||||
<Content Include="scripts\components\invulnerability_component.gd" />
|
||||
<Content Include="scripts\components\invulnerability_component.gd.uid" />
|
||||
<Content Include="scripts\components\jump_pad_component.gd" />
|
||||
<Content Include="scripts\components\jump_pad_component.gd.uid" />
|
||||
<Content Include="scripts\components\kill_player_out_of_screen.gd" />
|
||||
<Content Include="scripts\components\kill_player_out_of_screen.gd.uid" />
|
||||
<Content Include="scripts\components\knockback.gd" />
|
||||
<Content Include="scripts\components\knockback.gd.uid" />
|
||||
<Content Include="scripts\components\launch_component.gd" />
|
||||
<Content Include="scripts\components\launch_component.gd.uid" />
|
||||
<Content Include="scripts\components\lever_component.gd" />
|
||||
<Content Include="scripts\components\lever_component.gd.uid" />
|
||||
<Content Include="scripts\components\lifetime_component.gd" />
|
||||
<Content Include="scripts\components\lifetime_component.gd.uid" />
|
||||
<Content Include="scripts\components\magnetic_skill.gd" />
|
||||
<Content Include="scripts\components\magnetic_skill.gd.uid" />
|
||||
<Content Include="scripts\components\out_of_screen_component.gd" />
|
||||
<Content Include="scripts\components\out_of_screen_component.gd.uid" />
|
||||
<Content Include="scripts\components\periodic_shooting.gd" />
|
||||
<Content Include="scripts\components\periodic_shooting.gd.uid" />
|
||||
<Content Include="scripts\components\PlatformMovement.cs.uid" />
|
||||
<Content Include="scripts\components\platform_movement.gd" />
|
||||
<Content Include="scripts\components\platform_movement.gd.uid" />
|
||||
<Content Include="scripts\components\PlayerController.cs.uid" />
|
||||
<Content Include="scripts\components\player_death.gd" />
|
||||
<Content Include="scripts\components\player_death.gd.uid" />
|
||||
<Content Include="scripts\components\player_movement.gd" />
|
||||
<Content Include="scripts\components\player_movement.gd.uid" />
|
||||
<Content Include="scripts\components\progressive_damage_component.gd" />
|
||||
<Content Include="scripts\components\progressive_damage_component.gd.uid" />
|
||||
<Content Include="scripts\components\projectile_component.gd" />
|
||||
<Content Include="scripts\components\projectile_component.gd.uid" />
|
||||
<Content Include="scripts\components\projectile_init_component.gd" />
|
||||
<Content Include="scripts\components\projectile_init_component.gd.uid" />
|
||||
<Content Include="scripts\components\requirement_component.gd" />
|
||||
<Content Include="scripts\components\requirement_component.gd.uid" />
|
||||
<Content Include="scripts\components\score.gd" />
|
||||
<Content Include="scripts\components\score.gd.uid" />
|
||||
<Content Include="scripts\components\ship_movement.gd" />
|
||||
<Content Include="scripts\components\ship_movement.gd.uid" />
|
||||
<Content Include="scripts\components\ship_shooter.gd" />
|
||||
<Content Include="scripts\components\ship_shooter.gd.uid" />
|
||||
<Content Include="scripts\components\side_to_side_movement.gd" />
|
||||
<Content Include="scripts\components\side_to_side_movement.gd.uid" />
|
||||
<Content Include="scripts\components\skill_unlocker_component.gd" />
|
||||
<Content Include="scripts\components\skill_unlocker_component.gd.uid" />
|
||||
<Content Include="scripts\components\spaceship_enter_component.gd" />
|
||||
<Content Include="scripts\components\spaceship_enter_component.gd.uid" />
|
||||
<Content Include="scripts\components\spaceship_exit_component.gd" />
|
||||
<Content Include="scripts\components\spaceship_exit_component.gd.uid" />
|
||||
<Content Include="scripts\components\spin_component.gd" />
|
||||
<Content Include="scripts\components\spin_component.gd.uid" />
|
||||
<Content Include="scripts\components\status_effect_component.gd" />
|
||||
<Content Include="scripts\components\status_effect_component.gd.uid" />
|
||||
<Content Include="scripts\components\stomp_damage_component.gd" />
|
||||
<Content Include="scripts\components\stomp_damage_component.gd.uid" />
|
||||
<Content Include="scripts\components\straight_motion_component.gd" />
|
||||
<Content Include="scripts\components\straight_motion_component.gd.uid" />
|
||||
<Content Include="scripts\components\terrain_hit_fx.gd" />
|
||||
<Content Include="scripts\components\terrain_hit_fx.gd.uid" />
|
||||
<Content Include="scripts\components\tooltip_component.gd" />
|
||||
<Content Include="scripts\components\tooltip_component.gd.uid" />
|
||||
<Content Include="scripts\components\trail_component.gd" />
|
||||
<Content Include="scripts\components\trail_component.gd.uid" />
|
||||
<Content Include="scripts\components\trigger_lever_component.gd" />
|
||||
<Content Include="scripts\components\trigger_lever_component.gd.uid" />
|
||||
<Content Include="scripts\components\unlock_on_requirement_component.gd" />
|
||||
<Content Include="scripts\components\unlock_on_requirement_component.gd.uid" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -1,6 +1,4 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACanvasItem_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fef7b819b226fab796d1dfe66d415dd7510bcac87675020ddb8f03a828e763_003FCanvasItem_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACollisionShape2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F2ca9b7334678f5c97c7c2a9fbe4837be71cae11b6a30408dd4791b18f997e4a_003FCollisionShape2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANode2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F86db9cd834346aad02d74c1b66dd9c64d6ef3147435dd9c9c9477b48f7_003FNode2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARectangleShape2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fa1cc98873548652da0c14ecefa4737431426fcbb24a7f0641e3d9c266c3_003FRectangleShape2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AShape2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F3671dbbd9b17cdf2bf9075b468b6bd7e3ab13fc3be7a116484085d3b6cc9fe_003FShape2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
72
README.md
72
README.md
@@ -1,72 +0,0 @@
|
||||
# Przygody Pana Cegły
|
||||
|
||||
[](https://store.steampowered.com/app/3575090/Mr_Brick_Adventures/)
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
*"The world’s only brick-throwing dad simulator (probably)."*
|
||||
|
||||
---
|
||||
|
||||
## The Story
|
||||
|
||||
Disaster has struck!
|
||||
Mr. Brick’s kids have gone missing, scattered across mysterious lands filled with treacherous traps, cranky critters, and more collapsing bridges than an OSHA nightmare.
|
||||
|
||||
Armed with nothing but his legs, his wits, and an infinite supply of throwable bricks (don’t ask where he keeps them), Mr. Brick will stop at nothing to bring his children home.
|
||||
|
||||
---
|
||||
|
||||
## The Mission
|
||||
|
||||
Run, jump, and hurl bricks with pinpoint accuracy as you navigate dangerous worlds. Smash enemies, trigger ancient mechanisms, and uncover hidden treasures, all while dodging hazards that seem designed specifically to ruin your day.
|
||||
|
||||
---
|
||||
|
||||
## Features That’ll Knock Your Bricks Off
|
||||
|
||||
* **Tight, Classic Platforming**
|
||||
Leap over pits, time your jumps, and try not to land in something unpleasant.
|
||||
|
||||
* **Brick-Fu Combat**
|
||||
Toss bricks to flatten foes, flip switches, and solve puzzles in the most dad-like way possible.
|
||||
|
||||
* **Secrets & Collectibles**
|
||||
Hunt for coins, discover hidden rooms, and find upgrades to make you just a *little* less fragile.
|
||||
|
||||
* **NES-Inspired Pixel Art**
|
||||
All the charm of an 8-bit classic, no cartridge blowing required.
|
||||
|
||||
---
|
||||
|
||||
## Play It Here
|
||||
|
||||
[**Wishlist on Steam**](https://store.steampowered.com/app/3575090/Mr_Brick_Adventures/) so you’re ready for launch day.
|
||||
|
||||
---
|
||||
|
||||
## 📊 Project Stats
|
||||
📦 **Lines of Code:**
|
||||

|
||||
|
||||
📈 **Repo Activity:**
|
||||

|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
Check the [LICENSE](./LICENSE) for the legal stuff.
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Not open to code contributions right now but you *can* help by:
|
||||
|
||||
* Reporting bugs
|
||||
* Suggesting evil new trap ideas
|
||||
* Spreading the word so Mr. Brick can find his kids faster
|
@@ -1,10 +0,0 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.app;
|
||||
|
||||
public interface IGameScenes
|
||||
{
|
||||
void Load(PackedScene scene);
|
||||
void Restart();
|
||||
void ReturnToMain(PackedScene mainMenu);
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://b7d1ospa5p4nx
|
@@ -1,11 +0,0 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.app;
|
||||
|
||||
public interface ILevelCatalog
|
||||
{
|
||||
int Count { get; }
|
||||
PackedScene? Get(int index);
|
||||
PackedScene First { get; }
|
||||
PackedScene MainMenu { get; }
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://b2sxttgvk6nuq
|
@@ -1,70 +0,0 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Mr.BrickAdventures.app;
|
||||
using Mr.BrickAdventures.data;
|
||||
using Mr.BrickAdventures.game.repositories;
|
||||
using Mr.BrickAdventures.game.services;
|
||||
|
||||
namespace Mr.BrickAdventures.common;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class AppRoot : Node2D,
|
||||
IProvide<PlayerRepository>,
|
||||
IProvide<LevelRepository>,
|
||||
IProvide<SaveClient>,
|
||||
IProvide<SaveService>,
|
||||
IProvide<LevelService>,
|
||||
IProvide<IGameScenes>,
|
||||
IProvide<ILevelCatalog>,
|
||||
IGameScenes
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Export] private Array<PackedScene> _levels = [];
|
||||
[Export] private PackedScene _mainMenu = null!;
|
||||
|
||||
private readonly SaveClient _save = new("user://savegame.save", version: 2);
|
||||
private readonly PlayerRepository _players = new();
|
||||
private readonly LevelRepository _levelsRepo = new();
|
||||
private SaveService _saveService = null!;
|
||||
private LevelService _levelService = null!;
|
||||
private ILevelCatalog _catalog = null!;
|
||||
|
||||
PlayerRepository IProvide<PlayerRepository>.Value() => _players;
|
||||
LevelRepository IProvide<LevelRepository>.Value() => _levelsRepo;
|
||||
SaveClient IProvide<SaveClient>.Value() => _save;
|
||||
SaveService IProvide<SaveService>.Value() => _saveService;
|
||||
LevelService IProvide<LevelService>.Value() => _levelService;
|
||||
ILevelCatalog IProvide<ILevelCatalog>.Value() => _catalog;
|
||||
IGameScenes IProvide<IGameScenes>.Value() => this;
|
||||
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
_saveService = new SaveService(_players, _levelsRepo, _save);
|
||||
_levelService = new LevelService(_levelsRepo);
|
||||
|
||||
_catalog = new ExportedLevelCatalog(_levels, _mainMenu);
|
||||
|
||||
_saveService.TryLoad();
|
||||
this.Provide();
|
||||
}
|
||||
|
||||
public void Load(PackedScene scene) => GetTree().ChangeSceneToPacked(scene);
|
||||
public void Restart() => GetTree().ReloadCurrentScene();
|
||||
public void ReturnToMain(PackedScene mainMenu) => GetTree().ChangeSceneToPacked(mainMenu);
|
||||
|
||||
private sealed class ExportedLevelCatalog : ILevelCatalog
|
||||
{
|
||||
private readonly Array<PackedScene> _levels;
|
||||
public PackedScene MainMenu { get; }
|
||||
public ExportedLevelCatalog(Array<PackedScene> levels, PackedScene mainMenu) {
|
||||
_levels = levels; MainMenu = mainMenu;
|
||||
}
|
||||
public int Count => _levels.Count;
|
||||
public PackedScene? Get(int index) => (index >= 0 && index < _levels.Count) ? _levels[index] : null;
|
||||
public PackedScene First => _levels.Count > 0 ? _levels[0] : MainMenu;
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://dg2l7cw6da4vb
|
@@ -1,6 +0,0 @@
|
||||
namespace Mr.BrickAdventures.data;
|
||||
|
||||
public class ConfigClient
|
||||
{
|
||||
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://d3s774lnoljcu
|
@@ -1,103 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Mr.BrickAdventures.game.repositories;
|
||||
|
||||
namespace Mr.BrickAdventures.data;
|
||||
|
||||
public sealed class SaveClient
|
||||
{
|
||||
private readonly string _path;
|
||||
private readonly int _version;
|
||||
|
||||
public SaveClient(string path, int version) { _path = path; _version = version; }
|
||||
|
||||
public bool Exists() => FileAccess.FileExists(_path);
|
||||
|
||||
public bool TryLoad(out PlayerState player, out LevelState level) {
|
||||
player = null!; level = null!;
|
||||
if (!Exists()) return false;
|
||||
|
||||
using var f = FileAccess.Open(_path, FileAccess.ModeFlags.Read);
|
||||
var dict = (Dictionary)f.GetVar();
|
||||
|
||||
if ((int)dict.GetValueOrDefault("version", -1) != _version) return false;
|
||||
|
||||
player = ToPlayer((Dictionary)dict["player"]);
|
||||
level = ToLevel((Dictionary)dict["level"]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Strict load: requires version + player_state + level_state.
|
||||
// If anything is off, delete the file and act as "no save".
|
||||
public bool TryLoadStrict(out PlayerState player, out LevelState level) {
|
||||
player = default!;
|
||||
level = default!;
|
||||
|
||||
if (!Exists()) return false;
|
||||
|
||||
try {
|
||||
using var f = FileAccess.Open(_path, FileAccess.ModeFlags.Read);
|
||||
if (f == null) { Delete(); return false; }
|
||||
|
||||
var dictionary = (Dictionary)f.GetVar();
|
||||
|
||||
|
||||
if (!dictionary.TryGetValue("version", out var v) || (int)v != _version) { Delete(); return false; }
|
||||
|
||||
if (!dictionary.TryGetValue("player_state", out var pObj) || (Dictionary)pObj is not { } p) { Delete(); return false; }
|
||||
if (!dictionary.TryGetValue("level_state", out var lObj) || (Dictionary)lObj is not { } l) { Delete(); return false; }
|
||||
|
||||
player = ToPlayer(p);
|
||||
level = ToLevel(l);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
GD.PushWarning($"SaveClient: load failed — deleting bad save. {e.GetType().Name}: {e.Message}");
|
||||
Delete();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(PlayerState player, LevelState level) {
|
||||
using var f = FileAccess.Open(_path, FileAccess.ModeFlags.Write);
|
||||
var dict = new Dictionary {
|
||||
{ "version", _version },
|
||||
{ "player", FromPlayer(player) },
|
||||
{ "level", FromLevel(level) }
|
||||
};
|
||||
f.StoreVar(dict);
|
||||
}
|
||||
|
||||
public void Delete() {
|
||||
if (!Exists()) return;
|
||||
var abs = ProjectSettings.GlobalizePath(_path);
|
||||
var ok = DirAccess.RemoveAbsolute(abs);
|
||||
if (ok != Error.Ok) GD.PushWarning($"SaveClient: failed to delete {_path}: {ok}");
|
||||
}
|
||||
|
||||
private static Dictionary FromPlayer(PlayerState s) => new() { { "coins", s.Coins }, { "lives", s.Lives } };
|
||||
private static PlayerState ToPlayer(Dictionary d) => new() {
|
||||
Coins = d.TryGetValue("coins", out var c) ? (int)c : 0,
|
||||
Lives = d.TryGetValue("lives", out var l) ? (int)l : 3
|
||||
};
|
||||
|
||||
private static Dictionary FromLevel(LevelState s) => new() {
|
||||
{ "current", s.Current },
|
||||
{ "unlocked", new Array<int>(s.Unlocked) },
|
||||
{ "completed", new Array<int>(s.Completed) },
|
||||
};
|
||||
|
||||
private static LevelState ToLevel(Dictionary d) => new() {
|
||||
Current = d.TryGetValue("current", out var cur) ? (int)cur : 0,
|
||||
Unlocked = d.TryGetValue("unlocked", out var ul) && (Array<int>)ul is { } a1 ? a1.ToArray() : [0],
|
||||
Completed = d.TryGetValue("completed", out var cl) && (Array<int>)cl is { } a2 ? a2.ToArray() : [],
|
||||
};
|
||||
}
|
||||
|
||||
public record SaveSnapshot {
|
||||
public required PlayerState PlayerState { get; init; }
|
||||
public required LevelState LevelState { get; init; }
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://bsf45t7m2wa07
|
@@ -1,40 +0,0 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.app;
|
||||
using Mr.BrickAdventures.game.services;
|
||||
|
||||
namespace Mr.BrickAdventures.features.level;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class ExitDoorComponent : Area2D
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Export] public CollisionShape2D UnlockIndicator { get; set; } = null!;
|
||||
[Export] public bool Unlocked { get; set; } = false;
|
||||
|
||||
[Dependency] public LevelService Levels => this.DependOn<LevelService>();
|
||||
[Dependency] public ILevelCatalog Catalog => this.DependOn<ILevelCatalog>();
|
||||
[Dependency] public IGameScenes Scenes => this.DependOn<IGameScenes>();
|
||||
|
||||
public void OnReady() {
|
||||
BodyEntered += OnBodyEntered;
|
||||
UpdateVisuals();
|
||||
}
|
||||
|
||||
private void OnBodyEntered(Node body) {
|
||||
if (!Unlocked) return;
|
||||
if (body is not CharacterBody2D) return;
|
||||
|
||||
var nextIdx = Levels.CompleteAndAdvance();
|
||||
var next = Catalog.Get(nextIdx);
|
||||
if (next != null) Scenes.Load(next); else Scenes.ReturnToMain(Catalog.MainMenu);
|
||||
}
|
||||
|
||||
private void UpdateVisuals() {
|
||||
if (UnlockIndicator != null) UnlockIndicator.Disabled = !Unlocked;
|
||||
}
|
||||
|
||||
public void SetUnlocked(bool value) { Unlocked = value; UpdateVisuals(); }
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://ddh0jm0heqtc3
|
@@ -1,34 +0,0 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.game.repositories;
|
||||
using Mr.BrickAdventures.scripts.components;
|
||||
|
||||
namespace Mr.BrickAdventures.features.ui.hud;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class Hud : Node
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Export] public HealthComponent Health { get; set; } = null!;
|
||||
[Node] public Label CoinsLabel { get; set; } = null!;
|
||||
[Node] public ProgressBar HealthBar { get; set; } = null!;
|
||||
[Node] public Label LivesLabel { get; set; } = null!;
|
||||
|
||||
[Dependency] public PlayerRepository Player => this.DependOn<PlayerRepository>();
|
||||
|
||||
public void OnResolved() {
|
||||
CoinsLabel.Text = $"{Tr("COINS_LABEL")}: {Player.Coins}";
|
||||
LivesLabel.Text = $"{Tr("LIVES_LABEL")}: {Player.Lives}";
|
||||
|
||||
Player.CoinsChanged += c => CoinsLabel.Text = $"{Tr("COINS_LABEL")}: {c}";
|
||||
Player.LivesChanged += l => LivesLabel.Text = $"{Tr("LIVES_LABEL")}: {l}";
|
||||
|
||||
if (Health != null) {
|
||||
HealthBar.MaxValue = Health.MaxHealth;
|
||||
HealthBar.Value = Health.Health;
|
||||
Health.HealthChanged += (_, total) => { HealthBar.Value = total; };
|
||||
}
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://c1uwe5e1cfdxl
|
@@ -1,26 +0,0 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.app;
|
||||
|
||||
namespace Mr.BrickAdventures.features.ui.menus;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class GameOverScreen : Control
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Export] public Button RestartButton { get; set; } = null!;
|
||||
[Export] public Button MainMenuButton { get; set; } = null!;
|
||||
[Export] public PackedScene MainMenuScene { get; set; } = null!;
|
||||
|
||||
[Dependency] public IGameScenes Scenes => this.DependOn<IGameScenes>();
|
||||
|
||||
public void OnReady() {
|
||||
Visible = false;
|
||||
RestartButton.Pressed += () => Scenes.Restart();
|
||||
MainMenuButton.Pressed += () => Scenes.ReturnToMain(MainMenuScene);
|
||||
}
|
||||
|
||||
public void ShowGameOver() => Show();
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://b36jv878751ta
|
@@ -1,57 +0,0 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.app;
|
||||
using Mr.BrickAdventures.game.repositories;
|
||||
using Mr.BrickAdventures.game.services;
|
||||
|
||||
namespace Mr.BrickAdventures.features.ui.menus;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class MainMenu : Control
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Node] public Button NewGameButton { get; set; } = null!;
|
||||
[Node] public Button ContinueButton { get; set; } = null!;
|
||||
[Node] public Button SettingsButton { get; set; } = null!;
|
||||
[Node] public Button CreditsButton { get; set; } = null!;
|
||||
[Node] public Button ExitButton { get; set; } = null!;
|
||||
[Node] public Label VersionLabel { get; set; } = null!;
|
||||
[Export] public Control SettingsControl { get; set; } = null!;
|
||||
[Export] public Control CreditsControl { get; set; } = null!;
|
||||
|
||||
[Dependency] public SaveService Save => this.DependOn<SaveService>();
|
||||
[Dependency] public LevelRepository Levels => this.DependOn<LevelRepository>();
|
||||
[Dependency] public IGameScenes Scenes => this.DependOn<IGameScenes>();
|
||||
[Dependency] public ILevelCatalog Catalog => this.DependOn<ILevelCatalog>();
|
||||
|
||||
public void OnReady() {
|
||||
VersionLabel.Text = $"v. {ProjectSettings.GetSetting("application/config/version")}";
|
||||
|
||||
NewGameButton.Pressed += OnNewGamePressed;
|
||||
ContinueButton.Pressed += OnContinuePressed;
|
||||
SettingsButton.Pressed += () => SettingsControl.Show();
|
||||
CreditsButton.Pressed += () => CreditsControl.Show();
|
||||
ExitButton.Pressed += () => GetTree().Quit();
|
||||
}
|
||||
|
||||
public void OnResolved()
|
||||
{
|
||||
ContinueButton.Disabled = !Save.Exists();
|
||||
(ContinueButton.Disabled ? NewGameButton : ContinueButton).GrabFocus();
|
||||
}
|
||||
|
||||
private void OnNewGamePressed() {
|
||||
Save.NewGame();
|
||||
Levels.SetCurrent(0);
|
||||
var first = Catalog.First;
|
||||
Scenes.Load(first);
|
||||
}
|
||||
|
||||
private void OnContinuePressed() {
|
||||
if (!Save.TryLoad()) { OnNewGamePressed(); return; }
|
||||
var scene = Catalog.Get(Levels.Current) ?? Catalog.First;
|
||||
Scenes.Load(scene);
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://fcsg0e8s36in
|
@@ -1,33 +0,0 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.app;
|
||||
using Mr.BrickAdventures.game.services;
|
||||
|
||||
namespace Mr.BrickAdventures.features.ui.menus;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class PauseMenu : Control
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Export] public Button ResumeButton { get; set; } = null!;
|
||||
[Export] public Button RestartButton { get; set; } = null!;
|
||||
[Export] public Button MainMenuButton { get; set; } = null!;
|
||||
|
||||
[Dependency] public IGameScenes Scenes => this.DependOn<IGameScenes>();
|
||||
[Dependency] public ILevelCatalog Catalog => this.DependOn<ILevelCatalog>();
|
||||
[Dependency] public LevelService Levels => this.DependOn<LevelService>();
|
||||
|
||||
public void OnReady() {
|
||||
Visible = false;
|
||||
ResumeButton.Pressed += () => { GetTree().Paused = false; Hide(); };
|
||||
RestartButton.Pressed += () => { GetTree().Paused = false; Scenes.Restart(); };
|
||||
MainMenuButton.Pressed += () => { GetTree().Paused = false; Scenes.ReturnToMain(Catalog.MainMenu); };
|
||||
}
|
||||
|
||||
public void Toggle() {
|
||||
if (Visible) { GetTree().Paused = false; Hide(); }
|
||||
else { Show(); GetTree().Paused = true; }
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://bwgs02wcfnm8u
|
@@ -1,6 +0,0 @@
|
||||
namespace Mr.BrickAdventures.features.ui.settings;
|
||||
|
||||
public class AudioSettings
|
||||
{
|
||||
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://bnj36dhskiem
|
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Mr.BrickAdventures.game.repositories;
|
||||
|
||||
public sealed class LevelRepository
|
||||
{
|
||||
public int Current { get; private set; } = 0;
|
||||
public HashSet<int> Unlocked { get; } = new() { 0 };
|
||||
public HashSet<int> Completed { get; } = new();
|
||||
|
||||
public event Action<int>? CurrentChanged;
|
||||
|
||||
public void SetCurrent(int idx) { Current = idx; CurrentChanged?.Invoke(Current); }
|
||||
public void Unlock(int idx) => Unlocked.Add(idx);
|
||||
public void Complete(int idx) { Completed.Add(idx); Unlock(idx + 1); }
|
||||
|
||||
public LevelState Export() => new() {
|
||||
Current = Current, Unlocked = [..Unlocked], Completed = [..Completed]
|
||||
};
|
||||
public void Load(LevelState s) {
|
||||
Current = s.Current;
|
||||
Unlocked.Clear(); foreach (var i in s.Unlocked) Unlocked.Add(i);
|
||||
Completed.Clear(); foreach (var i in s.Completed) Completed.Add(i);
|
||||
CurrentChanged?.Invoke(Current);
|
||||
}
|
||||
}
|
||||
|
||||
public record LevelState {
|
||||
public int Current;
|
||||
public int[] Unlocked = [];
|
||||
public int[] Completed = [];
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://d0604lmwpadt5
|
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Mr.BrickAdventures.game.repositories;
|
||||
|
||||
public sealed class PlayerRepository
|
||||
{
|
||||
public int Coins { get; private set; } = 0;
|
||||
public int Lives { get; private set; } = 3;
|
||||
|
||||
public event Action<int>? CoinsChanged;
|
||||
public event Action<int>? LivesChanged;
|
||||
|
||||
public void SetCoins(int value) { Coins = Math.Max(0, value); CoinsChanged?.Invoke(Coins); }
|
||||
public void AddCoins(int amount) { SetCoins(Coins + amount); }
|
||||
public void RemoveCoins(int amount){ SetCoins(Coins - amount); }
|
||||
|
||||
public void SetLives(int value) { Lives = value; LivesChanged?.Invoke(Lives); }
|
||||
public void AddLives(int amount) { SetLives(Lives + amount); }
|
||||
public void RemoveLives(int amount){ SetLives(Lives - amount); }
|
||||
|
||||
public PlayerState Export() => new() { Coins = Coins, Lives = Lives };
|
||||
public void Load(PlayerState s) { SetCoins(s.Coins); SetLives(s.Lives); }
|
||||
}
|
||||
|
||||
public record PlayerState { public int Coins; public int Lives; }
|
@@ -1 +0,0 @@
|
||||
uid://d1dijkt574x4b
|
@@ -1,6 +0,0 @@
|
||||
namespace Mr.BrickAdventures.game.repositories;
|
||||
|
||||
public sealed class SessionRepository
|
||||
{
|
||||
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://b550hcqugygv0
|
@@ -1,6 +0,0 @@
|
||||
namespace Mr.BrickAdventures.game.repositories;
|
||||
|
||||
public class SettingsRepository
|
||||
{
|
||||
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://bk11iduo7bg2h
|
@@ -1,6 +0,0 @@
|
||||
namespace Mr.BrickAdventures.game.repositories;
|
||||
|
||||
public class SkillsRepository
|
||||
{
|
||||
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://cymx7mtmdblun
|
@@ -1,21 +0,0 @@
|
||||
using Mr.BrickAdventures.game.repositories;
|
||||
|
||||
namespace Mr.BrickAdventures.game.services;
|
||||
|
||||
public sealed class LevelService
|
||||
{
|
||||
private readonly LevelRepository _levels;
|
||||
public LevelService(LevelRepository levels) => _levels = levels;
|
||||
|
||||
public int CompleteAndAdvance() {
|
||||
var cur = _levels.Current;
|
||||
_levels.Complete(cur);
|
||||
var next = cur + 1;
|
||||
_levels.SetCurrent(next);
|
||||
return next;
|
||||
}
|
||||
|
||||
public void StartNew() {
|
||||
_levels.Load(new LevelState { Current = 0, Unlocked = new [] { 0 }, Completed = [] });
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://b2tsi3cjnh5xq
|
@@ -1,32 +0,0 @@
|
||||
using Mr.BrickAdventures.data;
|
||||
using Mr.BrickAdventures.game.repositories;
|
||||
|
||||
namespace Mr.BrickAdventures.game.services;
|
||||
|
||||
public sealed class SaveService
|
||||
{
|
||||
private readonly PlayerRepository _players;
|
||||
private readonly LevelRepository _levels;
|
||||
private readonly SaveClient _save;
|
||||
|
||||
public SaveService(PlayerRepository players, LevelRepository levels, SaveClient save) {
|
||||
_players = players; _levels = levels; _save = save;
|
||||
}
|
||||
|
||||
|
||||
public bool TryLoad() {
|
||||
if (!_save.TryLoad(out var p, out var l)) return false;
|
||||
_players.Load(p);
|
||||
_levels.Load(l);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Save() => _save.Save(_players.Export(), _levels.Export());
|
||||
public bool Exists() => _save.Exists();
|
||||
|
||||
public void NewGame() {
|
||||
_players.Load(new PlayerState { Coins = 0, Lives = 3 });
|
||||
_levels.Load(new LevelState { Current = 0, Unlocked = [0], Completed = [] });
|
||||
Save();
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://dxqkxlkkivxog
|
@@ -1,6 +0,0 @@
|
||||
namespace Mr.BrickAdventures.game.services;
|
||||
|
||||
public sealed class SkillService
|
||||
{
|
||||
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://dim21hs12wdi5
|
@@ -32,7 +32,7 @@
|
||||
[ext_resource type="PackedScene" uid="uid://bg76mtpcmfm2j" path="res://objects/ui/charging_bar_layer.tscn" id="28_3f5nm"]
|
||||
[ext_resource type="PackedScene" uid="uid://b12tppjkkqpt4" path="res://objects/fxs/hit_particles.tscn" id="28_jh5m0"]
|
||||
[ext_resource type="Script" uid="uid://ceq8n7yw7qxpi" path="res://scripts/components/hit_component.gd" id="29_jh5m0"]
|
||||
[ext_resource type="Script" uid="uid://cflncpa377l8l" path="res://scripts/components/platform_movement.gd" id="31_xoue7"]
|
||||
[ext_resource type="Script" uid="uid://c1wtrgw0x77xo" path="res://scripts/components/platform_movement.gd" id="31_xoue7"]
|
||||
[ext_resource type="AudioStream" uid="uid://dyev46uqusimi" path="res://sfx/shoot.wav" id="32_x2b7c"]
|
||||
[ext_resource type="Script" uid="uid://d1ctdx52gskv1" path="res://scripts/components/ship_shooter.gd" id="34_gwc8i"]
|
||||
[ext_resource type="PackedScene" uid="uid://dtem8jgcyoqar" path="res://objects/entities/green_laser.tscn" id="36_oxudy"]
|
||||
|
@@ -62,6 +62,9 @@ process_material = SubResource("ParticleProcessMaterial_lgb3u")
|
||||
|
||||
[node name="UI Layer" parent="." instance=ExtResource("2_lbnsn")]
|
||||
|
||||
[node name="HUD" parent="UI Layer" index="0" node_paths=PackedStringArray("player_health")]
|
||||
player_health = NodePath("../../Brick Player/HealthComponent")
|
||||
|
||||
[node name="DeathScreen" parent="UI Layer" index="1" node_paths=PackedStringArray("nodes_to_disable")]
|
||||
current_level = ExtResource("4_c2yv5")
|
||||
nodes_to_disable = [NodePath("../../Brick Player")]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=11 format=3 uid="uid://6foggu31cu14"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://byxf45ukq82pe" path="res://features/ui/hud/hud.tscn" id="1_tgtfe"]
|
||||
[ext_resource type="PackedScene" uid="uid://byxf45ukq82pe" path="res://objects/ui/hud.tscn" id="1_tgtfe"]
|
||||
[ext_resource type="PackedScene" uid="uid://dulkm3ah4tm0u" path="res://objects/ui/death_screen.tscn" id="2_ln68j"]
|
||||
[ext_resource type="Script" uid="uid://cp68km8bykymb" path="res://scripts/resources/level_resource.gd" id="3_5kt5k"]
|
||||
[ext_resource type="PackedScene" uid="uid://wmw6gaisyrvx" path="res://objects/ui/game_over_screen.tscn" id="4_11xmk"]
|
||||
@@ -34,8 +34,9 @@ visible = false
|
||||
offset_top = 32.0
|
||||
components_to_disable = [null]
|
||||
|
||||
[node name="Pause menu" parent="." instance=ExtResource("6_1q4vn")]
|
||||
[node name="Pause menu" parent="." node_paths=PackedStringArray("settings_menu") instance=ExtResource("6_1q4vn")]
|
||||
visible = false
|
||||
settings_menu = NodePath("../Settings menu")
|
||||
|
||||
[node name="Settings menu" parent="." node_paths=PackedStringArray("input_settings", "audio_settings") instance=ExtResource("7_hkjav")]
|
||||
visible = false
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[gd_scene load_steps=8 format=3 uid="uid://byxf45ukq82pe"]
|
||||
|
||||
[ext_resource type="LabelSettings" uid="uid://rvn5ivivfvv6" path="res://resources/ui/hud_label_settings.tres" id="1_4dsh5"]
|
||||
[ext_resource type="Script" uid="uid://c1uwe5e1cfdxl" path="res://features/ui/hud/Hud.cs" id="1_m4pq7"]
|
||||
[ext_resource type="Script" uid="uid://c3pde84b3kdco" path="res://scripts/ui/hud.gd" id="1_ueofj"]
|
||||
[ext_resource type="FontFile" uid="uid://xm0vbusjr7b7" path="res://fonts/PressStart2P-Regular.ttf" id="1_ygmwt"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_mmcdi"]
|
||||
@@ -16,7 +16,7 @@ bg_color = Color(0.47451, 0.47451, 0.47451, 1)
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_22dp1"]
|
||||
bg_color = Color(0.858824, 0.254902, 0.380392, 1)
|
||||
|
||||
[node name="HUD" type="Control"]
|
||||
[node name="HUD" type="Control" node_paths=PackedStringArray("coins_label", "health_progressbar", "lives_label")]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
@@ -25,7 +25,10 @@ grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
script = ExtResource("1_m4pq7")
|
||||
script = ExtResource("1_ueofj")
|
||||
coins_label = NodePath("PanelContainer/MarginContainer/HBoxContainer/Coins label")
|
||||
health_progressbar = NodePath("PanelContainer/MarginContainer/HBoxContainer/ProgressBar")
|
||||
lives_label = NodePath("PanelContainer/MarginContainer/HBoxContainer/Lives")
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="."]
|
||||
layout_mode = 1
|
||||
@@ -54,8 +57,7 @@ text = "HEALTH_LABEL"
|
||||
label_settings = ExtResource("1_4dsh5")
|
||||
uppercase = true
|
||||
|
||||
[node name="HealthBar" type="ProgressBar" parent="PanelContainer/MarginContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
[node name="ProgressBar" type="ProgressBar" parent="PanelContainer/MarginContainer/HBoxContainer"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
@@ -67,8 +69,7 @@ step = 0.1
|
||||
value = 60.0
|
||||
show_percentage = false
|
||||
|
||||
[node name="LivesLabel" type="Label" parent="PanelContainer/MarginContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
[node name="Lives" type="Label" parent="PanelContainer/MarginContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "LIVES_LABEL"
|
||||
@@ -76,8 +77,7 @@ label_settings = ExtResource("1_4dsh5")
|
||||
horizontal_alignment = 1
|
||||
uppercase = true
|
||||
|
||||
[node name="CoinsLabel" type="Label" parent="PanelContainer/MarginContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
[node name="Coins label" type="Label" parent="PanelContainer/MarginContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "COINS_LABEL"
|
@@ -1,18 +1,25 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://8b6ol5sssbgo"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://fcsg0e8s36in" path="res://features/ui/menus/MainMenu.cs" id="1_q8hru"]
|
||||
[ext_resource type="Script" uid="uid://hyfvthdbgjbc" path="res://scripts/ui/main_menu.gd" id="1_epxpl"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qv2q0"]
|
||||
bg_color = Color(0, 0, 0, 1)
|
||||
|
||||
[node name="MainMenu" type="Control"]
|
||||
[node name="MainMenu" type="Control" node_paths=PackedStringArray("main_menu_control", "new_game_button", "continue_button", "settings_button", "credits_button", "exit_button", "version_label")]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_q8hru")
|
||||
script = ExtResource("1_epxpl")
|
||||
main_menu_control = NodePath(".")
|
||||
new_game_button = NodePath("PanelContainer/MarginContainer/VBoxContainer/NewGameButton")
|
||||
continue_button = NodePath("PanelContainer/MarginContainer/VBoxContainer/ContinueButton")
|
||||
settings_button = NodePath("PanelContainer/MarginContainer/VBoxContainer/SettingsButton")
|
||||
credits_button = NodePath("PanelContainer/MarginContainer/VBoxContainer/CreditsButton")
|
||||
exit_button = NodePath("PanelContainer/MarginContainer/VBoxContainer/QuitButton")
|
||||
version_label = NodePath("PanelContainer/MarginContainer/VBoxContainer/version")
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="."]
|
||||
layout_mode = 1
|
||||
@@ -46,37 +53,31 @@ layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="ContinueButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "CONTINUE_BUTTON"
|
||||
flat = true
|
||||
|
||||
[node name="NewGameButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "NEW_GAME_BUTTON"
|
||||
flat = true
|
||||
|
||||
[node name="SettingsButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "SETTINGS_BUTTON"
|
||||
flat = true
|
||||
|
||||
[node name="CreditsButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "CREDITS_BUTTON"
|
||||
flat = true
|
||||
|
||||
[node name="ExitButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
[node name="QuitButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "QUIT_BUTTON"
|
||||
flat = true
|
||||
|
||||
[node name="VersionLabel" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
[node name="version" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 8
|
@@ -1,11 +1,12 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://i6mnjbjcoqe5"]
|
||||
[gd_scene load_steps=4 format=3 uid="uid://i6mnjbjcoqe5"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bwgs02wcfnm8u" path="res://features/ui/menus/PauseMenu.cs" id="1_ljtns"]
|
||||
[ext_resource type="Script" uid="uid://cugifchx6jhuk" path="res://scripts/ui/pause_menu.gd" id="1_aktha"]
|
||||
[ext_resource type="PackedScene" uid="uid://cl00e2ocomk3m" path="res://scenes/main_menu.tscn" id="2_h4pd5"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_g4ivv"]
|
||||
bg_color = Color(0, 0, 0, 1)
|
||||
|
||||
[node name="Pause menu" type="Control" node_paths=PackedStringArray("ResumeButton", "RestartButton", "MainMenuButton")]
|
||||
[node name="Pause menu" type="Control" node_paths=PackedStringArray("pause_menu_control", "resume_button", "quit_button", "settings_button", "exit_to_menu_button")]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
@@ -14,10 +15,13 @@ grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
script = ExtResource("1_ljtns")
|
||||
ResumeButton = NodePath("PanelContainer/MarginContainer/VBoxContainer/Resume Button")
|
||||
RestartButton = NodePath("PanelContainer/MarginContainer/VBoxContainer/Settings Button")
|
||||
MainMenuButton = NodePath("PanelContainer/MarginContainer/VBoxContainer/Exit to menu Button")
|
||||
script = ExtResource("1_aktha")
|
||||
pause_menu_control = NodePath(".")
|
||||
resume_button = NodePath("PanelContainer/MarginContainer/VBoxContainer/Resume Button")
|
||||
quit_button = NodePath("PanelContainer/MarginContainer/VBoxContainer/Quit game Button")
|
||||
settings_button = NodePath("PanelContainer/MarginContainer/VBoxContainer/Settings Button")
|
||||
exit_to_menu_button = NodePath("PanelContainer/MarginContainer/VBoxContainer/Exit to menu Button")
|
||||
exit_to_menu_scene = ExtResource("2_h4pd5")
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="."]
|
||||
layout_mode = 1
|
||||
|
@@ -66,6 +66,9 @@ process_material = SubResource("ParticleProcessMaterial_lgb3u")
|
||||
|
||||
[node name="UI Layer" parent="." instance=ExtResource("3_4fsls")]
|
||||
|
||||
[node name="HUD" parent="UI Layer" index="0" node_paths=PackedStringArray("player_health")]
|
||||
player_health = NodePath("../../Brick Player/HealthComponent")
|
||||
|
||||
[node name="DeathScreen" parent="UI Layer" index="1" node_paths=PackedStringArray("nodes_to_disable")]
|
||||
current_level = ExtResource("4_onnch")
|
||||
nodes_to_disable = [NodePath("../../Brick Player")]
|
||||
|
@@ -1,38 +1,27 @@
|
||||
[gd_scene load_steps=12 format=3 uid="uid://cl00e2ocomk3m"]
|
||||
[gd_scene load_steps=6 format=3 uid="uid://cl00e2ocomk3m"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://8b6ol5sssbgo" path="res://features/ui/menus/main_menu.tscn" id="1_ekxnf"]
|
||||
[ext_resource type="Script" uid="uid://dg2l7cw6da4vb" path="res://common/AppRoot.cs" id="1_rtw2f"]
|
||||
[ext_resource type="PackedScene" uid="uid://8b6ol5sssbgo" path="res://objects/ui/main_menu.tscn" id="1_ekxnf"]
|
||||
[ext_resource type="PackedScene" uid="uid://y0ae6e7t70fj" path="res://objects/ui/settings_menu.tscn" id="2_bqqt6"]
|
||||
[ext_resource type="PackedScene" uid="uid://bwgmrcyj4mvu" path="res://objects/ui/credits.tscn" id="3_bqqt6"]
|
||||
[ext_resource type="PackedScene" uid="uid://chqb11pfoqmeb" path="res://scenes/level_village_2.tscn" id="3_lgwnu"]
|
||||
[ext_resource type="PackedScene" uid="uid://bol7g83v2accs" path="res://scenes/level_village_1.tscn" id="3_oa1go"]
|
||||
[ext_resource type="PackedScene" uid="uid://b5fx1vdfky307" path="res://objects/ui/audio_settings.tscn" id="4_8ln24"]
|
||||
[ext_resource type="PackedScene" uid="uid://h60obxmju6mo" path="res://scenes/level_village_3.tscn" id="4_flqon"]
|
||||
[ext_resource type="PackedScene" uid="uid://bhad760x3vvco" path="res://scenes/level_village_4.tscn" id="5_rcqid"]
|
||||
[ext_resource type="PackedScene" uid="uid://cvfsbiy5ggrpg" path="res://objects/ui/input_settings.tscn" id="5_rtw2f"]
|
||||
[ext_resource type="PackedScene" uid="uid://dagpmlgvr262d" path="res://scenes/level_forest_5.tscn" id="6_1ajci"]
|
||||
|
||||
[node name="AppRoot" type="Node2D"]
|
||||
script = ExtResource("1_rtw2f")
|
||||
_levels = Array[PackedScene]([ExtResource("3_oa1go"), ExtResource("3_lgwnu"), ExtResource("4_flqon"), ExtResource("5_rcqid"), ExtResource("6_1ajci")])
|
||||
_mainMenu = null
|
||||
[node name="Main menu" type="CanvasLayer"]
|
||||
|
||||
[node name="Main menu" type="CanvasLayer" parent="."]
|
||||
[node name="MainMenu" parent="." node_paths=PackedStringArray("settings_control", "credits_control") instance=ExtResource("1_ekxnf")]
|
||||
settings_control = NodePath("../Settings menu")
|
||||
credits_control = NodePath("../Credits")
|
||||
|
||||
[node name="MainMenu" parent="Main menu" node_paths=PackedStringArray("SettingsControl", "CreditsControl") instance=ExtResource("1_ekxnf")]
|
||||
SettingsControl = NodePath("../Settings menu")
|
||||
CreditsControl = NodePath("../Credits")
|
||||
|
||||
[node name="Settings menu" parent="Main menu" node_paths=PackedStringArray("input_settings", "audio_settings") instance=ExtResource("2_bqqt6")]
|
||||
[node name="Settings menu" parent="." node_paths=PackedStringArray("input_settings", "audio_settings") instance=ExtResource("2_bqqt6")]
|
||||
visible = false
|
||||
input_settings = NodePath("../Input Settings")
|
||||
audio_settings = NodePath("../Audio settings")
|
||||
|
||||
[node name="Credits" parent="Main menu" instance=ExtResource("3_bqqt6")]
|
||||
[node name="Credits" parent="." instance=ExtResource("3_bqqt6")]
|
||||
visible = false
|
||||
|
||||
[node name="Audio settings" parent="Main menu" instance=ExtResource("4_8ln24")]
|
||||
[node name="Audio settings" parent="." instance=ExtResource("4_8ln24")]
|
||||
visible = false
|
||||
|
||||
[node name="Input Settings" parent="Main menu" instance=ExtResource("5_rtw2f")]
|
||||
[node name="Input Settings" parent="." instance=ExtResource("5_rtw2f")]
|
||||
visible = false
|
||||
|
@@ -1,70 +0,0 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
public partial class ChargeThrowInputResource : ThrowInputResource
|
||||
{
|
||||
[Export] public float MinPower { get; set; } = 0.5f;
|
||||
[Export] public float MaxPower { get; set; } = 2.0f;
|
||||
[Export] public float MaxChargeTime { get; set; } = 2.0f;
|
||||
[Export] public float MinChargeDuration { get; set; } = 0.1f;
|
||||
|
||||
private bool _isCharging = false;
|
||||
private float _chargeStartTime = 0f;
|
||||
|
||||
[Signal] public delegate void ChargeStartedEventHandler();
|
||||
[Signal] public delegate void ChargeUpdatedEventHandler(float chargeRatio);
|
||||
[Signal] public delegate void ChargeStoppedEventHandler();
|
||||
|
||||
public override void ProcessInput(InputEvent @event)
|
||||
{
|
||||
if (@event.IsActionPressed("attack"))
|
||||
{
|
||||
_isCharging = true;
|
||||
_chargeStartTime = Time.GetTicksMsec() / 1000f;
|
||||
EmitSignalChargeStarted();
|
||||
}
|
||||
|
||||
if (@event.IsActionReleased("attack") && _isCharging)
|
||||
{
|
||||
var power = CalculatePower();
|
||||
_isCharging = false;
|
||||
EmitSignalThrowRequested(power);
|
||||
EmitSignalChargeStopped();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(double delta)
|
||||
{
|
||||
if (!_isCharging) return;
|
||||
|
||||
var t = Mathf.Clamp(GetChargeRatio(), MinPower, MaxPower);
|
||||
EmitSignalChargeUpdated(t);
|
||||
}
|
||||
|
||||
public override bool SupportsCharging()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private float CalculatePower()
|
||||
{
|
||||
var now = Time.GetTicksMsec() / 1000f;
|
||||
var heldTime = now - _chargeStartTime;
|
||||
if (heldTime < MinChargeDuration)
|
||||
return MinPower;
|
||||
|
||||
var t = Mathf.Clamp(heldTime / MaxChargeTime, 0f, 1f);
|
||||
return Mathf.Lerp(MinPower, MaxPower, t);
|
||||
}
|
||||
|
||||
private float GetChargeRatio()
|
||||
{
|
||||
if (!_isCharging) return MinPower;
|
||||
|
||||
var now = Time.GetTicksMsec() / 1000f;
|
||||
var heldTime = now - _chargeStartTime;
|
||||
var t = Mathf.Clamp(heldTime / MaxChargeTime, 0f, 1f);
|
||||
return Mathf.Lerp(MinPower, MaxPower, t);
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://dtpdh4jp51jis
|
@@ -1 +0,0 @@
|
||||
uid://gptsgaw3agkf
|
@@ -1 +0,0 @@
|
||||
uid://2ql8wj3vfeke
|
@@ -6,9 +6,9 @@ namespace Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
public partial class SkillData : Resource
|
||||
{
|
||||
[Export] public string Name { get; set; } = "New Skill";
|
||||
[Export] public string Description { get; set; } = "New Skill";
|
||||
[Export] public Dictionary<string, Variant> Config { get; set; } = new();
|
||||
[Export] public String Name { get; set; } = "New Skill";
|
||||
[Export] public String Description { get; set; } = "New Skill";
|
||||
[Export] public Dictionary<String, Variant> Config { get; set; } = new();
|
||||
[Export] public int Cost { get; set; } = 0;
|
||||
[Export] public Texture2D Icon { get; set; }
|
||||
[Export] public bool IsActive { get; set; } = false;
|
||||
|
@@ -1 +0,0 @@
|
||||
uid://d4crrfmbgxnqf
|
@@ -1 +0,0 @@
|
||||
uid://sma20qug2r0q
|
@@ -1 +0,0 @@
|
||||
uid://pw0pu6gb21y2
|
@@ -1 +0,0 @@
|
||||
uid://b0a7k7mse3l68
|
@@ -1,20 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.scripts.interfaces;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
public partial class TapThrowInputResource : ThrowInputResource
|
||||
{
|
||||
public override void Update(double delta)
|
||||
{
|
||||
if (Input.IsActionPressed("attack"))
|
||||
{
|
||||
EmitSignalThrowRequested(1f);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool SupportsCharging()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://cx7ryqxemgs56
|
@@ -1,24 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.scripts.interfaces;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
public abstract partial class ThrowInputResource : Resource, IThrowInput
|
||||
{
|
||||
[Signal] public delegate void ThrowRequestedEventHandler(float powerMultiplier = 1f);
|
||||
|
||||
public virtual void ProcessInput(InputEvent @event)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual void Update(double delta)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual bool SupportsCharging()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://mnn5wy5cyr4m
|
@@ -1 +0,0 @@
|
||||
uid://chrhjch4ymfvr
|
@@ -1 +0,0 @@
|
||||
uid://di572axt0c3s8
|
@@ -1,102 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class AudioSettings : Node
|
||||
{
|
||||
[Export] public Slider MasterVolumeSlider { get; set; }
|
||||
[Export] public Slider MusicVolumeSlider { get; set; }
|
||||
[Export] public Slider SfxVolumeSlider { get; set; }
|
||||
[Export] public Control AudioSettingsControl { get; set; }
|
||||
[Export] public float MuteThreshold { get; set; } = -20f;
|
||||
|
||||
private UIManager _uiManager;
|
||||
private ConfigFileHandler _configFileHandler;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_uiManager = GetNode<UIManager>("/root/UIManager");
|
||||
_configFileHandler = GetNode<ConfigFileHandler>("/root/ConfigFileHandler");
|
||||
Initialize();
|
||||
MasterVolumeSlider.ValueChanged += OnMasterVolumeChanged;
|
||||
MusicVolumeSlider.ValueChanged += OnMusicVolumeChanged;
|
||||
SfxVolumeSlider.ValueChanged += OnSfxVolumeChanged;
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (!@event.IsActionReleased("ui_cancel")) return;
|
||||
if (!_uiManager.IsScreenOnTop(AudioSettingsControl)) return;
|
||||
|
||||
SaveSettings();
|
||||
_uiManager.PopScreen();
|
||||
}
|
||||
|
||||
private void OnSfxVolumeChanged(double value)
|
||||
{
|
||||
AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("sfx"), (float)value);
|
||||
HandleMute(AudioServer.GetBusIndex("sfx"), (float)value);
|
||||
}
|
||||
|
||||
private void OnMusicVolumeChanged(double value)
|
||||
{
|
||||
AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("music"), (float)value);
|
||||
HandleMute(AudioServer.GetBusIndex("music"), (float)value);
|
||||
}
|
||||
|
||||
private void OnMasterVolumeChanged(double value)
|
||||
{
|
||||
AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Master"), (float)value);
|
||||
HandleMute(AudioServer.GetBusIndex("Master"), (float)value);
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
var volumeDb = AudioServer.GetBusVolumeDb(AudioServer.GetBusIndex("Master"));
|
||||
MasterVolumeSlider.Value = volumeDb;
|
||||
MasterVolumeSlider.MinValue = MuteThreshold;
|
||||
MasterVolumeSlider.MaxValue = 0f;
|
||||
|
||||
var musicVolumeDb = AudioServer.GetBusVolumeDb(AudioServer.GetBusIndex("music"));
|
||||
MusicVolumeSlider.Value = musicVolumeDb;
|
||||
MusicVolumeSlider.MinValue = MuteThreshold;
|
||||
MusicVolumeSlider.MaxValue = 0f;
|
||||
|
||||
var sfxVolumeDb = AudioServer.GetBusVolumeDb(AudioServer.GetBusIndex("sfx"));
|
||||
SfxVolumeSlider.Value = sfxVolumeDb;
|
||||
SfxVolumeSlider.MinValue = MuteThreshold;
|
||||
SfxVolumeSlider.MaxValue = 0f;
|
||||
}
|
||||
|
||||
private void HandleMute(int busIndex, float value)
|
||||
{
|
||||
AudioServer.SetBusMute(busIndex, value <= MuteThreshold);
|
||||
}
|
||||
|
||||
private void SaveSettings()
|
||||
{
|
||||
var settingsConfig = _configFileHandler.SettingsConfig;
|
||||
settingsConfig.SetValue("audio_settings", "master_volume", MasterVolumeSlider.Value);
|
||||
settingsConfig.SetValue("audio_settings", "music_volume", MusicVolumeSlider.Value);
|
||||
settingsConfig.SetValue("audio_settings", "sfx_volume", SfxVolumeSlider.Value);
|
||||
settingsConfig.SetValue("audio_settings", "mute_threshold", MuteThreshold);
|
||||
settingsConfig.Save(ConfigFileHandler.SettingsPath);
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
var settingsConfig = _configFileHandler.SettingsConfig;
|
||||
if (!settingsConfig.HasSection("audio_settings")) return;
|
||||
|
||||
var masterVolume = (float)settingsConfig.GetValue("audio_settings", "master_volume", MasterVolumeSlider.Value);
|
||||
var musicVolume = (float)settingsConfig.GetValue("audio_settings", "music_volume", MusicVolumeSlider.Value);
|
||||
var sfxVolume = (float)settingsConfig.GetValue("audio_settings", "sfx_volume", SfxVolumeSlider.Value);
|
||||
var muteThreshold = (float)settingsConfig.GetValue("audio_settings", "mute_threshold", MuteThreshold);
|
||||
|
||||
MasterVolumeSlider.Value = masterVolume;
|
||||
MusicVolumeSlider.Value = musicVolume;
|
||||
SfxVolumeSlider.Value = sfxVolume;
|
||||
MuteThreshold = muteThreshold;
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://g61qqsymqfxd
|
@@ -1,81 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.scripts.components;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class ChargeProgressBar : Node
|
||||
{
|
||||
[Export] public ProgressBar ProgressBar { get; set; }
|
||||
[Export] public BrickThrowComponent ThrowComponent { get; set; }
|
||||
|
||||
private ChargeThrowInputResource _throwInput;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
Owner.ChildEnteredTree += OnNodeEntered;
|
||||
ProgressBar.Hide();
|
||||
SetupDependencies();
|
||||
}
|
||||
|
||||
private void OnNodeEntered(Node node)
|
||||
{
|
||||
if (node is not BrickThrowComponent throwComponent || ThrowComponent != null) return;
|
||||
ThrowComponent = throwComponent;
|
||||
SetupDependencies();
|
||||
}
|
||||
|
||||
private void SetupDependencies()
|
||||
{
|
||||
if (ThrowComponent.ThrowInputBehavior is ChargeThrowInputResource throwInput)
|
||||
{
|
||||
_throwInput = throwInput;
|
||||
}
|
||||
else
|
||||
{
|
||||
_throwInput = null;
|
||||
}
|
||||
|
||||
if (_throwInput == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_throwInput.SupportsCharging())
|
||||
{
|
||||
ProgressBar.Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
SetupProgressBar();
|
||||
|
||||
_throwInput.ChargeStarted += OnChargeStarted;
|
||||
_throwInput.ChargeStopped += OnChargeStopped;
|
||||
_throwInput.ChargeUpdated += OnChargeUpdated;
|
||||
}
|
||||
|
||||
private void SetupProgressBar()
|
||||
{
|
||||
ProgressBar.MinValue = _throwInput.MinPower;
|
||||
ProgressBar.MaxValue = _throwInput.MaxPower;
|
||||
ProgressBar.Value = _throwInput.MinPower;
|
||||
ProgressBar.Step = 0.01f;
|
||||
ProgressBar.Hide();
|
||||
}
|
||||
|
||||
private void OnChargeStarted()
|
||||
{
|
||||
ProgressBar.Show();
|
||||
}
|
||||
|
||||
private void OnChargeStopped()
|
||||
{
|
||||
ProgressBar.Hide();
|
||||
}
|
||||
|
||||
private void OnChargeUpdated(float chargeRatio)
|
||||
{
|
||||
ProgressBar.Value = chargeRatio;
|
||||
ProgressBar.Show();
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://dev2q1228otm2
|
@@ -1,23 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class Credits : Control
|
||||
{
|
||||
private UIManager _uiManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_uiManager = GetNode<UIManager>("/root/UIManager");
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (!@event.IsActionPressed("ui_cancel")) return;
|
||||
if (_uiManager != null && _uiManager.IsScreenOnTop(this))
|
||||
{
|
||||
_uiManager.PopScreen();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://daevj4uootmcw
|
@@ -1,39 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class GameOverScreen : Node
|
||||
{
|
||||
[Export] public Control GameOverPanel { get; set; }
|
||||
[Export] public Button RestartButton { get; set; }
|
||||
[Export] public Button MainMenuButton { get; set; }
|
||||
[Export] public PackedScene MainMenuScene { get; set; }
|
||||
|
||||
private GameManager _gameManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_gameManager = GetNode<GameManager>("/root/GameManager");
|
||||
RestartButton.Pressed += OnRestartClicked;
|
||||
MainMenuButton.Pressed += OnMainMenuClicked;
|
||||
}
|
||||
|
||||
private void OnMainMenuClicked()
|
||||
{
|
||||
_gameManager.ResetPlayerState();
|
||||
GetTree().ChangeSceneToPacked(MainMenuScene);
|
||||
}
|
||||
|
||||
private void OnRestartClicked()
|
||||
{
|
||||
_gameManager.RestartGame();
|
||||
}
|
||||
|
||||
public void OnPlayerDeath()
|
||||
{
|
||||
if (_gameManager == null || _gameManager.GetLives() != 0) return;
|
||||
|
||||
GameOverPanel.Show();
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://u4qfsx4w72dv
|
@@ -1,67 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class MainMenu : Node
|
||||
{
|
||||
[Export] public Control MainMenuControl { get; set; }
|
||||
[Export] public Button NewGameButton { get; set; }
|
||||
[Export] public Button ContinueButton { get; set; }
|
||||
[Export] public Button SettingsButton { get; set; }
|
||||
[Export] public Button CreditsButton { get; set; }
|
||||
[Export] public Button ExitButton { get; set; }
|
||||
[Export] public Label VersionLabel { get; set; }
|
||||
[Export] public Control SettingsControl { get; set; }
|
||||
[Export] public Control CreditsControl { get; set; }
|
||||
|
||||
private SaveSystem _saveSystem;
|
||||
private GameManager _gameManager;
|
||||
private UIManager _uiManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_saveSystem = GetNode<SaveSystem>("/root/SaveSystem");
|
||||
_gameManager = GetNode<GameManager>("/root/GameManager");
|
||||
_uiManager = GetNode<UIManager>("/root/UIManager");
|
||||
|
||||
NewGameButton.Pressed += OnNewGamePressed;
|
||||
ContinueButton.Pressed += OnContinuePressed;
|
||||
SettingsButton.Pressed += OnSettingsPressed;
|
||||
CreditsButton.Pressed += OnCreditsPressed;
|
||||
ExitButton.Pressed += OnExitPressed;
|
||||
|
||||
VersionLabel.Text = $"v. {ProjectSettings.GetSetting("application/config/version")}";
|
||||
ContinueButton.Disabled = !_saveSystem.CheckSaveExists();
|
||||
|
||||
if (_saveSystem.CheckSaveExists())
|
||||
ContinueButton.GrabFocus();
|
||||
else
|
||||
NewGameButton.GrabFocus();
|
||||
}
|
||||
|
||||
private void OnExitPressed()
|
||||
{
|
||||
_gameManager.QuitGame();
|
||||
}
|
||||
|
||||
private void OnCreditsPressed()
|
||||
{
|
||||
_uiManager.PushScreen(CreditsControl);
|
||||
}
|
||||
|
||||
private void OnSettingsPressed()
|
||||
{
|
||||
_uiManager.PushScreen(SettingsControl);
|
||||
}
|
||||
|
||||
private void OnContinuePressed()
|
||||
{
|
||||
_gameManager.ContinueGame();
|
||||
}
|
||||
|
||||
private void OnNewGamePressed()
|
||||
{
|
||||
_gameManager.StartNewGame();
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://bna3ggr6n7ycr
|
@@ -1,142 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
using Mr.BrickAdventures.scripts.components;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class Marketplace : Node
|
||||
{
|
||||
[Export] public Array<SkillData> Skills { get; set; } = [];
|
||||
[Export] public GridContainer ToUnlockGrid { get; set; }
|
||||
[Export] public GridContainer UnlockedGrid { get; set; }
|
||||
[Export] public Font Font { get; set; }
|
||||
[Export] public SkillUnlockedComponent SkillUnlockedComponent { get; set; }
|
||||
[Export] public Array<Node> ComponentsToDisable { get; set; } = [];
|
||||
[Export] public PackedScene MarketplaceButtonScene { get; set; }
|
||||
[Export] public PackedScene SkillButtonScene { get; set; }
|
||||
|
||||
private GameManager _gameManager;
|
||||
private readonly List<Button> _unlockButtons = [];
|
||||
private readonly List<SkillButton> _skillButtons = [];
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
var skillsToUnlock = new List<SkillData>();
|
||||
|
||||
foreach (var skill in Skills) skillsToUnlock.Add(skill);
|
||||
|
||||
foreach (var skill in skillsToUnlock) CreateUpgradeButton(skill);
|
||||
|
||||
var unlockedSkills = _gameManager.GetUnlockedSkills();
|
||||
foreach (var skill in unlockedSkills) CreateSkillButton(skill);
|
||||
|
||||
SkillUnlockedComponent.SkillUnlocked += OnSkillUnlocked;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
SkillUnlockedComponent.SkillUnlocked -= OnSkillUnlocked;
|
||||
}
|
||||
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
var root = Owner as Control;
|
||||
|
||||
if (!@event.IsActionPressed("show_marketplace")) return;
|
||||
|
||||
if (root != null && root.IsVisible())
|
||||
{
|
||||
root.Hide();
|
||||
foreach (var c in ComponentsToDisable) c.ProcessMode = ProcessModeEnum.Inherit;
|
||||
}
|
||||
else
|
||||
{
|
||||
root?.Show();
|
||||
foreach (var c in ComponentsToDisable) c.ProcessMode = ProcessModeEnum.Disabled;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetButtonText(SkillData skill)
|
||||
{
|
||||
return $"{Tr(skill.Name)} {skill.Cost}";
|
||||
}
|
||||
|
||||
private void OnSkillUnlocked(SkillData skill)
|
||||
{
|
||||
if (_skillButtons.Count == 0) CreateSkillButton(skill);
|
||||
|
||||
foreach (var btn in _skillButtons)
|
||||
{
|
||||
if (btn.Data.IsActive)
|
||||
btn.Activate();
|
||||
else
|
||||
btn.Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateSkillButton(SkillData skill)
|
||||
{
|
||||
var button = SkillButtonScene.Instantiate<SkillButton>();
|
||||
button.Data = skill;
|
||||
button.Setup();
|
||||
button.Pressed += () => OnSkillButtonPressed(button);
|
||||
button.Activate();
|
||||
|
||||
_skillButtons.Add(button);
|
||||
UnlockedGrid.AddChild(button);
|
||||
UnlockedGrid.QueueSort();
|
||||
}
|
||||
|
||||
private void CreateUpgradeButton(SkillData skill)
|
||||
{
|
||||
var button = MarketplaceButtonScene.Instantiate<MarketplaceButton>();
|
||||
button.Text = GetButtonText(skill);
|
||||
button.Data = skill;
|
||||
button.Icon = skill.Icon;
|
||||
button.Pressed += () => OnUpgradeButtonPressed(skill);
|
||||
|
||||
_unlockButtons.Add(button);
|
||||
UnlockedGrid.AddChild(button);
|
||||
UnlockedGrid.QueueSort();
|
||||
}
|
||||
|
||||
private void OnUpgradeButtonPressed(SkillData skill)
|
||||
{
|
||||
if (_gameManager.IsSkillUnlocked(skill))
|
||||
{
|
||||
if (skill.Level < skill.MaxLevel)
|
||||
{
|
||||
SkillUnlockedComponent.TryUpgradeSkill(skill);
|
||||
if (!skill.IsActive) SkillUnlockedComponent.SkillManager.ToggleSkillActivation(skill);
|
||||
}
|
||||
else
|
||||
{
|
||||
SkillUnlockedComponent.SkillManager.ToggleSkillActivation(skill);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SkillUnlockedComponent.TryUnlockSkill(skill);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveButton(SkillData skill)
|
||||
{
|
||||
foreach (var node in ToUnlockGrid.GetChildren())
|
||||
{
|
||||
var child = (Button)node;
|
||||
if (child.Text != GetButtonText(skill)) continue;
|
||||
|
||||
child.QueueFree();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSkillButtonPressed(SkillButton button)
|
||||
{
|
||||
SkillUnlockedComponent.SkillManager.ToggleSkillActivation(button.Data);
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://bnc16gndpl87i
|
@@ -1,62 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
using Mr.BrickAdventures.scripts.components;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class MarketplaceButton : Button
|
||||
{
|
||||
[Export] public SkillData Data { get; set; }
|
||||
[Export] public Texture2D UnlockedSkillIcon { get; set; }
|
||||
[Export] public Texture2D LockedSkillIcon { get; set; }
|
||||
[Export] public Container SkillLevelContainer { get; set; }
|
||||
|
||||
private GameManager _gameManager;
|
||||
private SkillUnlockedComponent _skillUnlockedComponent;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_gameManager = GetNode<GameManager>("/root/GameManager");
|
||||
|
||||
Setup();
|
||||
var player = _gameManager.Player;
|
||||
|
||||
var skillUnlockerComponent = player?.GetNodeOrNull<SkillUnlockedComponent>("SkillUnlockerComponent");
|
||||
if (skillUnlockerComponent == null) return;
|
||||
|
||||
skillUnlockerComponent.SkillUnlocked += OnSkillUnlock;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
_skillUnlockedComponent.SkillUnlocked -= OnSkillUnlock;
|
||||
}
|
||||
|
||||
private void Setup()
|
||||
{
|
||||
if (Data == null) return;
|
||||
|
||||
for (var i = 0; i < Data.MaxLevel; i++)
|
||||
{
|
||||
var icon = new TextureRect()
|
||||
{
|
||||
Texture = i < Data.Level ? UnlockedSkillIcon : LockedSkillIcon,
|
||||
};
|
||||
SkillLevelContainer.AddChild(icon);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSkillUnlock(SkillData skill)
|
||||
{
|
||||
if (skill.Name != Data.Name) return;
|
||||
|
||||
for (var i = 0; i < Data.MaxLevel; i++)
|
||||
{
|
||||
var icon = SkillLevelContainer.GetChildOrNull<TextureRect>(i);
|
||||
if (icon == null) continue;
|
||||
icon.Texture = i < Data.Level ? UnlockedSkillIcon : LockedSkillIcon;
|
||||
Disabled = i >= Data.Level;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://vokgv56bjpf1
|
@@ -1,67 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class PauseMenu : Node
|
||||
{
|
||||
[Export] public Control PauseMenuControl { get; set; }
|
||||
[Export] public Control SettingsControl { get; set; }
|
||||
[Export] public Button ResumeButton { get; set; }
|
||||
[Export] public Button MainMenuButton { get; set; }
|
||||
[Export] public Button QuitButton { get; set; }
|
||||
[Export] public Button SettingsButton { get; set; }
|
||||
[Export] public PackedScene MainMenuScene { get; set; }
|
||||
|
||||
private GameManager _gameManager;
|
||||
private UIManager _uiManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_gameManager = GetNode<GameManager>("/root/GameManager");
|
||||
_uiManager = GetNode<UIManager>("/root/UIManager");
|
||||
|
||||
ResumeButton.Pressed += OnResumePressed;
|
||||
MainMenuButton.Pressed += OnMainMenuPressed;
|
||||
QuitButton.Pressed += OnQuitPressed;
|
||||
SettingsButton.Pressed += OnSettingsPressed;
|
||||
|
||||
PauseMenuControl.Hide();
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (!@event.IsActionPressed("pause")) return;
|
||||
if (_uiManager.IsVisibleOnStack(PauseMenuControl))
|
||||
OnResumePressed();
|
||||
else
|
||||
{
|
||||
_uiManager.PushScreen(PauseMenuControl);
|
||||
_gameManager.PauseGame();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSettingsPressed()
|
||||
{
|
||||
_uiManager.PushScreen(SettingsControl);
|
||||
_gameManager.PauseGame();
|
||||
}
|
||||
|
||||
private void OnQuitPressed()
|
||||
{
|
||||
_gameManager.QuitGame();
|
||||
}
|
||||
|
||||
private void OnMainMenuPressed()
|
||||
{
|
||||
_gameManager.ResumeGame();
|
||||
_gameManager.ResetCurrentSessionState();
|
||||
GetTree().ChangeSceneToPacked(MainMenuScene);
|
||||
}
|
||||
|
||||
private void OnResumePressed()
|
||||
{
|
||||
_uiManager.PopScreen();
|
||||
_gameManager.ResumeGame();
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://cakgxndurgfa3
|
@@ -1,60 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class SettingsMenu : Node
|
||||
{
|
||||
[Export] public Control InputSettingsControl { get; set; }
|
||||
[Export] public Control AudioSettingsControl { get; set; }
|
||||
[Export] public Control DisplaySettingsControl { get; set; }
|
||||
[Export] public Control GameplaySettingsControl { get; set; }
|
||||
[Export] public Control SettingsMenuControl { get; set; }
|
||||
[Export] public Button InputSettingsButton { get; set; }
|
||||
[Export] public Button AudioSettingsButton { get; set; }
|
||||
[Export] public Button DisplaySettingsButton { get; set; }
|
||||
[Export] public Button GameplaySettingsButton { get; set; }
|
||||
|
||||
private UIManager _uiManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_uiManager = GetNode<UIManager>("/root/UIManager");
|
||||
|
||||
InputSettingsButton.Pressed += OnInputSettingsPressed;
|
||||
AudioSettingsButton.Pressed += OnAudioSettingsPressed;
|
||||
DisplaySettingsButton.Pressed += OnDisplaySettingsPressed;
|
||||
GameplaySettingsButton.Pressed += OnGameplaySettingsPressed;
|
||||
|
||||
InputSettingsControl.Hide();
|
||||
AudioSettingsControl.Hide();
|
||||
DisplaySettingsControl.Hide();
|
||||
GameplaySettingsControl.Hide();
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (!@event.IsActionPressed("ui_cancel")) return;
|
||||
if (_uiManager.IsScreenOnTop(SettingsMenuControl)) _uiManager.PopScreen();
|
||||
}
|
||||
|
||||
private void OnInputSettingsPressed()
|
||||
{
|
||||
_uiManager.PushScreen(InputSettingsControl);
|
||||
}
|
||||
|
||||
private void OnAudioSettingsPressed()
|
||||
{
|
||||
_uiManager.PushScreen(AudioSettingsControl);
|
||||
}
|
||||
|
||||
private void OnDisplaySettingsPressed()
|
||||
{
|
||||
_uiManager.PushScreen(DisplaySettingsControl);
|
||||
}
|
||||
|
||||
private void OnGameplaySettingsPressed()
|
||||
{
|
||||
_uiManager.PushScreen(GameplaySettingsControl);
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://i8j47qnrytuo
|
@@ -1,25 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class SkillButton : Button
|
||||
{
|
||||
[Export] public SkillData Data { get; set; }
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
Icon = Data?.Icon;
|
||||
Text = Tr(Data?.Name) ?? string.Empty;
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
Set("theme_override_colors/font_color", new Color("#49aa10"));
|
||||
}
|
||||
|
||||
public void Deactivate()
|
||||
{
|
||||
Set("theme_override_colors/font_color", new Color("#ffffff"));
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://bw8dlgq86jrtt
|
@@ -1,70 +0,0 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.scripts.interfaces;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
public partial class BrickThrowComponent : Node
|
||||
{
|
||||
[Export] public PackedScene BrickScene { get; set; }
|
||||
[Export] public float FireRate { get; set; } = 1.0f;
|
||||
[Export] public PlayerController PlayerController { get; set; }
|
||||
[Export] public ThrowInputResource ThrowInputBehavior { get; set; }
|
||||
|
||||
private bool _canThrow = true;
|
||||
private Timer _timer;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
SetupTimer();
|
||||
_canThrow = true;
|
||||
|
||||
if (ThrowInputBehavior != null) ThrowInputBehavior.ThrowRequested += ThrowBrick;
|
||||
}
|
||||
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
ThrowInputBehavior?.ProcessInput(@event);
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
ThrowInputBehavior?.Update(delta);
|
||||
}
|
||||
|
||||
private void SetupTimer()
|
||||
{
|
||||
_timer.WaitTime = FireRate;
|
||||
_timer.OneShot = false;
|
||||
_timer.Autostart = false;
|
||||
_timer.Timeout += OnTimerTimeout;
|
||||
}
|
||||
|
||||
private void OnTimerTimeout()
|
||||
{
|
||||
_canThrow = true;
|
||||
}
|
||||
|
||||
private void ThrowBrick(float powerMultiplier = 1f)
|
||||
{
|
||||
if (!_canThrow || PlayerController == null || BrickScene == null)
|
||||
return;
|
||||
|
||||
var instance = BrickScene.Instantiate<Node2D>();
|
||||
var init = instance.GetNodeOrNull<ProjectileInitComponent>("ProjectileInitComponent");
|
||||
if (init != null && PlayerController.CurrentMovement is PlatformMovementComponent)
|
||||
{
|
||||
init.Initialize(new ProjectileInitParams()
|
||||
{
|
||||
Position = PlayerController.GlobalPosition,
|
||||
Rotation = PlayerController.Rotation,
|
||||
Direction = PlayerController.CurrentMovement.LastDirection,
|
||||
PowerMultiplier = powerMultiplier,
|
||||
});
|
||||
}
|
||||
|
||||
GetTree().CurrentScene.AddChild(instance);
|
||||
_canThrow = false;
|
||||
_timer.Start();
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://b0bv8kw5w5037
|
@@ -1,45 +0,0 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
public partial class BulletComponent : Node
|
||||
{
|
||||
[Export] public Area2D Area { get; set; }
|
||||
[Export] public TerrainHitFx TerrainHitFx { get; set; }
|
||||
[Export] public Sprite2D BulletSprite { get; set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
Area.BodyEntered += OnBodyEntered;
|
||||
}
|
||||
|
||||
private void OnBodyEntered(Node2D body)
|
||||
{
|
||||
if (body is TileMapLayer)
|
||||
{
|
||||
if (BulletSprite != null)
|
||||
{
|
||||
BulletSprite.Visible = false;
|
||||
}
|
||||
|
||||
PlayTerrainHitFx();
|
||||
return;
|
||||
}
|
||||
|
||||
Owner.QueueFree();
|
||||
}
|
||||
|
||||
private void OnAreaEntered(Area2D area)
|
||||
{
|
||||
Owner.QueueFree();
|
||||
}
|
||||
|
||||
private void PlayTerrainHitFx()
|
||||
{
|
||||
if (TerrainHitFx == null) return;
|
||||
|
||||
TerrainHitFx.TriggerFx();
|
||||
|
||||
Owner.QueueFree();
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://cfw8nbrarex0i
|
@@ -1,47 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
public partial class CageComponent : Node
|
||||
{
|
||||
[Export] public LeverComponent Lever { get; set; }
|
||||
[Export] public Vector2 MoveValue { get; set; } = new(0, -100f);
|
||||
[Export] public float TweenDuration { get; set; } = 0.5f;
|
||||
[Export] public bool ShouldFree { get; set; } = true;
|
||||
|
||||
private const string LeverGroupName = "levers";
|
||||
|
||||
public override async void _Ready()
|
||||
{
|
||||
await ToSignal(GetTree(), SceneTree.SignalName.ProcessFrame);
|
||||
if (Lever == null)
|
||||
{
|
||||
var leverNodes = GetTree().GetNodesInGroup(LeverGroupName);
|
||||
foreach (var leverNode in leverNodes)
|
||||
{
|
||||
var lever = leverNode.GetNodeOrNull<LeverComponent>("LeverComponent");
|
||||
if (lever != null) lever.Activated += OnLeverActivated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLeverActivated()
|
||||
{
|
||||
var tween = CreateTween();
|
||||
if (Owner is Node2D root)
|
||||
{
|
||||
var endPosition = root.Position + MoveValue;
|
||||
tween.TweenProperty(root, "position", endPosition, TweenDuration);
|
||||
}
|
||||
|
||||
tween.TweenCallback(Callable.From(OnTweenCompleted));
|
||||
|
||||
}
|
||||
|
||||
private void OnTweenCompleted()
|
||||
{
|
||||
if (!ShouldFree) return;
|
||||
Owner.QueueFree();
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://dojn0gw8hsv02
|
@@ -1,8 +0,0 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
public partial class CanBeLaunchedComponent : Node
|
||||
{
|
||||
|
||||
}
|
@@ -1 +0,0 @@
|
||||
uid://cjcc7fia15wu3
|
@@ -1 +0,0 @@
|
||||
uid://mnjg3p0aw1ow
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user