Add plastique item

Add Door object
Initial work for look up animation
This commit is contained in:
2026-01-02 17:06:01 -08:00
parent 5b9de11e5a
commit 04543fcfac
32 changed files with 1652 additions and 990 deletions

View File

@@ -4,6 +4,8 @@ public partial class AppLogic
{ {
public static class Output public static class Output
{ {
public readonly record struct Initialize;
public readonly record struct FadeToBlack; public readonly record struct FadeToBlack;
public readonly record struct ShowSplashScreen; public readonly record struct ShowSplashScreen;

View File

@@ -9,5 +9,5 @@ public interface IAppLogic : ILogicBlock<AppLogic.State>;
[LogicBlock(typeof(State), Diagram = true)] [LogicBlock(typeof(State), Diagram = true)]
public partial class AppLogic : LogicBlock<AppLogic.State>, IAppLogic public partial class AppLogic : LogicBlock<AppLogic.State>, IAppLogic
{ {
public override Transition GetInitialState() => To<State.MainMenu>(); public override Transition GetInitialState() => To<State.Initialize>();
} }

View File

@@ -0,0 +1,21 @@
namespace Zennysoft.Ma.Adapter;
using Chickensoft.Introspection;
using Chickensoft.LogicBlocks;
public partial class AppLogic
{
public partial record State
{
[Meta]
public partial record Initialize : State, IGet<Input.SaveFileLoaded>
{
public Initialize()
{
this.OnEnter(() => Output(new Output.Initialize()));
}
public Transition On(in Input.SaveFileLoaded input) => To<SplashScreen>();
}
}
}

View File

@@ -15,7 +15,7 @@ public partial class AppLogic
this.OnEnter(() => Output(new Output.StartLoadingSaveFile())); this.OnEnter(() => Output(new Output.StartLoadingSaveFile()));
} }
public Transition On(in Input.SaveFileLoaded input) => To<GameStarted>(); public Transition On(in Input.SaveFileLoaded input) => To<MainMenu>();
} }
} }
} }

View File

@@ -11,6 +11,7 @@ public partial class AppLogic
{ {
public MainMenu() public MainMenu()
{ {
OnAttach(() => Output(new Output.ShowMainMenu()));
} }
public Transition On(in Input.NewGame input) => To<GameStarted>(); public Transition On(in Input.NewGame input) => To<GameStarted>();

View File

@@ -16,15 +16,17 @@ public partial class AppLogic
this.OnEnter(() => Output(new Output.ShowSplashScreen())); this.OnEnter(() => Output(new Output.ShowSplashScreen()));
OnAttach( OnAttach(
() => Get<IAppRepo>().SplashScreenSkipped += OnSplashScreenSkipped () =>
); {
Get<IAppRepo>().SplashScreenSkipped += OnSplashScreenSkipped;
});
OnDetach( OnDetach(
() => Get<IAppRepo>().SplashScreenSkipped -= OnSplashScreenSkipped () => Get<IAppRepo>().SplashScreenSkipped -= OnSplashScreenSkipped
); );
} }
public Transition On(in Input.FadeOutFinished input) => To<GameStarted>(); public Transition On(in Input.FadeOutFinished input) => To<MainMenu>();
public void OnSplashScreenSkipped() => public void OnSplashScreenSkipped() =>
Output(new Output.HideSplashScreen()); Output(new Output.HideSplashScreen());

View File

@@ -28,6 +28,8 @@ public partial class GameState
public readonly record struct CloseTeleport; public readonly record struct CloseTeleport;
public readonly record struct CloseInventory;
public readonly record struct GameOver; public readonly record struct GameOver;
} }
} }

View File

@@ -8,13 +8,19 @@ public partial class GameState
public partial record State public partial record State
{ {
[Meta, LogicBlock(typeof(State), Diagram = true)] [Meta, LogicBlock(typeof(State), Diagram = true)]
public partial record InventoryScreen : State, IGet<Input.InteractButtonPressed> public partial record InventoryScreen : State, IGet<Input.InteractButtonPressed>, IGet<Input.CloseInventory>
{ {
public Transition On(in Input.InteractButtonPressed input) public Transition On(in Input.InteractButtonPressed input)
{ {
Output(new Output.CloseInventoryMenu()); Output(new Output.CloseInventoryMenu());
return To<InGame>(); return To<InGame>();
} }
public Transition On(in Input.CloseInventory input)
{
Output(new Output.CloseInventoryMenu());
return To<InGame>();
}
} }
} }
} }

View File

@@ -18,12 +18,16 @@ public interface IPlayer : IKillable, ICharacterBody3D
public void LevelUp(); public void LevelUp();
public void LookUp();
public void TeleportPlayer(Transform3D newTransform); public void TeleportPlayer(Transform3D newTransform);
public void Equip(EquipableItem equipable); public void Equip(EquipableItem equipable);
public void Unequip(EquipableItem equipable); public void Unequip(EquipableItem equipable);
public void Reset();
public IInventory Inventory { get; } public IInventory Inventory { get; }
public IHealthComponent HealthComponent { get; } public IHealthComponent HealthComponent { get; }
@@ -44,4 +48,6 @@ public interface IPlayer : IKillable, ICharacterBody3D
public event Action PlayerDied; public event Action PlayerDied;
public delegate InventoryItem RerollItem(InventoryItem item); public delegate InventoryItem RerollItem(InventoryItem item);
public event Action PointUpFinished;
} }

View File

@@ -6,9 +6,9 @@ public partial class Main : Node
{ {
public override void _Ready() public override void _Ready()
{ {
CallDeferred("RunScene"); CallDeferred("RunScene");
} }
private void RunScene() private void RunScene()
=> GetTree().ChangeSceneToFile("res://src/app/App.tscn"); => GetTree().ChangeSceneToFile("res://src/app/App.tscn");
} }

View File

@@ -31,6 +31,8 @@ public partial class App : Node, IApp
[Node] private GalleryMenu GalleryMenu { get; set; } [Node] private GalleryMenu GalleryMenu { get; set; }
[Node] private VideoStreamPlayer VideoStreamPlayer { get; set; }
IAppRepo IProvide<IAppRepo>.Value() => AppRepo; IAppRepo IProvide<IAppRepo>.Value() => AppRepo;
public IAppRepo AppRepo { get; set; } = default!; public IAppRepo AppRepo { get; set; } = default!;
@@ -53,141 +55,144 @@ public partial class App : Node, IApp
public void Initialize() public void Initialize()
{ {
_container = new SimpleInjector.Container(); _container = new SimpleInjector.Container();
_container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle(); _container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
_container.RegisterSingleton<IAppRepo, AppRepo>(); _container.RegisterSingleton<IAppRepo, AppRepo>();
_container.RegisterSingleton<IAppLogic, AppLogic>(); _container.RegisterSingleton<IAppLogic, AppLogic>();
_container.RegisterSingleton<IFileSystem, FileSystem>(); _container.RegisterSingleton<IFileSystem, FileSystem>();
_container.RegisterSingleton<ISaveFileManager, SaveFileManager>(); _container.RegisterSingleton<ISaveFileManager, SaveFileManager>();
_saveFileManager = _container.GetInstance<ISaveFileManager>(); _saveFileManager = _container.GetInstance<ISaveFileManager>();
_optionsSavePath = $"{OS.GetUserDataDir()}/options.json"; _optionsSavePath = $"{OS.GetUserDataDir()}/options.json";
_controllerSavePath = $"{OS.GetUserDataDir()}/controls.json"; _controllerSavePath = $"{OS.GetUserDataDir()}/controls.json";
Task.Run(() => _saveFileManager.ReadFromFile<OptionsData>(_optionsSavePath).ContinueWith((data) => MainMenu.StartGame += OnStartGame;
{ MainMenu.EnemyViewer += OnEnemyViewer;
if (data.IsCompletedSuccessfully) MainMenu.Gallery += OnGallery;
OptionsMenu.CallDeferred("Load", data.Result); MainMenu.Options += OnOptions;
})); MainMenu.Quit += OnQuit;
Task.Run(() => _saveFileManager.ReadFromFile<string>(_controllerSavePath).ContinueWith((data) => GalleryMenu.GalleryExited += GalleryExited;
{
if (data.IsCompletedSuccessfully)
OptionsMenu.Controller.CallDeferred(nameof(OptionsMenu.Controller.LoadControllerInput), data.Result);
}));
MainMenu.StartGame += OnStartGame; OptionsMenu.OptionsMenuExited += OptionsMenu_OptionsMenuExited;
MainMenu.EnemyViewer += OnEnemyViewer; OptionsMenu.DeleteSaveData += DeleteSaveData;
MainMenu.Gallery += OnGallery; AppRepo = _container.GetInstance<IAppRepo>();
MainMenu.Options += OnOptions; AppLogic = _container.GetInstance<IAppLogic>();
MainMenu.Quit += OnQuit;
GalleryMenu.GalleryExited += GalleryExited; Task.Run(() => _saveFileManager.ReadFromFile<string>(_controllerSavePath).ContinueWith((data) =>
{
if (data.IsCompletedSuccessfully)
OptionsMenu.Controller.CallDeferred(nameof(OptionsMenu.Controller.LoadControllerInput), data.Result);
}));
OptionsMenu.OptionsMenuExited += OptionsMenu_OptionsMenuExited; AppLogic.Set(AppRepo);
OptionsMenu.DeleteSaveData += DeleteSaveData; AppLogic.Set(new AppLogic.Data());
AppRepo = _container.GetInstance<IAppRepo>();
AppLogic = _container.GetInstance<IAppLogic>();
AppLogic.Set(AppRepo); AppRepo.DataViewerExited += DataViewerExited;
AppLogic.Set(new AppLogic.Data());
AppRepo.DataViewerExited += DataViewerExited; Input.MouseMode = Input.MouseModeEnum.Visible;
_progress = [];
Input.MouseMode = Input.MouseModeEnum.Visible; this.Provide();
_progress = [];
this.Provide();
} }
private void GameExitRequested() private void GameExitRequested()
{ {
AppLogic.Input(new AppLogic.Input.QuitGame()); AppLogic.Input(new AppLogic.Input.QuitGame());
} }
private void DeleteSaveData() private void DeleteSaveData()
{ {
var saveFileManager = _container.GetInstance<ISaveFileManager>(); var saveFileManager = _container.GetInstance<ISaveFileManager>();
saveFileManager.DeleteSaveData(); saveFileManager.DeleteSaveData();
} }
private void DataViewerExited() private void DataViewerExited()
{ {
AppLogic.Input(new AppLogic.Input.EnemyViewerExited()); AppLogic.Input(new AppLogic.Input.EnemyViewerExited());
} }
private async void OptionsMenu_OptionsMenuExited() private async void OptionsMenu_OptionsMenuExited()
{ {
var saveFileManager = _container.GetInstance<ISaveFileManager>(); var saveFileManager = _container.GetInstance<ISaveFileManager>();
await saveFileManager.WriteToFile(OptionsMenu.OptionsData, _optionsSavePath); await saveFileManager.WriteToFile(OptionsMenu.OptionsData, _optionsSavePath);
var controllerOutput = InputHelper.SerializeInputsForActions(); var controllerOutput = InputHelper.SerializeInputsForActions();
await saveFileManager.WriteToFile(controllerOutput, _controllerSavePath); await saveFileManager.WriteToFile(controllerOutput, _controllerSavePath);
OptionsMenu.Hide(); OptionsMenu.Hide();
MainMenu.OptionsButton.GrabFocus(); MainMenu.OptionsButton.GrabFocus();
} }
private void GalleryExited() private void GalleryExited()
{ {
GalleryMenu.Hide(); GalleryMenu.Hide();
MainMenu.GalleryButton.GrabFocus(); MainMenu.GalleryButton.GrabFocus();
} }
public void OnReady() public void OnReady()
{ {
AppBinding = AppLogic.Bind(); AppBinding = AppLogic.Bind();
AppBinding AppBinding
.Handle((in AppLogic.Output.ShowSplashScreen _) => .Handle((in AppLogic.Output.Initialize _) =>
{ {
}) Task.Run(() => _saveFileManager.ReadFromFile<string>(_optionsSavePath).ContinueWith((data) =>
.Handle((in AppLogic.Output.HideSplashScreen _) => {
{ AppLogic.Input(new AppLogic.Input.SaveFileLoaded());
}) }));
.Handle((in AppLogic.Output.SetupGameScene _) => })
{ .Handle((in AppLogic.Output.ShowSplashScreen _) =>
LoadingScreen.Show(); {
LoadGame(GAME_SCENE_PATH); AppLogic.Input(new AppLogic.Input.FadeOutFinished());
}) })
.Handle((in AppLogic.Output.ShowMainMenu _) => .Handle((in AppLogic.Output.HideSplashScreen _) =>
{ {
}) })
.Handle((in AppLogic.Output.CloseGame _) => .Handle((in AppLogic.Output.SetupGameScene _) =>
{ {
LoadingScreen.Hide(); LoadingScreen.Show();
_game.GameExitRequested -= GameExitRequested; LoadGame(GAME_SCENE_PATH);
MainMenu.StartGameButton.GrabFocus(); })
_game.CallDeferred(MethodName.QueueFree, []); .Handle((in AppLogic.Output.ShowMainMenu _) =>
GetTree().Paused = false; {
}) MainMenu.CallDeferred(MainMenu.MethodName.FadeIn);
.Handle((in AppLogic.Output.StartLoadingSaveFile _) => })
{ .Handle((in AppLogic.Output.CloseGame _) =>
}) {
.Handle((in AppLogic.Output.EnemyViewerOpened _) => LoadingScreen.Hide();
{ _game.GameExitRequested -= GameExitRequested;
LoadingScreen.Show(); MainMenu.StartGameButton.GrabFocus();
LoadEnemyViewer(ENEMY_VIEWER_PATH); _game.CallDeferred(MethodName.QueueFree, []);
}) GetTree().Paused = false;
.Handle((in AppLogic.Output.EnemyViewerExited _) => })
{ .Handle((in AppLogic.Output.StartLoadingSaveFile _) =>
LoadingScreen.Hide(); {
if (_enemyViewer != null && _enemyViewer is DataViewer enemyViewer) })
enemyViewer.CallDeferred(MethodName.QueueFree); .Handle((in AppLogic.Output.EnemyViewerOpened _) =>
MainMenu.Show(); {
MainMenu.EnemyViewerButton.GrabFocus(); LoadingScreen.Show();
}) LoadEnemyViewer(ENEMY_VIEWER_PATH);
.Handle((in AppLogic.Output.ExitGame _) => })
{ .Handle((in AppLogic.Output.EnemyViewerExited _) =>
GetTree().Quit(); {
}); LoadingScreen.Hide();
if (_enemyViewer != null && _enemyViewer is DataViewer enemyViewer)
enemyViewer.CallDeferred(MethodName.QueueFree);
MainMenu.Show();
MainMenu.EnemyViewerButton.GrabFocus();
})
.Handle((in AppLogic.Output.ExitGame _) =>
{
GetTree().Quit();
});
AppLogic.Start(); AppLogic.Start();
} }
public override void _Process(double delta) public override void _Process(double delta)
{ {
if (_reportedProgress < 1) if (_reportedProgress < 1)
LoadingScreen.ProgressBar.Value = Mathf.RoundToInt(Mathf.Lerp(LoadingScreen.ProgressBar.Value, _reportedProgress * 100, (float)delta * 2)); LoadingScreen.ProgressBar.Value = Mathf.RoundToInt(Mathf.Lerp(LoadingScreen.ProgressBar.Value, _reportedProgress * 100, (float)delta * 2));
else else
LoadingScreen.ProgressBar.Value = Mathf.RoundToInt(Mathf.Lerp(LoadingScreen.ProgressBar.Value, 200, (float)delta * 5)); LoadingScreen.ProgressBar.Value = Mathf.RoundToInt(Mathf.Lerp(LoadingScreen.ProgressBar.Value, 200, (float)delta * 5));
} }
public void OnStartGame() => AppLogic.Input(new AppLogic.Input.NewGame()); public void OnStartGame() => AppLogic.Input(new AppLogic.Input.NewGame());
@@ -198,64 +203,64 @@ public partial class App : Node, IApp
private async void LoadGame(string sceneName) private async void LoadGame(string sceneName)
{ {
var scene = await LoadSceneInternal(sceneName); var scene = await LoadSceneInternal(sceneName);
_game = scene as IGame; _game = scene as IGame;
_game.GameExitRequested += GameExitRequested; _game.GameExitRequested += GameExitRequested;
await ToSignal(GetTree().CreateTimer(0.8f), "timeout"); await ToSignal(GetTree().CreateTimer(0.8f), "timeout");
CallDeferred(MethodName.AddChild, scene); CallDeferred(MethodName.AddChild, scene);
} }
private async void LoadEnemyViewer(string sceneName) private async void LoadEnemyViewer(string sceneName)
{ {
var scene = await LoadSceneInternal(sceneName); var scene = await LoadSceneInternal(sceneName);
_enemyViewer = scene as IDataViewer; _enemyViewer = scene as IDataViewer;
await ToSignal(GetTree().CreateTimer(0.8f), "timeout"); await ToSignal(GetTree().CreateTimer(0.8f), "timeout");
CallDeferred(MethodName.AddChild, scene); CallDeferred(MethodName.AddChild, scene);
} }
private async Task<Node> LoadSceneInternal(string sceneName) private async Task<Node> LoadSceneInternal(string sceneName)
{ {
LoadingScreen.Show(); LoadingScreen.Show();
LoadingScreen.ProgressBar.Value = 0; LoadingScreen.ProgressBar.Value = 0;
var sceneLoader = new SceneLoader(); var sceneLoader = new SceneLoader();
CallDeferred(MethodName.AddChild, sceneLoader); CallDeferred(MethodName.AddChild, sceneLoader);
sceneLoader.LoadSceneRequest(sceneName); sceneLoader.LoadSceneRequest(sceneName);
sceneLoader.SceneReportedProgress += SceneLoader_SceneReportedProgress; sceneLoader.SceneReportedProgress += SceneLoader_SceneReportedProgress;
await ToSignal(sceneLoader, SceneLoader.SignalName.SceneLoaded); await ToSignal(sceneLoader, SceneLoader.SignalName.SceneLoaded);
var result = sceneLoader.LoadedScene; var result = sceneLoader.LoadedScene;
sceneLoader.QueueFree(); sceneLoader.QueueFree();
return result; return result;
} }
private void SceneLoader_SceneReportedProgress(double progress) => _reportedProgress = progress; private void SceneLoader_SceneReportedProgress(double progress) => _reportedProgress = progress;
private async void OnOptions() private async void OnOptions()
{ {
OptionsMenu.Show(); OptionsMenu.Show();
OptionsMenu.GameTab.GrabFocus(); OptionsMenu.GameTab.GrabFocus();
} }
private async void OnGallery() private async void OnGallery()
{ {
GalleryMenu.Show(); GalleryMenu.Show();
GalleryMenu.ItemButton1.GrabFocus(); GalleryMenu.ItemButton1.GrabFocus();
} }
public void OnQuit() => AppLogic.Input(new AppLogic.Input.QuitGame()); public void OnQuit() => AppLogic.Input(new AppLogic.Input.QuitGame());
public void OnSaveFileLoaded() public void OnSaveFileLoaded()
{ {
AppLogic.Input(new AppLogic.Input.SaveFileLoaded()); AppLogic.Input(new AppLogic.Input.SaveFileLoaded());
} }
public void OnExitTree() public void OnExitTree()
{ {
AppLogic.Stop(); AppLogic.Stop();
AppBinding.Dispose(); AppBinding.Dispose();
AppRepo.Dispose(); AppRepo.Dispose();
MainMenu.StartGame -= OnStartGame; MainMenu.StartGame -= OnStartGame;
MainMenu.EnemyViewer -= OnEnemyViewer; MainMenu.EnemyViewer -= OnEnemyViewer;
MainMenu.Quit -= OnQuit; MainMenu.Quit -= OnQuit;
} }
} }

View File

@@ -12,6 +12,7 @@ script = ExtResource("1_rt73h")
[node name="MainMenu" parent="." instance=ExtResource("2_1uiag")] [node name="MainMenu" parent="." instance=ExtResource("2_1uiag")]
unique_name_in_owner = true unique_name_in_owner = true
visible = false
[node name="LoadingScreen" parent="." instance=ExtResource("3_3st5l")] [node name="LoadingScreen" parent="." instance=ExtResource("3_3st5l")]
unique_name_in_owner = true unique_name_in_owner = true
@@ -24,3 +25,9 @@ visible = false
[node name="GalleryMenu" parent="." instance=ExtResource("5_iuu71")] [node name="GalleryMenu" parent="." instance=ExtResource("5_iuu71")]
unique_name_in_owner = true unique_name_in_owner = true
visible = false visible = false
[node name="VideoStreamPlayer" type="VideoStreamPlayer" parent="."]
unique_name_in_owner = true
visible = false
offset_right = 40.0
offset_bottom = 40.0

View File

@@ -1,7 +1,13 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot; using Godot;
using System;
[Meta(typeof(IAutoNode))]
public partial class ShakeCamera : Camera3D public partial class ShakeCamera : Camera3D
{ {
public override void _Notification(int what) => this.Notify(what);
[Export] private double _shakeIntensity = 1.0; [Export] private double _shakeIntensity = 1.0;
[Export] private double _maxX = 10; [Export] private double _maxX = 10;
@@ -18,28 +24,28 @@ public partial class ShakeCamera : Camera3D
public override void _Ready() public override void _Ready()
{ {
_initialRotation = RotationDegrees; _initialRotation = RotationDegrees;
} }
public override void _Process(double delta) public override void _Process(double delta)
{ {
_time += delta; _time += delta;
_shake = Mathf.Max(_shake - delta * _shakeIntensity, 0.0); _shake = Mathf.Max(_shake - delta * _shakeIntensity, 0.0);
RotationDegrees = new Vector3( RotationDegrees = new Vector3(
(float)(_initialRotation.X + _maxX * Mathf.Pow(_shake, 2) * GetNoiseFromSeed(0)), (float)(_initialRotation.X + _maxX * Mathf.Pow(_shake, 2) * GetNoiseFromSeed(0)),
(float)(_initialRotation.Y + _maxY * Mathf.Pow(_shake, 2) * GetNoiseFromSeed(1)), (float)(_initialRotation.Y + _maxY * Mathf.Pow(_shake, 2) * GetNoiseFromSeed(1)),
(float)(_initialRotation.Z + _maxZ * Mathf.Pow(_shake, 2) * GetNoiseFromSeed(2))); (float)(_initialRotation.Z + _maxZ * Mathf.Pow(_shake, 2) * GetNoiseFromSeed(2)));
} }
public void AddShake(float shakeAmount) public void AddShake(float shakeAmount)
{ {
_shake = Mathf.Clamp(_shake + shakeAmount, 0.0, 1.0); _shake = Mathf.Clamp(_shake + shakeAmount, 0.0, 1.0);
} }
private double GetNoiseFromSeed(int seed) private double GetNoiseFromSeed(int seed)
{ {
_noise.Seed = seed; _noise.Seed = seed;
return _noise.GetNoise1D((float)(_time * _noiseSpeed)); return _noise.GetNoise1D((float)(_time * _noiseSpeed));
} }
} }

View File

@@ -167,12 +167,14 @@ public partial class Game : Node3D, IGame
OnLoadLevelRequest += LoadLevel; OnLoadLevelRequest += LoadLevel;
GameRepo.RestorativePickedUp += GameEventDepot_RestorativePickedUp; GameRepo.RestorativePickedUp += GameEventDepot_RestorativePickedUp;
GameRepo.CloseInventoryEvent += ExitInventoryAction;
_player.Inventory.BroadcastMessage += BroadcastMessage; _player.Inventory.BroadcastMessage += BroadcastMessage;
_map.FloorLoaded += OnFloorLoadFinished; _map.FloorLoaded += OnFloorLoadFinished;
_player.PlayerDied += GameOver; _player.PlayerDied += GameOver;
_player.PointUpFinished += PointUpFinished;
GameOverMenu.NewGame += OnNewGame; GameOverMenu.NewGame += OnNewGame;
GameOverMenu.QuitGame += OnQuit; GameOverMenu.QuitGame += OnQuit;
@@ -234,6 +236,14 @@ public partial class Game : Node3D, IGame
dropped.Drop(); dropped.Drop();
} }
public void SetItem(InventoryItem item)
{
var setScene = GD.Load<PackedScene>("res://src/items/misc/SetItem.tscn");
var setItem = setScene.Instantiate<SetItem>();
AddChild(setItem);
setItem.Set();
}
public void ThrowItem(InventoryItem item) public void ThrowItem(InventoryItem item)
{ {
var thrownScene = GD.Load<PackedScene>("res://src/items/thrown/ThrownItem.tscn"); var thrownScene = GD.Load<PackedScene>("res://src/items/thrown/ThrownItem.tscn");
@@ -296,9 +306,7 @@ public partial class Game : Node3D, IGame
}) })
.Handle((in GameState.Output.CloseInventoryMenu _) => .Handle((in GameState.Output.CloseInventoryMenu _) =>
{ {
GameRepo.Resume(); CloseInventory();
InGameUI.InventoryMenu.Hide();
InGameUI.InventoryMenu.SetProcessInput(false);
}) })
.Handle((in GameState.Output.OpenDebugMenu _) => .Handle((in GameState.Output.OpenDebugMenu _) =>
{ {
@@ -325,6 +333,7 @@ public partial class Game : Node3D, IGame
}) })
.Handle((in GameState.Output.LoadNextFloor _) => .Handle((in GameState.Output.LoadNextFloor _) =>
{ {
_player.Reset();
LoadNextLevel.FadeOut(); LoadNextLevel.FadeOut();
EmitSignal(SignalName.OnLoadLevelRequest); EmitSignal(SignalName.OnLoadLevelRequest);
Task.Run(() => Save()); Task.Run(() => Save());
@@ -366,6 +375,15 @@ public partial class Game : Node3D, IGame
InGameUI.Hide(); InGameUI.Hide();
} }
private void ExitInventoryAction() => GameState.Input(new GameState.Input.CloseInventory());
private void CloseInventory()
{
GameRepo.Resume();
InGameUI.InventoryMenu.Hide();
InGameUI.InventoryMenu.SetProcessInput(false);
}
private async void LoadLevel() => await _map.LoadFloor(); private async void LoadLevel() => await _map.LoadFloor();
private void FloorClearMenu_GoToNextFloor() => GameState.Input(new GameState.Input.LoadNextFloor()); private void FloorClearMenu_GoToNextFloor() => GameState.Input(new GameState.Input.LoadNextFloor());
@@ -385,7 +403,13 @@ public partial class Game : Node3D, IGame
GameRepo.Resume(); GameRepo.Resume();
} }
private void UseTeleportPrompt_TeleportToNextFloor() => GameState.Input(new GameState.Input.UseTeleport()); private void UseTeleportPrompt_TeleportToNextFloor()
{
//_player.LookUp();
GameState.Input(new GameState.Input.UseTeleport());
}
private void PointUpFinished() => GameState.Input(new GameState.Input.UseTeleport());
private void FloorClearMenu_TransitionCompleted() private void FloorClearMenu_TransitionCompleted()
{ {

View File

@@ -22,6 +22,8 @@ public interface IGame : IProvide<IGame>, IProvide<IGameRepo>, IProvide<IPlayer>
public void DropItem(InventoryItem item); public void DropItem(InventoryItem item);
public void SetItem(InventoryItem item);
public void ThrowItem(InventoryItem item); public void ThrowItem(InventoryItem item);
public void FloorExitReached(); public void FloorExitReached();

View File

@@ -0,0 +1,38 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Chickensoft.Serialization;
using Godot;
using Zennysoft.Game.Ma;
using Zennysoft.Ma.Adapter;
using Zennysoft.Ma.Adapter.Entity;
[Meta(typeof(IAutoNode))]
public partial class Plastique : InventoryItem
{
public override void _Notification(int what) => this.Notify(what);
[Node] private Sprite3D _sprite { get; set; }
public override string ItemName => Stats.Name;
public override string Description => Stats.Description;
public override float SpawnRate => Stats.SpawnRate;
public override int ThrowDamage => Stats.ThrowDamage;
public override float ThrowSpeed => Stats.ThrowSpeed;
public override ItemTag ItemTag => Stats.ItemTag;
public void OnResolved()
{
_sprite.Texture = Stats.Texture;
}
public override Texture2D GetTexture() => Stats.Texture;
[Export]
[Save("inventory_stats")]
public EffectItemStats Stats { get; set; } = new EffectItemStats();
}

View File

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

View File

@@ -0,0 +1,57 @@
[gd_scene load_steps=7 format=3 uid="uid://c075bk1jydkwn"]
[ext_resource type="Script" uid="uid://c5p0e4ywktyvd" path="res://src/items/misc/Plastique.cs" id="1_jk2qh"]
[ext_resource type="Script" uid="uid://b5w4iw4iqmxtn" path="res://src/items/effect/EffectItemStats.cs" id="2_p8vuq"]
[ext_resource type="AudioStream" uid="uid://bjcersd5id8ee" path="res://src/audio/sfx/ITEM_PLASTIQUETIMER.ogg" id="2_vv5l4"]
[ext_resource type="Texture2D" uid="uid://bd6omweout2t6" path="res://src/items/Icons/plastique icon1.png" id="3_kmryk"]
[sub_resource type="Resource" id="Resource_vv5l4"]
script = ExtResource("2_p8vuq")
UsableItemTag = 0
ElementalDamageType = 4
Name = "Plastique"
Description = "Thermal"
SpawnRate = 0.5
BonusAttack = 0
BonusDefense = 0
BonusLuck = 0.05
BonusHP = 0
BonusVT = 0
AeolicResistance = 0
TelluricResistance = 0
HydricResistance = 0
IgneousResistance = 0
FerrumResistance = 0
ThrowSpeed = 12.0
ThrowDamage = 5
ItemTag = 0
Texture = ExtResource("3_kmryk")
AudioStream = ExtResource("2_vv5l4")
metadata/_custom_type_script = "uid://b5w4iw4iqmxtn"
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_etomv"]
radius = 0.470016
[node name="Plastique" type="Node3D"]
script = ExtResource("1_jk2qh")
Stats = SubResource("Resource_vv5l4")
[node name="Pickup" type="Area3D" parent="."]
unique_name_in_owner = true
collision_layer = 4
collision_mask = 0
[node name="Sprite" type="Sprite3D" parent="Pickup"]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.272665, 0)
layers = 5
pixel_size = 0.05
billboard = 2
double_sided = false
alpha_antialiasing_mode = 1
texture_filter = 0
render_priority = 100
texture = ExtResource("3_kmryk")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Pickup"]
shape = SubResource("CapsuleShape3D_etomv")

View File

@@ -0,0 +1,57 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System;
using Zennysoft.Ma.Adapter;
using Zennysoft.Ma.Adapter.Entity;
[Meta(typeof(IAutoNode))]
public partial class SetItem : RigidBody3D
{
public override void _Notification(int what) => this.Notify(what);
[Node] public AnimationTree AnimationTree { get; set; }
[Node] public Area3D ExplosionArea { get; set; }
[Dependency] public IPlayer Player => this.DependOn<IPlayer>();
protected AnimationNodeStateMachinePlayback _stateMachine;
protected readonly string _parametersPlayback = "parameters/playback";
public void OnReady()
{
_stateMachine = (AnimationNodeStateMachinePlayback)AnimationTree.Get(_parametersPlayback);
ExplosionArea.AreaEntered += ExplosionArea_AreaEntered;
AnimationTree.AnimationFinished += AnimationTree_AnimationFinished;
}
private void AnimationTree_AnimationFinished(StringName animName)
{
if (animName == "explode")
QueueFree();
}
private void ExplosionArea_AreaEntered(Area3D area)
{
// if (area is IDoor door) etc
// door.Demolish();
if (area.GetOwner() is IEnemy enemy)
enemy.HealthComponent.Damage(10);
}
public async void Set()
{
AddCollisionExceptionWith((Node)Player);
GlobalPosition = Player.GlobalPosition + Vector3.Up;
ApplyCentralImpulse(-Player.GlobalBasis.Z.Normalized() * 5.0f);
await ToSignal(GetTree().CreateTimer(1), "timeout");
Explode();
}
public void Explode()
{
_stateMachine.Travel("timer");
}
}

View File

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

View File

@@ -0,0 +1,302 @@
[gd_scene load_steps=22 format=4 uid="uid://d1dquaeraxymf"]
[ext_resource type="Script" uid="uid://da8mhruqpgh6r" path="res://src/items/misc/SetItem.cs" id="1_m8dyi"]
[ext_resource type="AudioStream" uid="uid://bjcersd5id8ee" path="res://src/audio/sfx/ITEM_PLASTIQUETIMER.ogg" id="2_kgxna"]
[ext_resource type="Texture2D" uid="uid://dkqs4x4pi18on" path="res://src/items/assetts/plastique_plastique.png" id="2_m8dyi"]
[sub_resource type="Animation" id="Animation_eat5q"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("ExplosionArea/Radius:scale")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0, 0, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("ExplosionArea/Radius:visible")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Model/Mesh:transparency")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("Model/Mesh:material_overlay:albedo_color")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 0)]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("ExplosionArea/CollisionShape3D:disabled")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="Animation" id="Animation_v8u1n"]
resource_name = "explode"
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("ExplosionArea/Radius:scale")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 1),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(0, 0, 0), Vector3(10, 10, 10)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("ExplosionArea/Radius:visible")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 1),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [true, false]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Model/Mesh:transparency")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.4),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0.0, 1.0]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("ExplosionArea/CollisionShape3D:disabled")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [false, false]
}
[sub_resource type="Animation" id="Animation_kgxna"]
resource_name = "explode"
length = 6.0
tracks/0/type = "audio"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("TimerCountdown")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.0,
"stream": ExtResource("2_kgxna")
}],
"times": PackedFloat32Array(0)
}
tracks/0/use_blend = true
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Model/Mesh:transparency")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Model/Mesh:material_overlay:albedo_color")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.366667, 0.5, 0.565232, 1.4, 1.53333, 1.59749, 2.4, 2.5572, 2.60183, 3.4, 3.6, 3.63109, 4.43333, 4.6, 4.63377, 5.47862, 5.6),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 0, 0, 0.439216), Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 0, 0, 0.439216), Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 0, 0, 0.439216), Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 0, 0, 0.439216), Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 0, 0, 0.439216), Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 0, 0, 0.439216)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_eat5q"]
_data = {
&"RESET": SubResource("Animation_eat5q"),
&"explode": SubResource("Animation_v8u1n"),
&"timer": SubResource("Animation_kgxna")
}
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_kgxna"]
transparency = 1
albedo_color = Color(1, 1, 1, 0)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_omo1p"]
resource_name = "Material"
cull_mode = 2
albedo_texture = ExtResource("2_m8dyi")
texture_filter = 2
[sub_resource type="ArrayMesh" id="ArrayMesh_kgxna"]
_surfaces = [{
"aabb": AABB(-2.73095, -1.72171, -1.52513, 5.45651, 2.42106, 3.07651),
"format": 34896613377,
"index_count": 180,
"index_data": PackedByteArray("AAABAAIAAgABAAMAAAAEAAEABQADAAEABQABAAQABgADAAUAAgADAAYABwAFAAQABwAEAAAABgAFAAcAAgAIAAAABgAJAAIAAgAJAAgABwAKAAYABgAKAAkAAAALAAcAAAAIAAsABwALAAoADAAIAAkADQAKAAsADgALAAgADgANAAsADAAOAAgADQAPAAoADwAJAAoADgAPAA0ADwAMAAkADgAMAA8AGAARABkAEwAZABEAGAAaABEAGgATABEAGwAaABgAGQATABQAGwAQABoAGgAcABMAEAAcABoAHAAdABMAFAATAB0AEAAVABwAGQAUABIAHAAeAB0AFQAeABwAHgAUAB0AEAAfABUAFQAfAB4AHgAgABQAIAASABQAHwAgAB4AIQAZABIAIAAhABIAIQAYABkAHwAXACAAFwAhACAAHwAWABcAFwAWACEAEAAWAB8AFgAYACEAFgAQABsAFgAbABgA"),
"lods": [0.327004, PackedByteArray("AAABAAIAAgABAAMAAAAEAAEABQADAAEABQABAAQABgADAAUAAgADAAYABwAFAAQABwAEAAAABgAFAAcAAgAIAAAABgAJAAIAAgAJAAgABwAKAAYABgAKAAkAAAALAAcAAAAIAAsABwALAAoADAAIAAkADQAKAAsADgALAAgADgANAAsADAAOAAgADQAPAAoADwAJAAoADgAPAA0ADwAMAAkADgAMAA8AEAARABIAEwASABEAEAATABEAEgATABQAEAAVABMAFgAQABIAFQAXABMAFwAUABMAEAAXABUAFwASABQAEAAWABcAFwAWABIA")],
"name": "Material",
"primitive": 3,
"uv_scale": Vector4(0, 0, 0, 0),
"vertex_count": 34,
"vertex_data": PackedByteArray("Wkz+nlowAABaTG7LpM8AAFpM/p6kzwAApLNuy6TPAABaTG7LWjAAAKSzbstaMAAApLP+nqTPAACks/6eWjAAAAAA/p4AAAAAAAD+nv//AAD///6e//8AAP///p4AAAAAAAAAAP//AAD//wAAAAAAAAAAAAAAAAAA//8AAP//AABVoOTJEV0AAKSX///3ZQAA1Gj///dlAACkl///5pUAANRo///mlQAAVaDkyc2eAAAjYOTJEV0AACNg5MnNngAAPIAc4gBOAAA8gP//AE4AAKSXHOL3ZQAAPIDkyTM8AACklxzi5pUAADyA///erQAAPIAc4t6tAAA8gOTJq78AANRoHOLmlQAA1Ggc4vdlAAA=")
}]
blend_shape_mode = 0
[sub_resource type="ArrayMesh" id="ArrayMesh_v8u1n"]
resource_name = "plastique_Cube"
_surfaces = [{
"aabb": AABB(-2.73095, -1.72171, -1.52513, 5.45651, 2.42106, 3.07651),
"attribute_data": PackedByteArray("ObJMZuOmqjI5sqoy46ZMZhjUs2uJq+H+iauzaxjU4f6sKX0WHQF5aR0BfRasKXlpOvaEw+vf9Js69vSb69+Ew3VUfRbmK3lp5it9FnVUeWnh/rNrUtbh/lLWs2vh/uH+/2X80lNWs2v/ZZmXT6mza1NW4f6imZmXopn80k+p4f45lolhl2ImJjmWJiaXYolhWc1MZgPC6SpZzekqA8JMZsm/TGZztOkqyb/pKnO0TGbJoztAc5iZDMmjmQxzmDtAaR1VsZwPVqycD2yRaR1tjNYXz9XWF7y2SyULzmIKgb5S1tFeO/uCScboeWnG6Ns+4Rn8dhQMaIkUDN954RlLjLQ2WcTmKFq/5ihwpLQ2cZ95LneHqyDkmasgWop5LsacPBfhnpwP4Z48F1asPBdskWkd4Z5LKFqKSyjkmYYwcKTmKOWxhjDlsYYwWr+0NuWxSyWBvmIKC860E995tBNoiVLWgkk7+9Fe"),
"format": 34896613399,
"index_count": 180,
"index_data": PackedByteArray("AAABAAIAAAADAAEABAAFAAYABAAHAAUACAAJAAoACAALAAkADAANAA4ADAAPAA0AEAARABIAEAATABEAFAAVABYAFAAXABUAGAAZABoAGgAZABsAGAAcABkAGgAbAB0AHgAcABgAHQAbAB8AHgAfABwAHQAfAB4AIAAhACIAIAAjACEAJAAlACYAJAAnACUAKAApACoAKAArACkALAAtAC4ALAAvAC0ASAAxAEkASABKADEASwBIAEkASwBJADIAMwBIAEsAMwBMAEgATABKAEgATAAwAEoATQBFAEYATQBOAEUARABOAE0ARABHAE4ATwBQAEIATwBRAFAAUQBBAFAAQwBRAE8AUQBSAEEAQwBTAFEAUwBSAFEAUwBAAFIANABUADYAVAA0ADcANwA0AFUAVAA3ADUAVgA9AD4AVgBXAD0APABXAFYAPAA/AFcAOwA4AFgAOAA7AFkAWQA7ADkAOABZADoA"),
"lods": [0.327004, PackedByteArray("AAABAAIAAAADAAEABAAFAAYABAAHAAUACAAJAAoACAALAAkADAANAA4ADAAPAA0AEAARABIAEAATABEAFAAVABYAFAAXABUAGAAZABoAGgAZABsAGAAcABkAGgAbAB0AHgAcABgAHQAbAB8AHgAfABwAHQAfAB4AIAAhACIAIAAjACEAJAAlACYAJAAnACUAKAApACoAKAArACkALAAtAC4ALAAvAC0AMAAxADIAMwAwADIANAA1ADYANQA0ADcAOAA5ADoAOAA7ADkAPAA9AD4APAA/AD0AQABBAEIAQwBAAEIARABFAEYARABHAEUA")],
"material": SubResource("StandardMaterial3D_omo1p"),
"name": "Material",
"primitive": 3,
"uv_scale": Vector4(0, 0, 0, 0),
"vertex_count": 90,
"vertex_data": PackedByteArray("Wkz+nlowFfZaTG7LpM9z0VpM/p6kz9vdWkxuy1owGvv//wAA//9z0QAA/p7//3PR///+nv//SsAAAAAA//9KwAAAAAD//0rAAAD+ngAAGfsAAP6e//9z0QAAAAAAAG/ZAAAAAAAAlvH//wAA//+Wsf//AAAAAEDcAAAAAP//veP//wAAAAAa+////p7//0rA///+ngAAb9n//wAA//9z0QAAAAAAAG/Z///+ngAAb9kAAP6eAAAZ+///AAAAABr7pLP+nqTP3MUAAP6e//++41pM/p6kz/jXAAD+ngAAlvH///6e//+VsVpM/p5aMD/jpLP+nlowQNf///6eAABB3KSzbstaMEDcWkxuy6TPveNaTG7LWjCW8aSzbsukz5axWkz+nqTP292ks27LpM9KwKSz/p6kzzLBWkxuy6TPc9Gks/6eWjC9zVpMbstaMBr7Wkz+nlowFfaks27LWjBv2aSz/p6kzzLBpLNuy1owb9mks/6eWjC9zaSzbsukz0rAVaDkyRFdL96kl///92VJ0tRo///3ZcP0I2DkyRFdr+Wkl///5pWtsdRo///3ZfTopJf///dlBdHUaP//5pXu11Wg5MkRXfr+I2Dkyc2efLNVoOTJzZ5f+SNg5MkRXfPVI2Dkyc2eHdXUaP//92XD9NRo///mlYPYI2DkyRFdo9UjYOTJzZ5zsdRo///mlYPYpJf//+aVicFVoOTJzZ5661Wg5MkRXYP1pJf//+aVicGkl///92VJ0lWg5MnNnkLBPIAc4gBOvvM8gP//AE5E7aSXHOL3ZbbU1Ggc4vdltPU8gOTJMzye9qSXHOL3Za7ZpJcc4uaVlL6klxzi5pXbzjyA///erTvEPIAc4t6t08HUaBzi5pW2xzyA5MmrvxLBPID//wBOg+c8gP//3q0VqtRoHOLmlTDZ1Ggc4vdloeo8gOTJMzyu/DyA5Mmrv6Lr+sr1HrR5za8eiwS1UFcEtUqGMVCzecyvN7e5eMZIRIfGSESHUFcEtbN5zK/nOgS1vT2NZA5oMkZxX2cxvlkncK6o+ko3t7l4F8X6SkqGMVDnOgS1F8X6SlBXBLWuqPpKq9AcIifwQCYZ4nopjeRCQjDG8Bdk2iw0E8cGKWaxjSBnsY0gJvBAJo3kQUIxxvEXHosEtTi3unjnwgiOtHnNr3vVzUhQVwS1+sr1HhfF+krnwgiOF8X6SnvVzUg4t7p4+pY+NHXEBVK/XHy0pzijlau9GSfR8ShIS7gaMTT5hTU8F/G/PlAL/hcMkdWfZVf23k9tjL9cfLQYc/SxiU8nwxxWN7UYc/Sx+7uBcHahqGWOtBFa+7uBcHXEBVKQjplHQca9OU3JsTaStrFCVFBuqiI73MQSwClXiLGnYxGzTXPqmeqZWpNak49yC7YncCZwD90rUY7rfi/SaIGoBFx0uOxZt+hyEXr7")
}]
blend_shape_mode = 0
shadow_mesh = SubResource("ArrayMesh_kgxna")
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_v8u1n"]
animation = &"explode"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_8ntcp"]
animation = &"timer"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_6b0xy"]
switch_mode = 2
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_8ps5k"]
switch_mode = 2
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_7onlu"]
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_ublq3"]
states/explode/node = SubResource("AnimationNodeAnimation_v8u1n")
states/explode/position = Vector2(634, 100)
states/timer/node = SubResource("AnimationNodeAnimation_8ntcp")
states/timer/position = Vector2(371, 100)
transitions = ["explode", "End", SubResource("AnimationNodeStateMachineTransition_6b0xy"), "timer", "explode", SubResource("AnimationNodeStateMachineTransition_8ps5k"), "Start", "timer", SubResource("AnimationNodeStateMachineTransition_7onlu")]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8ntcp"]
transparency = 1
albedo_color = Color(1, 1, 1, 0.113725)
[sub_resource type="SphereMesh" id="SphereMesh_6b0xy"]
material = SubResource("StandardMaterial3D_8ntcp")
[sub_resource type="SphereShape3D" id="SphereShape3D_kgxna"]
radius = 3.0
[sub_resource type="BoxShape3D" id="BoxShape3D_kgxna"]
size = Vector3(1, 0.303711, 0.469)
[node name="SetItem" type="RigidBody3D"]
process_mode = 1
collision_layer = 0
collision_mask = 5
axis_lock_angular_x = true
axis_lock_angular_y = true
axis_lock_angular_z = true
gravity_scale = 0.8
contact_monitor = true
script = ExtResource("1_m8dyi")
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
unique_name_in_owner = true
libraries = {
&"": SubResource("AnimationLibrary_eat5q")
}
[node name="Model" type="Node3D" parent="."]
transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0.00817871, 0)
[node name="Mesh" type="MeshInstance3D" parent="Model"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00269588, 0.721714, -0.0131256)
material_overlay = SubResource("StandardMaterial3D_kgxna")
mesh = SubResource("ArrayMesh_v8u1n")
skeleton = NodePath("")
[node name="TimerCountdown" type="AudioStreamPlayer3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.00817871, 0)
[node name="AnimationTree" type="AnimationTree" parent="."]
unique_name_in_owner = true
root_node = NodePath("%AnimationTree/..")
tree_root = SubResource("AnimationNodeStateMachine_ublq3")
anim_player = NodePath("../AnimationPlayer")
[node name="ExplosionArea" type="Area3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.00817871, 0)
collision_layer = 0
collision_mask = 2048
[node name="Radius" type="MeshInstance3D" parent="ExplosionArea"]
transform = Transform3D(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
mesh = SubResource("SphereMesh_6b0xy")
skeleton = NodePath("../..")
[node name="CollisionShape3D" type="CollisionShape3D" parent="ExplosionArea"]
shape = SubResource("SphereShape3D_kgxna")
[node name="CollisionShape3D2" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.199832, 0.0127869)
shape = SubResource("BoxShape3D_kgxna")

View File

@@ -0,0 +1,27 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
[Meta(typeof(IAutoNode))]
public partial class Door : Node3D, IDoor
{
public override void _Notification(int what) => this.Notify(what);
[Node] public AnimationPlayer AnimationPlayer { get; set; }
public void OnReady()
{
AnimationPlayer.AnimationFinished += AnimationPlayer_AnimationFinished;
}
private void AnimationPlayer_AnimationFinished(StringName animName)
{
QueueFree();
}
public void Demolish()
{
AnimationPlayer.Play("explode");
}
}

View File

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

View File

@@ -0,0 +1,5 @@
using Chickensoft.GodotNodeInterfaces;
public interface IDoor : INode3D
{
}

View File

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

View File

@@ -34,73 +34,73 @@ public partial class Map : Node3D, IMap
public void OnResolved() public void OnResolved()
{ {
this.Provide(); this.Provide();
} }
public void InitializeMapData() public void InitializeMapData()
{ {
CurrentFloorNumber.OnNext(-1); CurrentFloorNumber.OnNext(-1);
} }
public IDungeonRoom GetPlayersCurrentRoom() public IDungeonRoom GetPlayersCurrentRoom()
{ {
var rooms = CurrentFloor.Rooms; var rooms = CurrentFloor.Rooms;
var playersRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom); var playersRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom);
return playersRoom; return playersRoom;
} }
public Transform3D GetPlayerSpawnPosition() => CurrentFloor.GetPlayerSpawnPoint(); public Transform3D GetPlayerSpawnPosition() => CurrentFloor.GetPlayerSpawnPoint();
public async Task LoadFloor() public async Task LoadFloor()
{ {
var floor = MapOrder.GetChildren().OfType<FloorNode>().ElementAt(CurrentFloorNumber.Value + 1); var floor = MapOrder.GetChildren().OfType<FloorNode>().ElementAt(CurrentFloorNumber.Value + 1);
var sceneToLoad = LayoutToScenePathConverter.Convert(floor); var sceneToLoad = LayoutToScenePathConverter.Convert(floor);
await LoadFloor(sceneToLoad); await LoadFloor(sceneToLoad);
if (CurrentFloor is DungeonFloor dungeonFloor && floor is DungeonFloorNode dungeonFloorNode) if (CurrentFloor is DungeonFloor dungeonFloor && floor is DungeonFloorNode dungeonFloorNode)
dungeonFloor.SpawnEnemies(dungeonFloorNode); dungeonFloor.SpawnEnemies(dungeonFloorNode);
} }
public async Task LoadFloor(string sceneName) public async Task LoadFloor(string sceneName)
{ {
AnimationPlayer.CallDeferred(AnimationPlayer.MethodName.Play, "fade_out"); AnimationPlayer.CallDeferred(AnimationPlayer.MethodName.Play, "fade_out");
ClearMap(); ClearMap();
var newFloor = await LoadNewFloor(sceneName); var newFloor = await LoadNewFloor(sceneName);
AddChild(newFloor); AddChild(newFloor);
InitializeFloor(newFloor); InitializeFloor(newFloor);
AnimationPlayer.CallDeferred(AnimationPlayer.MethodName.Play, ("fade_in")); AnimationPlayer.CallDeferred(AnimationPlayer.MethodName.Play, ("fade_in"));
} }
public void ClearMap() public void ClearMap()
{ {
AnimationPlayer.CallDeferred(AnimationPlayer.MethodName.Play, "fade_out"); AnimationPlayer.CallDeferred(AnimationPlayer.MethodName.Play, "fade_out");
CurrentFloor?.CallDeferred(MethodName.QueueFree, []); CurrentFloor?.CallDeferred(MethodName.QueueFree, []);
SpawnPointCreated?.Invoke(new Transform3D(Basis.Identity, new Vector3(-999, -999, -999))); SpawnPointCreated?.Invoke(new Transform3D(Basis.Identity, new Vector3(-999, -999, -999)));
} }
private void InitializeFloor(Node newFloor) private void InitializeFloor(Node newFloor)
{ {
CurrentFloor = (IDungeonFloor)newFloor; CurrentFloor = (IDungeonFloor)newFloor;
SetupDungeonFloor(); SetupDungeonFloor();
CurrentFloor.FloorIsLoaded = true; CurrentFloor.FloorIsLoaded = true;
CurrentFloorNumber.OnNext(CurrentFloorNumber.Value + 1); CurrentFloorNumber.OnNext(CurrentFloorNumber.Value + 1);
FloorLoaded?.Invoke(); FloorLoaded?.Invoke();
} }
private async Task<Node> LoadNewFloor(string sceneName) private async Task<Node> LoadNewFloor(string sceneName)
{ {
var sceneLoader = new SceneLoader(); var sceneLoader = new SceneLoader();
AddChild(sceneLoader); AddChild(sceneLoader);
sceneLoader.LoadSceneRequest(sceneName); sceneLoader.LoadSceneRequest(sceneName);
await ToSignal(sceneLoader, SceneLoader.SignalName.SceneLoaded); await ToSignal(sceneLoader, SceneLoader.SignalName.SceneLoaded);
var result = sceneLoader.LoadedScene; var result = sceneLoader.LoadedScene;
sceneLoader.QueueFree(); sceneLoader.QueueFree();
return result; return result;
} }
private void SetupDungeonFloor() private void SetupDungeonFloor()
{ {
CurrentFloor.InitializeDungeon(); CurrentFloor.InitializeDungeon();
var transform = GetPlayerSpawnPosition(); var transform = GetPlayerSpawnPosition();
SpawnPointCreated?.Invoke(transform); SpawnPointCreated?.Invoke(transform);
} }
} }

View File

@@ -2,6 +2,7 @@ using Chickensoft.AutoInject;
using Chickensoft.Introspection; using Chickensoft.Introspection;
using Godot; using Godot;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq;
using Zennysoft.Ma.Adapter; using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma; namespace Zennysoft.Game.Ma;
@@ -13,6 +14,8 @@ public partial class Altar : Node3D, IDungeonFloor
[Dependency] protected IGame Game => this.DependOn<IGame>(); [Dependency] protected IGame Game => this.DependOn<IGame>();
[Dependency] protected IPlayer _player => this.DependOn(() => GetParent().GetChildren().OfType<IPlayer>().Single());
[Node] private Area3D Exit { get; set; } = default!; [Node] private Area3D Exit { get; set; } = default!;
[Node] private Marker3D PlayerSpawnPoint { get; set; } = default!; [Node] private Marker3D PlayerSpawnPoint { get; set; } = default!;
@@ -25,25 +28,29 @@ public partial class Altar : Node3D, IDungeonFloor
public bool FloorIsLoaded { get; set; } public bool FloorIsLoaded { get; set; }
public override void _Ready() public void OnResolved()
{ {
Show(); Show();
Exit.AreaEntered += Exit_AreaEntered; Exit.AreaEntered += Exit_AreaEntered;
NoExitArea.AreaEntered += NoExitArea_AreaEntered; NoExitArea.AreaEntered += NoExitArea_AreaEntered;
FloorIsLoaded = true; _player.PointUpFinished += _player_PointUpFinished;
FloorIsLoaded = true;
}
private void _player_PointUpFinished()
{
_player.Activate();
} }
private void NoExitArea_AreaEntered(Area3D area) private void NoExitArea_AreaEntered(Area3D area)
{ {
DialogueController.ShowDialogue(Dialogue, "no_exit"); DialogueController.ShowDialogue(Dialogue, "no_exit");
//if (area.GetOwner() is IPlayer player)
// player.Deactivate();
} }
private void Exit_AreaEntered(Area3D area) private void Exit_AreaEntered(Area3D area)
{ {
if (area.GetOwner() is IPlayer) if (area.GetOwner() is IPlayer)
ExitReached(); ExitReached();
} }
public void ExitReached() => Game.FloorExitReached(); public void ExitReached() => Game.FloorExitReached();

File diff suppressed because one or more lines are too long

View File

@@ -184,6 +184,7 @@ public partial class OptionsMenu : Control
var selectedDeviceIndex = AudioServer.GetOutputDeviceList().ToList().IndexOf(optionsData.AudioDeviceName); var selectedDeviceIndex = AudioServer.GetOutputDeviceList().ToList().IndexOf(optionsData.AudioDeviceName);
SoundDeviceOptions.Select(selectedDeviceIndex); SoundDeviceOptions.Select(selectedDeviceIndex);
} }
SkipOpeningCSCheck.ButtonPressed = optionsData.SkipCutscene; SkipOpeningCSCheck.ButtonPressed = optionsData.SkipCutscene;
DisplayServer.WindowSetMode(_windowModes[optionsData.ScreenResolution]); DisplayServer.WindowSetMode(_windowModes[optionsData.ScreenResolution]);
} }

View File

@@ -71,6 +71,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
private bool HealthTimerIsActive = false; private bool HealthTimerIsActive = false;
#endregion #endregion
public event Action PointUpFinished;
#region Node Dependencies #region Node Dependencies
[Node] private IAnimationPlayer AnimationPlayer { get; set; } = default!; [Node] private IAnimationPlayer AnimationPlayer { get; set; } = default!;
@@ -91,6 +93,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
[Node] private CollisionShape3D MainCollision { get; set; } = default!; [Node] private CollisionShape3D MainCollision { get; set; } = default!;
[Node] private ShakeCamera _camera3D { get; set; } = default!; [Node] private ShakeCamera _camera3D { get; set; } = default!;
[Node] private AnimationPlayer CameraAnimations { get; set; } = default!;
#endregion #endregion
@@ -107,187 +111,201 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
public void Initialize() public void Initialize()
{ {
var container = new SimpleInjector.Container(); var container = new SimpleInjector.Container();
container.Register<IPlayerLogic, PlayerLogic>(Lifestyle.Singleton); container.Register<IPlayerLogic, PlayerLogic>(Lifestyle.Singleton);
PlayerLogic = container.GetInstance<IPlayerLogic>(); PlayerLogic = container.GetInstance<IPlayerLogic>();
PlayerLogic.Set(this as IPlayer); PlayerLogic.Set(this as IPlayer);
PlayerLogic.Set(Settings); PlayerLogic.Set(Settings);
Inventory = new Inventory(); Inventory = new Inventory();
HealthComponent = new HealthComponent(InitialHP); HealthComponent = new HealthComponent(InitialHP);
VTComponent = new VTComponent(InitialVT); VTComponent = new VTComponent(InitialVT);
AttackComponent = new AttackComponent(InitialAttack); AttackComponent = new AttackComponent(InitialAttack);
DefenseComponent = new DefenseComponent(InitialDefense); DefenseComponent = new DefenseComponent(InitialDefense);
ExperiencePointsComponent = new ExperiencePointsComponent(); ExperiencePointsComponent = new ExperiencePointsComponent();
LuckComponent = new LuckComponent(InitialLuck); LuckComponent = new LuckComponent(InitialLuck);
EquipmentComponent = new EquipmentComponent(); EquipmentComponent = new EquipmentComponent();
_itemReroller = new ItemReroller(ItemDatabase.Instance); _itemReroller = new ItemReroller(ItemDatabase.Instance);
Settings = new PlayerLogic.Settings() { RotationSpeed = RotationSpeed, MoveSpeed = MoveSpeed, Acceleration = Acceleration }; CameraAnimations.AnimationFinished += CameraAnimations_AnimationFinished;
PlayerBinding = PlayerLogic.Bind(); Settings = new PlayerLogic.Settings() { RotationSpeed = RotationSpeed, MoveSpeed = MoveSpeed, Acceleration = Acceleration };
PlayerBinding PlayerBinding = PlayerLogic.Bind();
.Handle((in PlayerLogic.Output.ThrowItem output) =>
{
})
.Handle((in PlayerLogic.Output.Move output) =>
{
Move(output.delta);
});
PlayerLogic.Start(); PlayerBinding
this.Provide(); .Handle((in PlayerLogic.Output.ThrowItem output) =>
{
})
.Handle((in PlayerLogic.Output.Move output) =>
{
Move(output.delta);
});
PlayerLogic.Start();
this.Provide();
} }
public void ResetPlayerData() public void ResetPlayerData()
{ {
foreach (var item in Inventory.Items) foreach (var item in Inventory.Items)
Inventory.Remove(item); Inventory.Remove(item);
HealthComponent.Reset(); HealthComponent.Reset();
VTComponent.Reset(); VTComponent.Reset();
AttackComponent.Reset(); AttackComponent.Reset();
DefenseComponent.Reset(); DefenseComponent.Reset();
ExperiencePointsComponent.Reset(); ExperiencePointsComponent.Reset();
LuckComponent.Reset(); LuckComponent.Reset();
EquipmentComponent.Reset(); EquipmentComponent.Reset();
HealthTimer.Timeout += OnHealthTimerTimeout; HealthTimer.Timeout += OnHealthTimerTimeout;
} }
#region Initialization #region Initialization
public void OnReady() public void OnReady()
{ {
Hitbox.AreaEntered += Hitbox_AreaEntered; Hitbox.AreaEntered += Hitbox_AreaEntered;
CollisionDetector.AreaEntered += CollisionDetector_AreaEntered; CollisionDetector.AreaEntered += CollisionDetector_AreaEntered;
HealthComponent.HealthReachedZero += Die; HealthComponent.HealthReachedZero += Die;
HealthTimer.WaitTime = _healthTimerWaitTime; HealthTimer.WaitTime = _healthTimerWaitTime;
SetProcessInput(false); SetProcessInput(false);
SetPhysicsProcess(false); SetPhysicsProcess(false);
} }
#endregion #endregion
public void Activate() public void Activate()
{ {
SetProcessInput(true); SetProcessInput(true);
SetPhysicsProcess(true); SetPhysicsProcess(true);
SetHealthTimerStatus(HealthTimerIsActive); SetHealthTimerStatus(HealthTimerIsActive);
} }
public void Deactivate() public void Deactivate()
{ {
Velocity = Vector3.Zero; Velocity = Vector3.Zero;
SetProcessInput(false); SetProcessInput(false);
SetPhysicsProcess(false); SetPhysicsProcess(false);
SetHealthTimerStatus(false); SetHealthTimerStatus(false);
} }
public void LookUp() => CameraAnimations.Play("look_up");
private void SetHealthTimerStatus(bool isActive) private void SetHealthTimerStatus(bool isActive)
{ {
if (isActive) if (isActive)
HealthTimer.Start(); HealthTimer.Start();
else else
HealthTimer.Stop(); HealthTimer.Stop();
} }
public void TeleportPlayer(Transform3D newTransform) public void TeleportPlayer(Transform3D newTransform)
{ {
Transform = newTransform; Transform = newTransform;
} }
public void TakeDamage(AttackData damage) public void TakeDamage(AttackData damage)
{ {
_camera3D.AddShake(1.0f); _camera3D.AddShake(1.0f);
TakeDamageAnimationPlayer.Play("take_damage"); TakeDamageAnimationPlayer.Play("take_damage");
var damageReceived = DamageCalculator.CalculateDamage(damage, DefenseComponent.CurrentDefense.Value + EquipmentComponent.BonusDefense, EquipmentComponent.ElementalResistance); var damageReceived = DamageCalculator.CalculateDamage(damage, DefenseComponent.CurrentDefense.Value + EquipmentComponent.BonusDefense, EquipmentComponent.ElementalResistance);
HealthComponent.Damage(damageReceived); HealthComponent.Damage(damageReceived);
SfxDatabase.Instance.Play(SoundEffect.TakeDamage); SfxDatabase.Instance.Play(SoundEffect.TakeDamage);
} }
public void Knockback(float impulse) public void Knockback(float impulse)
{ {
_knockbackStrength = impulse; _knockbackStrength = impulse;
_knockbackDirection = GlobalBasis.Z.Normalized(); _knockbackDirection = GlobalBasis.Z.Normalized();
} }
public void LevelUp() public void LevelUp()
{ {
var rng = new RandomNumberGenerator(); var rng = new RandomNumberGenerator();
rng.Randomize(); rng.Randomize();
var hpIncrease = rng.RandiRange(3, 6); var hpIncrease = rng.RandiRange(3, 6);
HealthComponent.RaiseMaximumHP(hpIncrease); HealthComponent.RaiseMaximumHP(hpIncrease);
ExperiencePointsComponent.LevelUp(); ExperiencePointsComponent.LevelUp();
} }
public void Die() public void Die()
{ {
PlayerFXAnimations.Play("death"); PlayerFXAnimations.Play("death");
HealthTimer.WaitTime = _healthTimerWaitTime; HealthTimer.WaitTime = _healthTimerWaitTime;
HealthTimer.Timeout -= OnHealthTimerTimeout; HealthTimer.Timeout -= OnHealthTimerTimeout;
SetProcessInput(false); SetProcessInput(false);
SetPhysicsProcess(false); SetPhysicsProcess(false);
PlayerDied?.Invoke(); PlayerDied?.Invoke();
}
public void Reset()
{
CameraAnimations.Play("RESET");
} }
public override void _Input(InputEvent @event) public override void _Input(InputEvent @event)
{ {
if (@event.IsActionPressed(GameInputs.Attack)) if (@event.IsActionPressed(GameInputs.Attack))
Attack(); Attack();
if (@event.IsActionPressed(GameInputs.Sprint)) if (@event.IsActionPressed(GameInputs.Sprint))
Settings.MoveSpeed *= 2; Settings.MoveSpeed *= 2;
if (@event.IsActionReleased(GameInputs.Sprint)) if (@event.IsActionReleased(GameInputs.Sprint))
Settings.MoveSpeed /= 2; Settings.MoveSpeed /= 2;
} }
public void PlayTestAnimation() public void PlayTestAnimation()
{ {
PlayerFXAnimations.Play("test_animation"); PlayerFXAnimations.Play("test_animation");
} }
public void OnPhysicsProcess(double delta) public void OnPhysicsProcess(double delta)
{ {
PlayerLogic.Input(new PlayerLogic.Input.PhysicsTick(delta)); PlayerLogic.Input(new PlayerLogic.Input.PhysicsTick(delta));
PlayerLogic.Input(new PlayerLogic.Input.Moved(GlobalPosition, GlobalTransform)); PlayerLogic.Input(new PlayerLogic.Input.Moved(GlobalPosition, GlobalTransform));
} }
public void Equip(EquipableItem equipable) public void Equip(EquipableItem equipable)
{ {
if (equipable.ItemTag == ItemTag.MysteryItem) if (equipable.ItemTag == ItemTag.MysteryItem)
{ {
var rerolledItem = _itemReroller.RerollItem(equipable, Inventory); var rerolledItem = _itemReroller.RerollItem(equipable, Inventory);
Equip(rerolledItem); Equip(rerolledItem);
return; return;
} }
HealthComponent.RaiseMaximumHP(equipable.BonusHP, false); HealthComponent.RaiseMaximumHP(equipable.BonusHP, false);
VTComponent.RaiseMaximumVT(equipable.BonusVT, false); VTComponent.RaiseMaximumVT(equipable.BonusVT, false);
EquipmentComponent.Equip(equipable); EquipmentComponent.Equip(equipable);
} }
public void Unequip(EquipableItem equipable) public void Unequip(EquipableItem equipable)
{ {
HealthComponent.SetMaximumHealth(HealthComponent.MaximumHP.Value - equipable.BonusHP); HealthComponent.SetMaximumHealth(HealthComponent.MaximumHP.Value - equipable.BonusHP);
VTComponent.SetMaximumVT(VTComponent.MaximumVT.Value - equipable.BonusVT); VTComponent.SetMaximumVT(VTComponent.MaximumVT.Value - equipable.BonusVT);
EquipmentComponent.Unequip(equipable); EquipmentComponent.Unequip(equipable);
}
private void CameraAnimations_AnimationFinished(StringName animName)
{
PointUpFinished?.Invoke();
} }
private static Vector3 GlobalInputVector private static Vector3 GlobalInputVector
{ {
get get
{ {
var rawInput = Input.GetVector(GameInputs.MoveLeft, GameInputs.MoveRight, GameInputs.MoveUp, GameInputs.MoveDown); var rawInput = Input.GetVector(GameInputs.MoveLeft, GameInputs.MoveRight, GameInputs.MoveUp, GameInputs.MoveDown);
var input = new Vector3 var input = new Vector3
{ {
X = rawInput.X, X = rawInput.X,
Z = rawInput.Y Z = rawInput.Y
}; };
return input with { Y = 0f }; return input with { Y = 0f };
} }
} }
private static float LeftStrafeInputVector => Input.GetActionStrength(GameInputs.StrafeLeft); private static float LeftStrafeInputVector => Input.GetActionStrength(GameInputs.StrafeLeft);
@@ -296,143 +314,143 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
private void Attack() private void Attack()
{ {
if (PlayerIsHittingGeometry()) if (PlayerIsHittingGeometry())
AnimationPlayer.Play("hit_wall"); AnimationPlayer.Play("hit_wall");
else if (!AnimationPlayer.IsPlaying()) else if (!AnimationPlayer.IsPlaying())
PlayAttackAnimation(); PlayAttackAnimation();
} }
private void ThrowItem() private void ThrowItem()
{ {
var itemScene = GD.Load<PackedScene>("res://src/items/throwable/ThrowableItem.tscn"); var itemScene = GD.Load<PackedScene>("res://src/items/throwable/ThrowableItem.tscn");
var throwItem = itemScene.Instantiate<ThrowableItem>(); var throwItem = itemScene.Instantiate<ThrowableItem>();
GetTree().Root.AddChildEx(throwItem); GetTree().Root.AddChildEx(throwItem);
throwItem.GlobalPosition = CurrentPosition + new Vector3(0, 3.5f, 0); throwItem.GlobalPosition = CurrentPosition + new Vector3(0, 3.5f, 0);
throwItem.GlobalRotation = GlobalRotation; throwItem.GlobalRotation = GlobalRotation;
} }
private void PlayAttackAnimation() private void PlayAttackAnimation()
{ {
SfxDatabase.Instance.Play(((Weapon)EquipmentComponent.EquippedWeapon.Value).SoundEffect); SfxDatabase.Instance.Play(((Weapon)EquipmentComponent.EquippedWeapon.Value).SoundEffect);
var attackSpeed = ((Weapon)EquipmentComponent.EquippedWeapon.Value).AttackSpeed; var attackSpeed = ((Weapon)EquipmentComponent.EquippedWeapon.Value).AttackSpeed;
AnimationPlayer.SetSpeedScale((float)attackSpeed); AnimationPlayer.SetSpeedScale((float)attackSpeed);
AnimationPlayer.Play("attack"); AnimationPlayer.Play("attack");
} }
private void OnExitTree() private void OnExitTree()
{ {
PlayerLogic.Stop(); PlayerLogic.Stop();
PlayerBinding.Dispose(); PlayerBinding.Dispose();
Hitbox.AreaEntered -= Hitbox_AreaEntered; Hitbox.AreaEntered -= Hitbox_AreaEntered;
CollisionDetector.AreaEntered -= CollisionDetector_AreaEntered; CollisionDetector.AreaEntered -= CollisionDetector_AreaEntered;
HealthComponent.HealthReachedZero -= Die; HealthComponent.HealthReachedZero -= Die;
HealthTimer.Timeout -= OnHealthTimerTimeout; HealthTimer.Timeout -= OnHealthTimerTimeout;
} }
private void Move(float delta) private void Move(float delta)
{ {
var rawInput = GlobalInputVector; var rawInput = GlobalInputVector;
var strafeLeftInput = LeftStrafeInputVector; var strafeLeftInput = LeftStrafeInputVector;
var strafeRightInput = RightStrafeInputVector; var strafeRightInput = RightStrafeInputVector;
var transform = Transform; var transform = Transform;
transform.Basis = new Basis(Vector3.Up, Settings.RotationSpeed * -rawInput.X * delta) * transform.Basis; transform.Basis = new Basis(Vector3.Up, Settings.RotationSpeed * -rawInput.X * delta) * transform.Basis;
var moveDirection = new Vector3(strafeRightInput - strafeLeftInput, 0, rawInput.Z).Normalized(); var moveDirection = new Vector3(strafeRightInput - strafeLeftInput, 0, rawInput.Z).Normalized();
var velocity = Basis * moveDirection * Settings.MoveSpeed * Settings.Acceleration; var velocity = Basis * moveDirection * Settings.MoveSpeed * Settings.Acceleration;
_knockbackStrength *= 0.9f; _knockbackStrength *= 0.9f;
Transform = Transform with { Basis = transform.Basis }; Transform = Transform with { Basis = transform.Basis };
Velocity = velocity + (_knockbackDirection * _knockbackStrength); Velocity = velocity + (_knockbackDirection * _knockbackStrength);
if (!WalkSFX.Playing && !Velocity.IsZeroApprox()) if (!WalkSFX.Playing && !Velocity.IsZeroApprox())
WalkSFX.Play(); WalkSFX.Play();
else if (Velocity.IsZeroApprox()) else if (Velocity.IsZeroApprox())
WalkSFX.Stop(); WalkSFX.Stop();
MoveAndSlide(); MoveAndSlide();
} }
private void OnPlayerPositionUpdated(Vector3 globalPosition) => GlobalPosition = globalPosition; private void OnPlayerPositionUpdated(Vector3 globalPosition) => GlobalPosition = globalPosition;
private void OnHealthTimerTimeout() private void OnHealthTimerTimeout()
{ {
if (VTComponent.CurrentVT.Value > 0) if (VTComponent.CurrentVT.Value > 0)
{ {
if (((Accessory)EquipmentComponent.EquippedAccessory.Value).AccessoryTag == AccessoryTag.HalfVTConsumption) if (((Accessory)EquipmentComponent.EquippedAccessory.Value).AccessoryTag == AccessoryTag.HalfVTConsumption)
reduceOnTick = !reduceOnTick; reduceOnTick = !reduceOnTick;
HealthComponent.Heal(1); HealthComponent.Heal(1);
if (reduceOnTick) if (reduceOnTick)
VTComponent.Reduce(1); VTComponent.Reduce(1);
} }
else else
HealthComponent.Damage(1); HealthComponent.Damage(1);
} }
private void Hitbox_AreaEntered(Area3D area) private void Hitbox_AreaEntered(Area3D area)
{ {
var target = area.GetOwner(); var target = area.GetOwner();
if (target is IEnemy enemy) if (target is IEnemy enemy)
HitEnemy(enemy); HitEnemy(enemy);
} }
private void HitEnemy(IEnemy enemy) private void HitEnemy(IEnemy enemy)
{ {
var ignoreElementalResistance = (EquipmentComponent.EquippedWeapon.Value as Weapon).WeaponTag == WeaponTag.IgnoreAffinity; var ignoreElementalResistance = (EquipmentComponent.EquippedWeapon.Value as Weapon).WeaponTag == WeaponTag.IgnoreAffinity;
var ignoreDefense = (EquipmentComponent.EquippedWeapon.Value as Weapon).WeaponTag == WeaponTag.IgnoreDefense; var ignoreDefense = (EquipmentComponent.EquippedWeapon.Value as Weapon).WeaponTag == WeaponTag.IgnoreDefense;
var isCriticalHit = BattleExtensions.IsCriticalHit(LuckComponent.Luck.Value + EquipmentComponent.BonusLuck); var isCriticalHit = BattleExtensions.IsCriticalHit(LuckComponent.Luck.Value + EquipmentComponent.BonusLuck);
var totalDamage = AttackComponent.CurrentAttack.Value + EquipmentComponent.BonusAttack; var totalDamage = AttackComponent.CurrentAttack.Value + EquipmentComponent.BonusAttack;
var element = (EquipmentComponent.EquippedWeapon.Value as Weapon).WeaponElement; var element = (EquipmentComponent.EquippedWeapon.Value as Weapon).WeaponElement;
if (isCriticalHit) if (isCriticalHit)
{ {
totalDamage += (int)(totalDamage * 0.5f); totalDamage += (int)(totalDamage * 0.5f);
SfxDatabase.Instance.Play(SoundEffect.Crit); SfxDatabase.Instance.Play(SoundEffect.Crit);
} }
var baseAttack = new AttackData(totalDamage, element, ignoreDefense, ignoreElementalResistance); var baseAttack = new AttackData(totalDamage, element, ignoreDefense, ignoreElementalResistance);
var damageDealt = DamageCalculator.CalculateDamage(baseAttack, enemy.DefenseComponent.CurrentDefense.Value, ElementalResistanceSet.None); var damageDealt = DamageCalculator.CalculateDamage(baseAttack, enemy.DefenseComponent.CurrentDefense.Value, ElementalResistanceSet.None);
enemy.HealthComponent.Damage(damageDealt); enemy.HealthComponent.Damage(damageDealt);
if (((Weapon)EquipmentComponent.EquippedWeapon.Value).WeaponTag == WeaponTag.Knockback && enemy is IKnockbackable knockbackable) if (((Weapon)EquipmentComponent.EquippedWeapon.Value).WeaponTag == WeaponTag.Knockback && enemy is IKnockbackable knockbackable)
knockbackable.Knockback(0.3f, -CurrentBasis.Z.Normalized()); knockbackable.Knockback(0.3f, -CurrentBasis.Z.Normalized());
if (((Weapon)EquipmentComponent.EquippedWeapon.Value).WeaponTag == WeaponTag.SelfDamage) if (((Weapon)EquipmentComponent.EquippedWeapon.Value).WeaponTag == WeaponTag.SelfDamage)
HealthComponent.Damage(5); HealthComponent.Damage(5);
} }
private void CollisionDetector_AreaEntered(Area3D area) private void CollisionDetector_AreaEntered(Area3D area)
{ {
if (area.GetParent() is InventoryItem inventoryItem) if (area.GetParent() is InventoryItem inventoryItem)
{ {
var isAdded = Inventory.PickUpItem(inventoryItem); var isAdded = Inventory.PickUpItem(inventoryItem);
if (isAdded) if (isAdded)
inventoryItem.QueueFree(); inventoryItem.QueueFree();
} }
if (area.GetParent() is DroppedItem droppedItem) if (area.GetParent() is DroppedItem droppedItem)
{ {
var isAdded = Inventory.PickUpItem(droppedItem.Item); var isAdded = Inventory.PickUpItem(droppedItem.Item);
if (isAdded) if (isAdded)
droppedItem.QueueFree(); droppedItem.QueueFree();
} }
if (area.GetParent() is ThrownItem thrownItem) if (area.GetParent() is ThrownItem thrownItem)
{ {
var isAdded = Inventory.PickUpItem(thrownItem.ItemThatIsThrown); var isAdded = Inventory.PickUpItem(thrownItem.ItemThatIsThrown);
if (isAdded) if (isAdded)
thrownItem.QueueFree(); thrownItem.QueueFree();
} }
if (area.GetParent() is Restorative restorative) if (area.GetParent() is Restorative restorative)
{ {
restorative.QueueFree(); restorative.QueueFree();
} }
} }
private bool PlayerIsHittingGeometry() private bool PlayerIsHittingGeometry()
{ {
var collisions = WallCheck.GetCollidingBodies(); var collisions = WallCheck.GetCollidingBodies();
return collisions.Count > 0; return collisions.Count > 0;
} }
private void WallCheck_BodyEntered(Node body) private void WallCheck_BodyEntered(Node body)
{ {
GD.Print("Hit wall"); GD.Print("Hit wall");
AnimationPlayer.Stop(); AnimationPlayer.Stop();
} }
} }

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=1729 format=3 uid="uid://cfecvvav8kkp6"] [gd_scene load_steps=1732 format=3 uid="uid://cfecvvav8kkp6"]
[ext_resource type="Script" uid="uid://yxmiqy7i0t7r" path="res://src/player/Player.cs" id="1_xcol5"] [ext_resource type="Script" uid="uid://yxmiqy7i0t7r" path="res://src/player/Player.cs" id="1_xcol5"]
[ext_resource type="PackedScene" uid="uid://didc6vnf5ftlg" path="res://src/camera/ShakeCamera.tscn" id="2_jtmj1"] [ext_resource type="PackedScene" uid="uid://didc6vnf5ftlg" path="res://src/camera/ShakeCamera.tscn" id="2_jtmj1"]
@@ -46,6 +46,42 @@ material = SubResource("ShaderMaterial_jtmj1")
flip_faces = true flip_faces = true
size = Vector2(2, 2) size = Vector2(2, 2)
[sub_resource type="Animation" id="Animation_ilpvp"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:rotation")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0, 0, 0)]
}
[sub_resource type="Animation" id="Animation_ubmds"]
resource_name = "look_up"
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:rotation")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 1),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(0, 0, 0), Vector3(0.785398, 0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_sifmb"]
_data = {
&"RESET": SubResource("Animation_ilpvp"),
&"look_up": SubResource("Animation_ubmds")
}
[sub_resource type="Animation" id="Animation_3ojaj"] [sub_resource type="Animation" id="Animation_3ojaj"]
resource_name = "IconAnimation" resource_name = "IconAnimation"
length = 2.5 length = 2.5
@@ -163,371 +199,6 @@ _data = {
&"hit_wall": SubResource("Animation_qgbg1") &"hit_wall": SubResource("Animation_qgbg1")
} }
[sub_resource type="AtlasTexture" id="AtlasTexture_gx6yx"]
atlas = ExtResource("5_bngr8")
region = Rect2(0, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_5gt6s"]
atlas = ExtResource("5_bngr8")
region = Rect2(512, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_syglp"]
atlas = ExtResource("5_bngr8")
region = Rect2(1024, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_o81wv"]
atlas = ExtResource("5_bngr8")
region = Rect2(1536, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_uc14s"]
atlas = ExtResource("5_bngr8")
region = Rect2(2048, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_84vg4"]
atlas = ExtResource("5_bngr8")
region = Rect2(2560, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_18gts"]
atlas = ExtResource("5_bngr8")
region = Rect2(3072, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_sq31b"]
atlas = ExtResource("5_bngr8")
region = Rect2(3584, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_ucph0"]
atlas = ExtResource("5_bngr8")
region = Rect2(4096, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_5pe5a"]
atlas = ExtResource("5_bngr8")
region = Rect2(4608, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_iqf1f"]
atlas = ExtResource("5_bngr8")
region = Rect2(5120, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_58hdl"]
atlas = ExtResource("5_bngr8")
region = Rect2(5632, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_3dk5l"]
atlas = ExtResource("5_bngr8")
region = Rect2(6144, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_pmdkx"]
atlas = ExtResource("5_bngr8")
region = Rect2(6656, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_delwj"]
atlas = ExtResource("5_bngr8")
region = Rect2(7168, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_c0hrp"]
atlas = ExtResource("5_bngr8")
region = Rect2(7680, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_nm3ps"]
atlas = ExtResource("5_bngr8")
region = Rect2(8192, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_ax7gm"]
atlas = ExtResource("5_bngr8")
region = Rect2(8704, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_xdngf"]
atlas = ExtResource("5_bngr8")
region = Rect2(9216, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_qjoth"]
atlas = ExtResource("5_bngr8")
region = Rect2(9728, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_ir6la"]
atlas = ExtResource("5_bngr8")
region = Rect2(10240, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_kvy4v"]
atlas = ExtResource("5_bngr8")
region = Rect2(10752, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_6y4ab"]
atlas = ExtResource("5_bngr8")
region = Rect2(11264, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_hhwgf"]
atlas = ExtResource("5_bngr8")
region = Rect2(11776, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_l178f"]
atlas = ExtResource("5_bngr8")
region = Rect2(12288, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_0npj3"]
atlas = ExtResource("5_bngr8")
region = Rect2(12800, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_dcc3e"]
atlas = ExtResource("5_bngr8")
region = Rect2(13312, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_iqcna"]
atlas = ExtResource("5_bngr8")
region = Rect2(13824, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_0u5oq"]
atlas = ExtResource("5_bngr8")
region = Rect2(14336, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_qninq"]
atlas = ExtResource("5_bngr8")
region = Rect2(14848, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_5vt5r"]
atlas = ExtResource("5_bngr8")
region = Rect2(15360, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_a3n34"]
atlas = ExtResource("5_bngr8")
region = Rect2(15872, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_hh1fj"]
atlas = ExtResource("5_bngr8")
region = Rect2(0, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_4ldcx"]
atlas = ExtResource("5_bngr8")
region = Rect2(512, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_07bvn"]
atlas = ExtResource("5_bngr8")
region = Rect2(1024, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_rqdqm"]
atlas = ExtResource("5_bngr8")
region = Rect2(1536, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_mjb05"]
atlas = ExtResource("5_bngr8")
region = Rect2(2048, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_r0mys"]
atlas = ExtResource("5_bngr8")
region = Rect2(2560, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_ro8ch"]
atlas = ExtResource("5_bngr8")
region = Rect2(3072, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_c5lge"]
atlas = ExtResource("5_bngr8")
region = Rect2(3584, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_o0af2"]
atlas = ExtResource("5_bngr8")
region = Rect2(4096, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_ht5qq"]
atlas = ExtResource("5_bngr8")
region = Rect2(4608, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_spm6q"]
atlas = ExtResource("5_bngr8")
region = Rect2(5120, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_baipy"]
atlas = ExtResource("5_bngr8")
region = Rect2(5632, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_i0amg"]
atlas = ExtResource("5_bngr8")
region = Rect2(6144, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_xpptc"]
atlas = ExtResource("5_bngr8")
region = Rect2(6656, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_bxeg4"]
atlas = ExtResource("5_bngr8")
region = Rect2(7168, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_xgu6y"]
atlas = ExtResource("5_bngr8")
region = Rect2(7680, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_53n88"]
atlas = ExtResource("5_bngr8")
region = Rect2(8192, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_gwmts"]
atlas = ExtResource("5_bngr8")
region = Rect2(8704, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_7wi2f"]
atlas = ExtResource("5_bngr8")
region = Rect2(9216, 512, 512, 512)
[sub_resource type="SpriteFrames" id="SpriteFrames_xbcdg"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_gx6yx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5gt6s")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_syglp")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_o81wv")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_uc14s")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_84vg4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_18gts")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_sq31b")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ucph0")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5pe5a")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_iqf1f")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_58hdl")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_3dk5l")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_pmdkx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_delwj")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_c0hrp")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_nm3ps")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ax7gm")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_xdngf")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_qjoth")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ir6la")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_kvy4v")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_6y4ab")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_hhwgf")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_l178f")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0npj3")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_dcc3e")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_iqcna")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0u5oq")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_qninq")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5vt5r")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_a3n34")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_hh1fj")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_4ldcx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_07bvn")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_rqdqm")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_mjb05")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_r0mys")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ro8ch")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_c5lge")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_o0af2")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ht5qq")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_spm6q")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_baipy")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_i0amg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_xpptc")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_bxeg4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_xgu6y")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_53n88")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_gwmts")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_7wi2f")
}],
"loop": false,
"name": &"default",
"speed": 64.0
}]
[sub_resource type="AtlasTexture" id="AtlasTexture_eu047"] [sub_resource type="AtlasTexture" id="AtlasTexture_eu047"]
atlas = ExtResource("6_ct55r") atlas = ExtResource("6_ct55r")
region = Rect2(0, 0, 512, 512) region = Rect2(0, 0, 512, 512)
@@ -1271,6 +942,442 @@ animations = [{
"speed": 32.0 "speed": 32.0
}] }]
[sub_resource type="Animation" id="Animation_j5wmh"]
resource_name = "Divinity_Recall"
length = 3.46667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SubViewportContainer/SubViewport/Divinity Recall:sprite_frames")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 3.46667),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [SubResource("SpriteFrames_xtuex"), SubResource("SpriteFrames_xtuex")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("SubViewportContainer/SubViewport/Divinity Recall:modulate")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0.0333333, 1.06667, 2.7),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("SubViewportContainer/SubViewport/ColorRect:color")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0.623529), Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 1, 1, 0.623529), Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 1, 1, 0.623529), Color(1, 1, 1, 0)]
}
[sub_resource type="AtlasTexture" id="AtlasTexture_gx6yx"]
atlas = ExtResource("5_bngr8")
region = Rect2(0, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_5gt6s"]
atlas = ExtResource("5_bngr8")
region = Rect2(512, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_syglp"]
atlas = ExtResource("5_bngr8")
region = Rect2(1024, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_o81wv"]
atlas = ExtResource("5_bngr8")
region = Rect2(1536, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_uc14s"]
atlas = ExtResource("5_bngr8")
region = Rect2(2048, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_84vg4"]
atlas = ExtResource("5_bngr8")
region = Rect2(2560, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_18gts"]
atlas = ExtResource("5_bngr8")
region = Rect2(3072, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_sq31b"]
atlas = ExtResource("5_bngr8")
region = Rect2(3584, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_ucph0"]
atlas = ExtResource("5_bngr8")
region = Rect2(4096, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_5pe5a"]
atlas = ExtResource("5_bngr8")
region = Rect2(4608, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_iqf1f"]
atlas = ExtResource("5_bngr8")
region = Rect2(5120, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_58hdl"]
atlas = ExtResource("5_bngr8")
region = Rect2(5632, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_3dk5l"]
atlas = ExtResource("5_bngr8")
region = Rect2(6144, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_pmdkx"]
atlas = ExtResource("5_bngr8")
region = Rect2(6656, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_delwj"]
atlas = ExtResource("5_bngr8")
region = Rect2(7168, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_c0hrp"]
atlas = ExtResource("5_bngr8")
region = Rect2(7680, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_nm3ps"]
atlas = ExtResource("5_bngr8")
region = Rect2(8192, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_ax7gm"]
atlas = ExtResource("5_bngr8")
region = Rect2(8704, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_xdngf"]
atlas = ExtResource("5_bngr8")
region = Rect2(9216, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_qjoth"]
atlas = ExtResource("5_bngr8")
region = Rect2(9728, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_ir6la"]
atlas = ExtResource("5_bngr8")
region = Rect2(10240, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_kvy4v"]
atlas = ExtResource("5_bngr8")
region = Rect2(10752, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_6y4ab"]
atlas = ExtResource("5_bngr8")
region = Rect2(11264, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_hhwgf"]
atlas = ExtResource("5_bngr8")
region = Rect2(11776, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_l178f"]
atlas = ExtResource("5_bngr8")
region = Rect2(12288, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_0npj3"]
atlas = ExtResource("5_bngr8")
region = Rect2(12800, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_dcc3e"]
atlas = ExtResource("5_bngr8")
region = Rect2(13312, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_iqcna"]
atlas = ExtResource("5_bngr8")
region = Rect2(13824, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_0u5oq"]
atlas = ExtResource("5_bngr8")
region = Rect2(14336, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_qninq"]
atlas = ExtResource("5_bngr8")
region = Rect2(14848, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_5vt5r"]
atlas = ExtResource("5_bngr8")
region = Rect2(15360, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_a3n34"]
atlas = ExtResource("5_bngr8")
region = Rect2(15872, 0, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_hh1fj"]
atlas = ExtResource("5_bngr8")
region = Rect2(0, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_4ldcx"]
atlas = ExtResource("5_bngr8")
region = Rect2(512, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_07bvn"]
atlas = ExtResource("5_bngr8")
region = Rect2(1024, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_rqdqm"]
atlas = ExtResource("5_bngr8")
region = Rect2(1536, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_mjb05"]
atlas = ExtResource("5_bngr8")
region = Rect2(2048, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_r0mys"]
atlas = ExtResource("5_bngr8")
region = Rect2(2560, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_ro8ch"]
atlas = ExtResource("5_bngr8")
region = Rect2(3072, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_c5lge"]
atlas = ExtResource("5_bngr8")
region = Rect2(3584, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_o0af2"]
atlas = ExtResource("5_bngr8")
region = Rect2(4096, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_ht5qq"]
atlas = ExtResource("5_bngr8")
region = Rect2(4608, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_spm6q"]
atlas = ExtResource("5_bngr8")
region = Rect2(5120, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_baipy"]
atlas = ExtResource("5_bngr8")
region = Rect2(5632, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_i0amg"]
atlas = ExtResource("5_bngr8")
region = Rect2(6144, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_xpptc"]
atlas = ExtResource("5_bngr8")
region = Rect2(6656, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_bxeg4"]
atlas = ExtResource("5_bngr8")
region = Rect2(7168, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_xgu6y"]
atlas = ExtResource("5_bngr8")
region = Rect2(7680, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_53n88"]
atlas = ExtResource("5_bngr8")
region = Rect2(8192, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_gwmts"]
atlas = ExtResource("5_bngr8")
region = Rect2(8704, 512, 512, 512)
[sub_resource type="AtlasTexture" id="AtlasTexture_7wi2f"]
atlas = ExtResource("5_bngr8")
region = Rect2(9216, 512, 512, 512)
[sub_resource type="SpriteFrames" id="SpriteFrames_xbcdg"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_gx6yx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5gt6s")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_syglp")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_o81wv")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_uc14s")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_84vg4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_18gts")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_sq31b")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ucph0")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5pe5a")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_iqf1f")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_58hdl")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_3dk5l")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_pmdkx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_delwj")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_c0hrp")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_nm3ps")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ax7gm")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_xdngf")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_qjoth")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ir6la")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_kvy4v")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_6y4ab")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_hhwgf")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_l178f")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0npj3")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_dcc3e")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_iqcna")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_0u5oq")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_qninq")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5vt5r")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_a3n34")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_hh1fj")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_4ldcx")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_07bvn")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_rqdqm")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_mjb05")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_r0mys")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ro8ch")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_c5lge")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_o0af2")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ht5qq")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_spm6q")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_baipy")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_i0amg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_xpptc")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_bxeg4")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_xgu6y")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_53n88")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_gwmts")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_7wi2f")
}],
"loop": false,
"name": &"default",
"speed": 64.0
}]
[sub_resource type="Animation" id="Animation_rxepx"]
resource_name = "GeoReactor Air"
length = 1.66667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SubViewportContainer/SubViewport/Geomantic Reactor Air:sprite_frames")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 1.66667),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [SubResource("SpriteFrames_xbcdg"), SubResource("SpriteFrames_xbcdg")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("SubViewportContainer/SubViewport/ColorRect:color")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.0333333, 0.0666667),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0.623529), Color(1, 1, 1, 0)]
}
[sub_resource type="Animation" id="Animation_27b85"]
resource_name = "GeoReactor Water"
[sub_resource type="Animation" id="Animation_jtmj1"] [sub_resource type="Animation" id="Animation_jtmj1"]
length = 0.001 length = 0.001
tracks/0/type = "value" tracks/0/type = "value"
@@ -1568,77 +1675,6 @@ tracks/1/keys = {
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1), Color(1, 1, 1, 0.48), Color(1, 1, 1, 1), Color(1, 1, 1, 0.48), Color(1, 1, 1, 0)] "values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1), Color(1, 1, 1, 0.48), Color(1, 1, 1, 1), Color(1, 1, 1, 0.48), Color(1, 1, 1, 0)]
} }
[sub_resource type="Animation" id="Animation_j5wmh"]
resource_name = "Divinity_Recall"
length = 3.46667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SubViewportContainer/SubViewport/Divinity Recall:sprite_frames")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 3.46667),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [SubResource("SpriteFrames_xtuex"), SubResource("SpriteFrames_xtuex")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("SubViewportContainer/SubViewport/Divinity Recall:modulate")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0.0333333, 1.06667, 2.7),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("SubViewportContainer/SubViewport/ColorRect:color")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0.623529), Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 1, 1, 0.623529), Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 1, 1, 0.623529), Color(1, 1, 1, 0)]
}
[sub_resource type="Animation" id="Animation_rxepx"]
resource_name = "GeoReactor Air"
length = 1.66667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SubViewportContainer/SubViewport/Geomantic Reactor Air:sprite_frames")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 1.66667),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [SubResource("SpriteFrames_xbcdg"), SubResource("SpriteFrames_xbcdg")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("SubViewportContainer/SubViewport/ColorRect:color")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.0333333, 0.0666667),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0.623529), Color(1, 1, 1, 0)]
}
[sub_resource type="Animation" id="Animation_27b85"]
resource_name = "GeoReactor Water"
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ebyyx"] [sub_resource type="AnimationLibrary" id="AnimationLibrary_ebyyx"]
_data = { _data = {
&"Divinity_Recall": SubResource("Animation_j5wmh"), &"Divinity_Recall": SubResource("Animation_j5wmh"),
@@ -12346,6 +12382,12 @@ shadow_blur = 2.038
omni_range = 6.0 omni_range = 6.0
omni_attenuation = 0.017 omni_attenuation = 0.017
[node name="CameraAnimations" type="AnimationPlayer" parent="Camera"]
unique_name_in_owner = true
libraries = {
&"": SubResource("AnimationLibrary_sifmb")
}
[node name="Minimap" type="Node3D" parent="."] [node name="Minimap" type="Node3D" parent="."]
[node name="Minimap Sprite" type="Sprite3D" parent="Minimap"] [node name="Minimap Sprite" type="Sprite3D" parent="Minimap"]
@@ -12499,7 +12541,6 @@ frame_progress = 0.0753843
[node name="ItemVFX" type="Sprite2D" parent="ScreenFX/SubViewportContainer/SubViewport"] [node name="ItemVFX" type="Sprite2D" parent="ScreenFX/SubViewportContainer/SubViewport"]
position = Vector2(6.10352e-05, 6.10352e-05) position = Vector2(6.10352e-05, 6.10352e-05)
scale = Vector2(1, 1)
[node name="Kyuuketsuki" type="AnimatedSprite2D" parent="ScreenFX/SubViewportContainer/SubViewport"] [node name="Kyuuketsuki" type="AnimatedSprite2D" parent="ScreenFX/SubViewportContainer/SubViewport"]
modulate = Color(1, 1, 1, 0.508) modulate = Color(1, 1, 1, 0.508)

View File

@@ -1,4 +1,4 @@
using Chickensoft.AutoInject; using Chickensoft.AutoInject;
using Chickensoft.Introspection; using Chickensoft.Introspection;
using Godot; using Godot;
using System.Collections.Generic; using System.Collections.Generic;
@@ -62,144 +62,144 @@ public partial class InventoryMenu : Control, IInventoryMenu
public override void _EnterTree() public override void _EnterTree()
{ {
SetProcessInput(false); SetProcessInput(false);
} }
public void OnResolved() public void OnResolved()
{ {
ItemSlots = [ItemSlot1, ItemSlot2, ItemSlot3, ItemSlot4, ItemSlot5, ItemSlot6, ItemSlot7, ItemSlot8, ItemSlot9, ItemSlot10, ItemSlot11, ItemSlot12, ItemSlot13, ItemSlot14, ItemSlot15, ItemSlot16, ItemSlot17, ItemSlot18, ItemSlot19, ItemSlot20]; ItemSlots = [ItemSlot1, ItemSlot2, ItemSlot3, ItemSlot4, ItemSlot5, ItemSlot6, ItemSlot7, ItemSlot8, ItemSlot9, ItemSlot10, ItemSlot11, ItemSlot12, ItemSlot13, ItemSlot14, ItemSlot15, ItemSlot16, ItemSlot17, ItemSlot18, ItemSlot19, ItemSlot20];
_currentlySelectedItem = ItemSlot1; _currentlySelectedItem = ItemSlot1;
foreach (var item in ItemSlots) foreach (var item in ItemSlots)
{ {
item.ItemPressed += Item_Pressed; item.ItemPressed += Item_Pressed;
item.ItemEnterFocus += Item_FocusEntered; item.ItemEnterFocus += Item_FocusEntered;
item.ItemExitFocus += Item_ItemExitFocus; item.ItemExitFocus += Item_ItemExitFocus;
} }
_player.AttackComponent.CurrentAttack.Sync += Attack_Sync; _player.AttackComponent.CurrentAttack.Sync += Attack_Sync;
_player.AttackComponent.MaximumAttack.Sync += Attack_Sync; _player.AttackComponent.MaximumAttack.Sync += Attack_Sync;
_player.DefenseComponent.CurrentDefense.Sync += Defense_Sync; _player.DefenseComponent.CurrentDefense.Sync += Defense_Sync;
_player.DefenseComponent.MaximumDefense.Sync += Defense_Sync; _player.DefenseComponent.MaximumDefense.Sync += Defense_Sync;
_player.EquipmentComponent.EquipmentChanged += EquipmentComponent_EquipmentChanged; _player.EquipmentComponent.EquipmentChanged += EquipmentComponent_EquipmentChanged;
_player.Inventory.InventoryChanged += Inventory_InventoryChanged; _player.Inventory.InventoryChanged += Inventory_InventoryChanged;
UseButton.Pressed += UseButtonPressed; UseButton.Pressed += UseButtonPressed;
ThrowButton.Pressed += ThrowButtonPressed; ThrowButton.Pressed += ThrowButtonPressed;
DropButton.Pressed += DropButtonPressed; DropButton.Pressed += DropButtonPressed;
UseButton.FocusEntered += ActionButtonFocusChanged; UseButton.FocusEntered += ActionButtonFocusChanged;
ThrowButton.FocusEntered += ActionButtonFocusChanged; ThrowButton.FocusEntered += ActionButtonFocusChanged;
DropButton.FocusEntered += ActionButtonFocusChanged; DropButton.FocusEntered += ActionButtonFocusChanged;
VisibilityChanged += InventoryMenu_VisibilityChanged; VisibilityChanged += InventoryMenu_VisibilityChanged;
} }
private void ActionButtonFocusChanged() private void ActionButtonFocusChanged()
{ {
if (!_enableMenuSound) if (!_enableMenuSound)
SfxDatabase.Instance.Play(SoundEffect.MoveUI); SfxDatabase.Instance.Play(SoundEffect.MoveUI);
} }
public override void _UnhandledInput(InputEvent @event) public override void _UnhandledInput(InputEvent @event)
{ {
if (!Visible) if (!Visible)
return; return;
if ((!Input.IsActionJustPressed(GameInputs.UiUp) && Input.IsActionPressed(GameInputs.UiUp)) || (!Input.IsActionJustPressed(GameInputs.UiDown) && Input.IsActionPressed(GameInputs.UiDown))) if ((!Input.IsActionJustPressed(GameInputs.UiUp) && Input.IsActionPressed(GameInputs.UiUp)) || (!Input.IsActionJustPressed(GameInputs.UiDown) && Input.IsActionPressed(GameInputs.UiDown)))
AcceptEvent(); AcceptEvent();
if (Input.IsActionJustPressed(GameInputs.UiCancel) && (UseButton.HasFocus() || DropButton.HasFocus() || ThrowButton.HasFocus())) if (Input.IsActionJustPressed(GameInputs.UiCancel) && (UseButton.HasFocus() || DropButton.HasFocus() || ThrowButton.HasFocus()))
{ {
SfxDatabase.Instance.Play(SoundEffect.CancelUI); SfxDatabase.Instance.Play(SoundEffect.CancelUI);
AcceptEvent(); AcceptEvent();
HideUserActionPrompt(); HideUserActionPrompt();
} }
else if (Input.IsActionJustPressed(GameInputs.UiCancel)) else if (Input.IsActionJustPressed(GameInputs.UiCancel))
{ {
SfxDatabase.Instance.Play(SoundEffect.CancelUI); SfxDatabase.Instance.Play(SoundEffect.CancelUI);
AcceptEvent(); AcceptEvent();
_gameRepo.CloseInventory(); _gameRepo.CloseInventory();
} }
if (Input.IsActionJustPressed(GameInputs.InventorySort)) if (Input.IsActionJustPressed(GameInputs.InventorySort))
{ {
var isChanged = _player.Inventory.Sort(_player.EquipmentComponent.EquippedWeapon.Value, _player.EquipmentComponent.EquippedArmor.Value, _player.EquipmentComponent.EquippedAccessory.Value); var isChanged = _player.Inventory.Sort(_player.EquipmentComponent.EquippedWeapon.Value, _player.EquipmentComponent.EquippedArmor.Value, _player.EquipmentComponent.EquippedAccessory.Value);
if (!isChanged) if (!isChanged)
return; return;
SfxDatabase.Instance.Play(SoundEffect.SortInventory); SfxDatabase.Instance.Play(SoundEffect.SortInventory);
Inventory_InventoryChanged(); Inventory_InventoryChanged();
foreach (var slot in ItemSlots) foreach (var slot in ItemSlots)
slot.SetItemStyle(); slot.SetItemStyle();
Item_ItemExitFocus(_currentlySelectedItem); Item_ItemExitFocus(_currentlySelectedItem);
_currentlySelectedItem = ItemSlot1; _currentlySelectedItem = ItemSlot1;
_currentlySelectedItem.GrabFocus(); _currentlySelectedItem.GrabFocus();
} }
} }
private void InventoryMenu_VisibilityChanged() private void InventoryMenu_VisibilityChanged()
{ {
if (Visible) if (Visible)
{ {
SfxDatabase.Instance.Play(SoundEffect.OpenInventory); SfxDatabase.Instance.Play(SoundEffect.OpenInventory);
_currentlySelectedItem.GrabFocus(); _currentlySelectedItem.GrabFocus();
_enableMenuSound = true; _enableMenuSound = true;
} }
else else
{ {
SfxDatabase.Instance.Play(SoundEffect.CancelUI); SfxDatabase.Instance.Play(SoundEffect.CancelUI);
_enableMenuSound = false; _enableMenuSound = false;
} }
} }
private void Item_ItemExitFocus(IItemSlot itemSlot) private void Item_ItemExitFocus(IItemSlot itemSlot)
{ {
ItemDescriptionTitle.Text = string.Empty; ItemDescriptionTitle.Text = string.Empty;
ItemEffectLabel.Text = string.Empty; ItemEffectLabel.Text = string.Empty;
itemSlot.IsSelected = false; itemSlot.IsSelected = false;
itemSlot.SetItemStyle(); itemSlot.SetItemStyle();
} }
private void Item_FocusEntered(IItemSlot itemSlot) private void Item_FocusEntered(IItemSlot itemSlot)
{ {
if (itemSlot.Item.Value == null) if (itemSlot.Item.Value == null)
return; return;
if (_enableMenuSound) if (_enableMenuSound)
SfxDatabase.Instance.Play(SoundEffect.MoveUI); SfxDatabase.Instance.Play(SoundEffect.MoveUI);
ItemDescriptionTitle.Text = $"{itemSlot.Item.Value.ItemName}"; ItemDescriptionTitle.Text = $"{itemSlot.Item.Value.ItemName}";
ItemEffectLabel.Text = $"{itemSlot.Item.Value.Description}"; ItemEffectLabel.Text = $"{itemSlot.Item.Value.Description}";
_currentlySelectedItem = itemSlot; _currentlySelectedItem = itemSlot;
itemSlot.IsSelected = true; itemSlot.IsSelected = true;
itemSlot.SetItemStyle(); itemSlot.SetItemStyle();
AcceptEvent(); AcceptEvent();
} }
private void Item_Pressed(InventoryItem item) => DisplayUserActionPrompt(item); private void Item_Pressed(InventoryItem item) => DisplayUserActionPrompt(item);
private async void Inventory_InventoryChanged() private async void Inventory_InventoryChanged()
{ {
foreach (var slot in ItemSlots) foreach (var slot in ItemSlots)
{ {
slot.Visible = false; slot.Visible = false;
slot.SetItemStyle(); slot.SetItemStyle();
} }
var itemsToDisplay = _player.Inventory.Items; var itemsToDisplay = _player.Inventory.Items;
for (var i = 0; i < itemsToDisplay.Count; i++) for (var i = 0; i < itemsToDisplay.Count; i++)
{ {
ItemSlots[i].Item.OnNext(itemsToDisplay[i]); ItemSlots[i].Item.OnNext(itemsToDisplay[i]);
ItemSlots[i].Visible = true; ItemSlots[i].Visible = true;
} }
if (!_player.Inventory.Items.Contains(_currentlySelectedItem.Item.Value)) if (!_player.Inventory.Items.Contains(_currentlySelectedItem.Item.Value))
{ {
_currentlySelectedItem.Item.OnNext(null); _currentlySelectedItem.Item.OnNext(null);
var elementToSelect = Mathf.Max(0, ItemSlots.IndexOf(_currentlySelectedItem) - 1); var elementToSelect = Mathf.Max(0, ItemSlots.IndexOf(_currentlySelectedItem) - 1);
_currentlySelectedItem = ItemSlots.ElementAt(elementToSelect); _currentlySelectedItem = ItemSlots.ElementAt(elementToSelect);
_currentlySelectedItem.GrabFocus(); _currentlySelectedItem.GrabFocus();
} }
} }
private void Attack_Sync(int obj) => ATKValue.Text = $"{_player.AttackComponent.CurrentAttack.Value}/{_player.AttackComponent.MaximumAttack.Value}"; private void Attack_Sync(int obj) => ATKValue.Text = $"{_player.AttackComponent.CurrentAttack.Value}/{_player.AttackComponent.MaximumAttack.Value}";
@@ -207,111 +207,125 @@ public partial class InventoryMenu : Control, IInventoryMenu
private void EquipmentComponent_EquipmentChanged(EquipableItem equipableItem) private void EquipmentComponent_EquipmentChanged(EquipableItem equipableItem)
{ {
ATKBonusLabel.Text = $"{_player.EquipmentComponent.BonusAttack:+0;-#;\\.\\.\\.}"; ATKBonusLabel.Text = $"{_player.EquipmentComponent.BonusAttack:+0;-#;\\.\\.\\.}";
DEFBonusLabel.Text = $"{_player.EquipmentComponent.BonusDefense:+0;-#;\\.\\.\\.}"; DEFBonusLabel.Text = $"{_player.EquipmentComponent.BonusDefense:+0;-#;\\.\\.\\.}";
} }
private async void UseButtonPressed() private async void UseButtonPressed()
{ {
UseButton.Disabled = true; UseButton.Disabled = true;
if (_currentlySelectedItem.Item.Value is EquipableItem equipable) if (_currentlySelectedItem.Item.Value is EquipableItem equipable)
await EquipOrUnequipItem(equipable); await EquipOrUnequipItem(equipable);
else else if (_currentlySelectedItem.Item.Value is Plastique plastique)
await _game.UseItem(_currentlySelectedItem.Item.Value); SetItem();
UseButton.Disabled = false; else
await _game.UseItem(_currentlySelectedItem.Item.Value);
UseButton.Disabled = false;
HideUserActionPrompt(); HideUserActionPrompt();
await ShowInventoryInfo(); await ShowInventoryInfo();
await ToSignal(GetTree().CreateTimer(1f), "timeout"); await ToSignal(GetTree().CreateTimer(1f), "timeout");
}
private async void SetItem()
{
_game.SetItem(_currentlySelectedItem.Item.Value);
_player.Inventory.Remove(_currentlySelectedItem.Item.Value);
HideUserActionPrompt();
await ShowInventoryInfo();
_gameRepo.CloseInventory();
} }
private async void ThrowButtonPressed() private async void ThrowButtonPressed()
{ {
_game.ThrowItem(_currentlySelectedItem.Item.Value); _game.ThrowItem(_currentlySelectedItem.Item.Value);
_player.Inventory.Remove(_currentlySelectedItem.Item.Value); _player.Inventory.Remove(_currentlySelectedItem.Item.Value);
HideUserActionPrompt(); HideUserActionPrompt();
await ShowInventoryInfo(); await ShowInventoryInfo();
_gameRepo.CloseInventory(); _gameRepo.CloseInventory();
} }
private async void DropButtonPressed() private async void DropButtonPressed()
{ {
_game.DropItem(_currentlySelectedItem.Item.Value); _game.DropItem(_currentlySelectedItem.Item.Value);
_player.Inventory.Remove(_currentlySelectedItem.Item.Value); _player.Inventory.Remove(_currentlySelectedItem.Item.Value);
HideUserActionPrompt(); HideUserActionPrompt();
await ShowInventoryInfo(); await ShowInventoryInfo();
_gameRepo.CloseInventory();
} }
private void DisplayUserActionPrompt(InventoryItem item) private void DisplayUserActionPrompt(InventoryItem item)
{ {
SfxDatabase.Instance.Play(SoundEffect.SelectUI); SfxDatabase.Instance.Play(SoundEffect.SelectUI);
ItemDescriptionTitle.Hide(); ItemDescriptionTitle.Hide();
ItemEffectLabel.Hide(); ItemEffectLabel.Hide();
UseItemPrompt.Show(); UseItemPrompt.Show();
UseButton.Show(); UseButton.Show();
ThrowButton.Show(); ThrowButton.Show();
DropButton.Show(); DropButton.Show();
if (item is EquipableItem equipable) if (item is EquipableItem equipable)
{ {
var isItemEquipped = _player.EquipmentComponent.IsItemEquipped(equipable); var isItemEquipped = _player.EquipmentComponent.IsItemEquipped(equipable);
UseButton.Text = isItemEquipped ? "Unequip" : "Equip"; UseButton.Text = isItemEquipped ? "Unequip" : "Equip";
ThrowButton.Disabled = isItemEquipped; ThrowButton.Disabled = isItemEquipped;
ThrowButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All; ThrowButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All;
DropButton.Disabled = isItemEquipped; DropButton.Disabled = isItemEquipped;
DropButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All; DropButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All;
} }
else else if (item is Plastique plastique)
{ {
UseButton.Text = "Use"; UseButton.Text = "Set";
} }
else
{
UseButton.Text = "Use";
}
UseButton.GrabFocus(); UseButton.GrabFocus();
_enableMenuSound = false; _enableMenuSound = false;
} }
private void HideUserActionPrompt() private void HideUserActionPrompt()
{ {
UseItemPrompt.Hide(); UseItemPrompt.Hide();
UseButton.Hide(); UseButton.Hide();
ThrowButton.Hide(); ThrowButton.Hide();
DropButton.Hide(); DropButton.Hide();
UseButton.ReleaseFocus(); UseButton.ReleaseFocus();
ThrowButton.ReleaseFocus(); ThrowButton.ReleaseFocus();
DropButton.ReleaseFocus(); DropButton.ReleaseFocus();
_currentlySelectedItem.GrabFocus(); _currentlySelectedItem.GrabFocus();
_enableMenuSound = true; _enableMenuSound = true;
} }
private async Task EquipOrUnequipItem(EquipableItem equipable) private async Task EquipOrUnequipItem(EquipableItem equipable)
{ {
if (_player.EquipmentComponent.IsItemEquipped(equipable)) if (_player.EquipmentComponent.IsItemEquipped(equipable))
{ {
SfxDatabase.Instance.Play(SoundEffect.Unequip); SfxDatabase.Instance.Play(SoundEffect.Unequip);
ItemEffectLabel.Text = $"{equipable.GetType().Name} unequipped."; ItemEffectLabel.Text = $"{equipable.GetType().Name} unequipped.";
_player.Unequip(equipable); _player.Unequip(equipable);
} }
else else
{ {
SfxDatabase.Instance.Play(SoundEffect.Equip); SfxDatabase.Instance.Play(SoundEffect.Equip);
var itemSlot = _currentlySelectedItem; var itemSlot = _currentlySelectedItem;
ItemEffectLabel.Text = $"{equipable.GetType().Name} equipped."; ItemEffectLabel.Text = $"{equipable.GetType().Name} equipped.";
_player.Equip(equipable); _player.Equip(equipable);
_currentlySelectedItem = itemSlot; _currentlySelectedItem = itemSlot;
} }
} }
private async Task ShowInventoryInfo() private async Task ShowInventoryInfo()
{ {
ItemDescriptionTitle.Show(); ItemDescriptionTitle.Show();
ItemEffectLabel.Show(); ItemEffectLabel.Show();
} }
private enum InventoryPageNumber private enum InventoryPageNumber
{ {
FirstPage, FirstPage,
SecondPage SecondPage
} }
} }