Compare commits
177 Commits
aa624f7784
...
item_chang
| Author | SHA1 | Date | |
|---|---|---|---|
| 34c125e6bb | |||
| 66905c9b53 | |||
|
|
a1f4a29eb3 | ||
| a6ea1b1873 | |||
|
|
47ceb2f613 | ||
| bf6b0d50c3 | |||
| c7603a163f | |||
| a20c80d922 | |||
| e14007b7f4 | |||
| b17c134c9a | |||
| fe0241ac88 | |||
| 0ab6ef1343 | |||
|
|
638946d23a | ||
|
|
b56668dcbe | ||
| d6faf8642a | |||
| 68b1455c53 | |||
| 9615e1e251 | |||
| c755485855 | |||
| d503413140 | |||
|
|
ac31c3ae65 | ||
|
|
549040c339 | ||
| c246d8d654 | |||
| b475df6f68 | |||
| 230b47061d | |||
| 8ce38c3c13 | |||
| 5451f0b31f | |||
| 92b4e8662f | |||
| 2f377d2d7a | |||
| 363ee1cd33 | |||
| 97198afe18 | |||
|
|
fdc4a6f2c1 | ||
|
|
843a100218 | ||
|
|
8001556f37 | ||
| 90d054a3c6 | |||
| aba325ff2b | |||
| bfaa324e6a | |||
| f08c69fa10 | |||
| 9d6aa6d88d | |||
| 654e368a65 | |||
| ce727b523a | |||
|
|
6a474576f0 | ||
| 8dd194a202 | |||
| 70a33d68cf | |||
| da8c4209d7 | |||
| c6fbc9f553 | |||
| 36b851254e | |||
| 147f04d2ff | |||
| 8ea881edb3 | |||
| 8a99771491 | |||
| d45bc67722 | |||
| 13ebe54474 | |||
| b9a1888bfc | |||
| 5ae556cb4b | |||
| 52dc8fb9e4 | |||
| affa5e1f79 | |||
|
|
35a625f636 | ||
|
|
d5de5f7379 | ||
| 3e6e21977e | |||
|
|
4a2d131276 | ||
|
|
d9c2ba7ed1 | ||
| 051ffbbcb1 | |||
| 9747d7d2c5 | |||
| 34dce8c5a2 | |||
| 51010c4f7d | |||
| fd96eb2dc9 | |||
| 51c8f26e50 | |||
| 4c90eb6f07 | |||
| 30f0a078a9 | |||
| 6e4a4d605c | |||
|
|
836b9eb26d | ||
|
|
cb2df83079 | ||
| 0282ef68f3 | |||
|
|
1678d79bbd | ||
|
|
20d2890b37 | ||
|
|
e85c8d51f1 | ||
|
|
3e178257aa | ||
|
|
25b6d53ec4 | ||
| a9ed8fda10 | |||
|
|
4801d7d9b3 | ||
|
|
f08817a586 | ||
|
|
4b23c2ca6f | ||
| 39b2bc631d | |||
| f346f0f529 | |||
| 4ffe04fcff | |||
| 2ef838f270 | |||
| e63a94210c | |||
| 865934399d | |||
| 2622ed4423 | |||
| 79dd6eb33a | |||
|
|
bba0bb5ecd | ||
|
|
d6b20ce4c2 | ||
|
|
60d8c55c7d | ||
| d3a3c18d13 | |||
|
|
12993bced0 | ||
|
|
8fd7a5133d | ||
|
|
97472f2a61 | ||
| 5284a7c00d | |||
|
|
92b39c1ee9 | ||
| faf3288061 | |||
| b715d6b459 | |||
| 9897acffac | |||
| aa9e14c498 | |||
| 945c5e14bb | |||
| a1f67c3d71 | |||
|
|
670f8baabf | ||
|
|
6a62d3d943 | ||
| 3fe45cb3e7 | |||
|
|
db218f26e7 | ||
|
|
eb4e901c8a | ||
| 48a00933d9 | |||
|
|
be8bbcac28 | ||
| c5cb586e4b | |||
| 1e97eb9ede | |||
|
|
0591dccc31 | ||
|
|
70f7642d0f | ||
| 7e8826f143 | |||
|
|
f13afc9fdc | ||
| 04543fcfac | |||
| 5b9de11e5a | |||
| 678916be89 | |||
|
|
f39bd8ecdb | ||
|
|
76f4adc5be | ||
|
|
95227946d1 | ||
|
|
1ee3e97f85 | ||
| 6f90a0985a | |||
| 34742d568e | |||
|
|
3c369f79f7 | ||
|
|
fe45f0bcf2 | ||
| edff41af22 | |||
| 4ee4e02a51 | |||
| 8f8cc217dc | |||
| c491ea5050 | |||
|
|
725547d388 | ||
|
|
539430d112 | ||
| 46402401b4 | |||
| ed9e611fd9 | |||
| db7a1df1f7 | |||
|
|
3e8c11d55d | ||
| 613fc3bf60 | |||
| f69e219643 | |||
|
|
0afbf38bf9 | ||
|
|
23fdf7309d | ||
| fcffdb3b35 | |||
| 7210133330 | |||
|
|
e7bae342c9 | ||
|
|
c22fde3bb5 | ||
|
|
7cb5b20293 | ||
| a5846e08dc | |||
| 7b7fc910bd | |||
| 9fc875eda5 | |||
|
|
dc3c458414 | ||
|
|
ba38c6443c | ||
| 575a565a2c | |||
| 21d8c4770d | |||
|
|
1a77695155 | ||
|
|
11cbb8c4e5 | ||
| eed50bc04e | |||
| 2d55ae9cc4 | |||
| 0b909e4e7e | |||
| 7e6dca1c29 | |||
| 720696aed0 | |||
| 286c221530 | |||
| f5360adbf1 | |||
| bc161a58b3 | |||
| f0c4e65783 | |||
| 6ec45c4805 | |||
| 44fd8c82b0 | |||
|
|
20b659681a | ||
|
|
2786c95c22 | ||
|
|
b0f6aa176e | ||
| e29bef51c5 | |||
|
|
9ed5f8600c | ||
|
|
4c5281c852 | ||
|
|
8e030aabcd | ||
| d692d5c705 | |||
|
|
9bfb410f99 | ||
|
|
18cf7e062c |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -715,3 +715,8 @@ healthchecksdb
|
|||||||
|
|
||||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
MigrationBackup/
|
MigrationBackup/
|
||||||
|
/Zennysoft.Game.Ma/src/map/dungeon/models/Area 2/Puer/A2-Puer.glb.import
|
||||||
|
/Zennysoft.Game.Ma/src/audio/AMB/amb_beach.wav.import
|
||||||
|
/Zennysoft.Game.Ma/src/audio/AMB/amb_perlin.wav.import
|
||||||
|
/Zennysoft.Game.Ma/src/audio/AMB/amb_white_noise.wav.import
|
||||||
|
/Zennysoft.Game.Ma/src/audio/AMB/amb_wind_loop_altar.wav.import
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ public interface IAppRepo : IDisposable
|
|||||||
|
|
||||||
event Action? MainMenuEntered;
|
event Action? MainMenuEntered;
|
||||||
|
|
||||||
|
event Action? DataViewerExited;
|
||||||
|
|
||||||
void SkipSplashScreen();
|
void SkipSplashScreen();
|
||||||
|
|
||||||
void OnMainMenuEntered();
|
void OnMainMenuEntered();
|
||||||
@@ -19,4 +21,6 @@ public interface IAppRepo : IDisposable
|
|||||||
void OnExitGame();
|
void OnExitGame();
|
||||||
|
|
||||||
void OnGameOver();
|
void OnGameOver();
|
||||||
|
|
||||||
|
void OnDataViewerExited();
|
||||||
}
|
}
|
||||||
|
|||||||
5
Zennysoft.Game.Abstractions/Entity/IBehavior.cs
Normal file
5
Zennysoft.Game.Abstractions/Entity/IBehavior.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
namespace Zennysoft.Game.Abstractions.Entity;
|
||||||
|
|
||||||
|
public interface IBehavior
|
||||||
|
{
|
||||||
|
}
|
||||||
11
Zennysoft.Game.Abstractions/Entity/IEntity.cs
Normal file
11
Zennysoft.Game.Abstractions/Entity/IEntity.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace Zennysoft.Game.Abstractions.Entity
|
||||||
|
{
|
||||||
|
public interface IAction
|
||||||
|
{
|
||||||
|
public Task PerformAction();
|
||||||
|
}
|
||||||
|
public interface IAction<T>
|
||||||
|
{
|
||||||
|
public Task PerformAction(T arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace Zennysoft.Game.Abstractions;
|
|
||||||
|
|
||||||
public interface IStackable
|
|
||||||
{
|
|
||||||
int Count { get; }
|
|
||||||
|
|
||||||
void SetCount(int count);
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Zennysoft.Game.Abstractions;
|
|
||||||
|
|
||||||
public interface ICanPatrol
|
|
||||||
{
|
|
||||||
public void Patrol();
|
|
||||||
}
|
|
||||||
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
public interface IHealthPack
|
public interface IHealthPack
|
||||||
{
|
{
|
||||||
public double RestoreAmount { get; }
|
public int RestoreAmount { get; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json.Serialization.Metadata;
|
||||||
using System.Text.Json.Serialization.Metadata;
|
|
||||||
|
|
||||||
namespace Zennysoft.Game.Abstractions;
|
namespace Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
public interface ISaveFileManager<T>
|
public interface ISaveFileManager
|
||||||
{
|
{
|
||||||
public Task WriteToFile(T gameData, params IJsonTypeInfoResolver?[] resolvers);
|
public Task WriteToFile<T>(T gameData, params IJsonTypeInfoResolver?[] resolvers);
|
||||||
|
|
||||||
public Task WriteToFile(T gameData, string filePath, params IJsonTypeInfoResolver?[] resolvers);
|
public Task WriteToFile<T>(T gameData, string filePath, params IJsonTypeInfoResolver?[] resolvers);
|
||||||
|
|
||||||
public Task<T?> ReadFromFile(params IJsonTypeInfoResolver?[] resolvers);
|
public Task<T?> ReadFromFile<T>(params IJsonTypeInfoResolver?[] resolvers);
|
||||||
|
|
||||||
public Task<T?> ReadFromFile(string filePath, params IJsonTypeInfoResolver?[] resolvers);
|
public Task<T?> ReadFromFile<T>(string filePath, params IJsonTypeInfoResolver?[] resolvers);
|
||||||
|
|
||||||
|
public void DeleteSaveData(string filePath);
|
||||||
|
|
||||||
|
public void DeleteSaveData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
namespace Zennysoft.Game.Implementation;
|
||||||
|
|
||||||
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
|
using Godot;
|
||||||
|
using Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
|
public partial class DimmableAudioStreamPlayer3D : AudioStreamPlayer3D, IDimmableAudioStreamPlayer
|
||||||
|
{
|
||||||
|
#region Constants
|
||||||
|
// -60 to -80 is considered inaudible for decibels.
|
||||||
|
public const float VOLUME_DB_INAUDIBLE = -80f;
|
||||||
|
public const double FADE_DURATION = 3d; // seconds
|
||||||
|
#endregion Constants
|
||||||
|
|
||||||
|
public ITween? FadeTween { get; set; }
|
||||||
|
|
||||||
|
public float InitialVolumeDb;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
InitialVolumeDb = VolumeDb;
|
||||||
|
VolumeDb = VOLUME_DB_INAUDIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FadeIn()
|
||||||
|
{
|
||||||
|
SetupFade(InitialVolumeDb, Tween.EaseType.Out);
|
||||||
|
Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FadeOut()
|
||||||
|
{
|
||||||
|
SetupFade(VOLUME_DB_INAUDIBLE, Tween.EaseType.In);
|
||||||
|
FadeTween!.TweenCallback(Callable.From(Stop));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetupFade(float volumeDb, Tween.EaseType ease)
|
||||||
|
{
|
||||||
|
FadeTween?.Kill();
|
||||||
|
|
||||||
|
FadeTween = GodotInterfaces.Adapt<ITween>(CreateTween());
|
||||||
|
|
||||||
|
FadeTween.TweenProperty(
|
||||||
|
this,
|
||||||
|
"volume_db",
|
||||||
|
volumeDb,
|
||||||
|
FADE_DURATION
|
||||||
|
).SetTrans(Tween.TransitionType.Circ).SetEase(ease);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _EnterTree() => FadeIn();
|
||||||
|
|
||||||
|
public override void _ExitTree() => FadeOut();
|
||||||
|
}
|
||||||
10
Zennysoft.Game.Godot.Implementation/Entity/IStackable.cs
Normal file
10
Zennysoft.Game.Godot.Implementation/Entity/IStackable.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using Chickensoft.Collections;
|
||||||
|
|
||||||
|
namespace Zennysoft.Game.Implementation;
|
||||||
|
|
||||||
|
public interface IStackable
|
||||||
|
{
|
||||||
|
AutoProp<int> Count { get; }
|
||||||
|
|
||||||
|
void SetCount(int count);
|
||||||
|
}
|
||||||
@@ -9,10 +9,9 @@ using Zennysoft.Game.Abstractions;
|
|||||||
|
|
||||||
namespace Zennysoft.Game.Implementation;
|
namespace Zennysoft.Game.Implementation;
|
||||||
|
|
||||||
public class SaveFileManager<T> : ISaveFileManager<T>
|
public class SaveFileManager : ISaveFileManager
|
||||||
{
|
{
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly JsonSerializerOptions _jsonOptions;
|
|
||||||
private string _defaultSaveLocation;
|
private string _defaultSaveLocation;
|
||||||
public const string DEFAULT_SAVE_FILE_NAME = "game.json";
|
public const string DEFAULT_SAVE_FILE_NAME = "game.json";
|
||||||
|
|
||||||
@@ -23,27 +22,17 @@ public class SaveFileManager<T> : ISaveFileManager<T>
|
|||||||
|
|
||||||
GodotSerialization.Setup();
|
GodotSerialization.Setup();
|
||||||
Serializer.AddConverter(new Texture2DConverter());
|
Serializer.AddConverter(new Texture2DConverter());
|
||||||
|
|
||||||
var upgradeDependencies = new Blackboard();
|
|
||||||
|
|
||||||
_jsonOptions = new JsonSerializerOptions
|
|
||||||
{
|
|
||||||
Converters = {
|
|
||||||
new SerializableTypeConverter(upgradeDependencies)
|
|
||||||
},
|
|
||||||
WriteIndented = true
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Task<T?> ReadFromFile(params IJsonTypeInfoResolver?[] resolvers)
|
public Task<T?> ReadFromFile<T>(params IJsonTypeInfoResolver?[] resolvers)
|
||||||
{
|
{
|
||||||
if (!_fileSystem.File.Exists(_defaultSaveLocation))
|
if (!_fileSystem.File.Exists(_defaultSaveLocation))
|
||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
return ReadFromFile(_defaultSaveLocation, resolvers);
|
return ReadFromFile<T>(_defaultSaveLocation, resolvers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T?> ReadFromFile(string filePath, params IJsonTypeInfoResolver?[] resolvers)
|
public async Task<T?> ReadFromFile<T>(string filePath, params IJsonTypeInfoResolver?[] resolvers)
|
||||||
{
|
{
|
||||||
if (!_fileSystem.File.Exists(filePath))
|
if (!_fileSystem.File.Exists(filePath))
|
||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
@@ -51,20 +40,42 @@ public class SaveFileManager<T> : ISaveFileManager<T>
|
|||||||
var json = await _fileSystem.File.ReadAllTextAsync(filePath);
|
var json = await _fileSystem.File.ReadAllTextAsync(filePath);
|
||||||
|
|
||||||
var resolver = new SerializableTypeResolver();
|
var resolver = new SerializableTypeResolver();
|
||||||
_jsonOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine([resolver, .. resolvers]);
|
var upgradeDependencies = new Blackboard();
|
||||||
return JsonSerializer.Deserialize<T?>(json, _jsonOptions);
|
|
||||||
|
var jsonOptions = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
Converters = {
|
||||||
|
new SerializableTypeConverter(upgradeDependencies)
|
||||||
|
},
|
||||||
|
WriteIndented = true
|
||||||
|
};
|
||||||
|
jsonOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine([resolver, .. resolvers]);
|
||||||
|
return JsonSerializer.Deserialize<T?>(json, jsonOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task WriteToFile(T gameData, params IJsonTypeInfoResolver?[] resolvers)
|
public Task WriteToFile<T>(T gameData, params IJsonTypeInfoResolver?[] resolvers)
|
||||||
{
|
{
|
||||||
return WriteToFile(gameData, _defaultSaveLocation, resolvers);
|
return WriteToFile(gameData, _defaultSaveLocation, resolvers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task WriteToFile(T gameData, string filePath, params IJsonTypeInfoResolver?[] resolvers)
|
public async Task WriteToFile<T>(T gameData, string filePath, params IJsonTypeInfoResolver?[] resolvers)
|
||||||
{
|
{
|
||||||
var resolver = new SerializableTypeResolver();
|
var resolver = new SerializableTypeResolver();
|
||||||
_jsonOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine([resolver, .. resolvers]);
|
var upgradeDependencies = new Blackboard();
|
||||||
var json = JsonSerializer.Serialize(gameData, _jsonOptions);
|
|
||||||
|
var jsonOptions = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
Converters = {
|
||||||
|
new SerializableTypeConverter(upgradeDependencies)
|
||||||
|
},
|
||||||
|
WriteIndented = true
|
||||||
|
};
|
||||||
|
jsonOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine([resolver, .. resolvers]);
|
||||||
|
var json = JsonSerializer.Serialize(gameData, jsonOptions);
|
||||||
await _fileSystem.File.WriteAllTextAsync(filePath, json);
|
await _fileSystem.File.WriteAllTextAsync(filePath, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DeleteSaveData() => DeleteSaveData(_defaultSaveLocation);
|
||||||
|
|
||||||
|
public void DeleteSaveData(string filePath) => _fileSystem.File.Delete(filePath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<PackageReference Include="Chickensoft.Serialization.Godot" Version="0.7.6" />
|
<PackageReference Include="Chickensoft.Serialization.Godot" Version="0.7.6" />
|
||||||
<PackageReference Include="System.IO.Abstractions" Version="22.0.11" />
|
<PackageReference Include="System.IO.Abstractions" Version="22.0.11" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Zennysoft.Game.Abstractions\Zennysoft.Game.Abstractions.csproj" />
|
<ProjectReference Include="..\Zennysoft.Game.Abstractions\Zennysoft.Game.Abstractions.csproj" />
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public class AppRepo : IAppRepo
|
|||||||
public event Action? MainMenuEntered;
|
public event Action? MainMenuEntered;
|
||||||
public event Action? GameEntered;
|
public event Action? GameEntered;
|
||||||
public event Action? GameExited;
|
public event Action? GameExited;
|
||||||
|
public event Action? DataViewerExited;
|
||||||
|
|
||||||
private bool _disposedValue;
|
private bool _disposedValue;
|
||||||
|
|
||||||
@@ -21,6 +22,8 @@ public class AppRepo : IAppRepo
|
|||||||
|
|
||||||
public void OnGameOver() => GameExited?.Invoke();
|
public void OnGameOver() => GameExited?.Invoke();
|
||||||
|
|
||||||
|
public void OnDataViewerExited() => DataViewerExited?.Invoke();
|
||||||
|
|
||||||
protected void Dispose(bool disposing)
|
protected void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!_disposedValue)
|
if (!_disposedValue)
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ public partial class AppLogic
|
|||||||
|
|
||||||
public readonly record struct EnemyViewerOpened;
|
public readonly record struct EnemyViewerOpened;
|
||||||
|
|
||||||
|
public readonly record struct EnemyViewerExited;
|
||||||
|
|
||||||
public readonly record struct GalleryOpened;
|
public readonly record struct GalleryOpened;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -24,6 +26,8 @@ public partial class AppLogic
|
|||||||
|
|
||||||
public readonly record struct ShowMainMenu;
|
public readonly record struct ShowMainMenu;
|
||||||
|
|
||||||
|
public readonly record struct CloseGame;
|
||||||
|
|
||||||
public readonly record struct ExitGame;
|
public readonly record struct ExitGame;
|
||||||
|
|
||||||
public readonly record struct GameOver;
|
public readonly record struct GameOver;
|
||||||
@@ -32,6 +36,8 @@ public partial class AppLogic
|
|||||||
|
|
||||||
public readonly record struct EnemyViewerOpened;
|
public readonly record struct EnemyViewerOpened;
|
||||||
|
|
||||||
|
public readonly record struct EnemyViewerExited;
|
||||||
|
|
||||||
public readonly record struct GalleryOpened;
|
public readonly record struct GalleryOpened;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public partial class AppLogic
|
|||||||
public partial record State
|
public partial record State
|
||||||
{
|
{
|
||||||
[Meta]
|
[Meta]
|
||||||
public partial record EnemyViewer : State
|
public partial record EnemyViewer : State, IGet<Input.EnemyViewerExited>
|
||||||
{
|
{
|
||||||
public EnemyViewer()
|
public EnemyViewer()
|
||||||
{
|
{
|
||||||
@@ -18,7 +18,13 @@ public partial class AppLogic
|
|||||||
{
|
{
|
||||||
Output(new Output.EnemyViewerOpened());
|
Output(new Output.EnemyViewerOpened());
|
||||||
});
|
});
|
||||||
|
this.OnExit(() =>
|
||||||
|
{
|
||||||
|
Output(new Output.EnemyViewerExited());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Transition On(in Input.EnemyViewerExited input) => To<MainMenu>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public partial class AppLogic
|
|||||||
public partial record State
|
public partial record State
|
||||||
{
|
{
|
||||||
[Meta]
|
[Meta]
|
||||||
public partial record GameStarted : State
|
public partial record GameStarted : State, IGet<Input.QuitGame>
|
||||||
{
|
{
|
||||||
public GameStarted()
|
public GameStarted()
|
||||||
{
|
{
|
||||||
@@ -26,6 +26,11 @@ public partial class AppLogic
|
|||||||
OnDetach(() => Get<IAppRepo>().GameExited -= OnGameExited);
|
OnDetach(() => Get<IAppRepo>().GameExited -= OnGameExited);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Transition On(in Input.QuitGame input)
|
||||||
|
{
|
||||||
|
Output(new Output.CloseGame());
|
||||||
|
return To<MainMenu>();
|
||||||
|
}
|
||||||
public void OnGameExited() => Input(new Input.QuitGame());
|
public void OnGameExited() => Input(new Input.QuitGame());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,15 +7,21 @@ public partial class AppLogic
|
|||||||
public partial record State
|
public partial record State
|
||||||
{
|
{
|
||||||
[Meta]
|
[Meta]
|
||||||
public partial record MainMenu : State, IGet<Input.NewGame>, IGet<Input.EnemyViewerOpened>
|
public partial record MainMenu : State, IGet<Input.NewGame>, IGet<Input.EnemyViewerOpened>, IGet<Input.QuitGame>
|
||||||
{
|
{
|
||||||
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>();
|
||||||
|
|
||||||
public Transition On(in Input.EnemyViewerOpened input) => To<EnemyViewer>();
|
public Transition On(in Input.EnemyViewerOpened input) => To<EnemyViewer>();
|
||||||
|
public Transition On(in Input.QuitGame input)
|
||||||
|
{
|
||||||
|
Output(new Output.ExitGame());
|
||||||
|
return ToSelf();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
public partial class AudioManager : Node
|
|
||||||
{
|
|
||||||
#pragma warning disable IDE0044 // Add readonly modifier
|
|
||||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
|
|
||||||
private static string _sfxPath = $"res://src/audio/sfx";
|
|
||||||
private AudioStreamPlayer _audioPlayer;
|
|
||||||
private IDictionary<SoundEffects, AudioStream> _sfxDictionary;
|
|
||||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
|
|
||||||
#pragma warning restore IDE0044 // Add readonly modifier
|
|
||||||
|
|
||||||
public override void _Ready()
|
|
||||||
{
|
|
||||||
_audioPlayer = new AudioStreamPlayer();
|
|
||||||
_sfxDictionary = new Dictionary<SoundEffects, AudioStream>();
|
|
||||||
var soundEffects = Enum.GetValues(typeof(SoundEffects));
|
|
||||||
foreach (var effect in soundEffects)
|
|
||||||
_sfxDictionary.Add((SoundEffects)effect, GD.Load<AudioStream>(_sfxPath + effect + ".ogg"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Play(SoundEffects soundEffect)
|
|
||||||
{
|
|
||||||
_sfxDictionary.TryGetValue(soundEffect, out var stream);
|
|
||||||
_audioPlayer.Stream = stream;
|
|
||||||
_audioPlayer.Play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
public enum SoundEffects
|
|
||||||
{
|
|
||||||
Cancel,
|
|
||||||
Equip,
|
|
||||||
Heal,
|
|
||||||
MenuBack,
|
|
||||||
MoveThroughOptions,
|
|
||||||
PlayerAttack,
|
|
||||||
PlayerHitWall,
|
|
||||||
Sort,
|
|
||||||
Unequip
|
|
||||||
}
|
|
||||||
@@ -3,50 +3,30 @@ using Zennysoft.Ma.Adapter.Entity;
|
|||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter
|
namespace Zennysoft.Ma.Adapter
|
||||||
{
|
{
|
||||||
public class DamageCalculator : IDamageCalculator
|
public static class DamageCalculator
|
||||||
{
|
{
|
||||||
public double CalculateDamage(double damage,
|
public static int CalculateDamage(AttackData damage, double defense, ElementalResistanceSet elementalResistanceSet)
|
||||||
ElementType elementType,
|
|
||||||
double defense,
|
|
||||||
ElementalResistanceSet elementalResistanceSet,
|
|
||||||
bool isCriticalHit = false,
|
|
||||||
bool ignoreDefense = false,
|
|
||||||
bool ignoreElementalResistance = false)
|
|
||||||
{
|
{
|
||||||
var calculatedDamage = damage;
|
var calculatedDamage = damage.BaseDamage;
|
||||||
if (!ignoreElementalResistance)
|
if (!damage.IgnoreDefense)
|
||||||
calculatedDamage = CalculateElementalResistance(calculatedDamage, elementType, elementalResistanceSet);
|
|
||||||
if (!ignoreDefense)
|
|
||||||
calculatedDamage = CalculateDefenseResistance(calculatedDamage, defense);
|
calculatedDamage = CalculateDefenseResistance(calculatedDamage, defense);
|
||||||
if (isCriticalHit)
|
if (!damage.IgnoreElementalResistance)
|
||||||
calculatedDamage *= 2;
|
calculatedDamage = CalculateElementalResistance(calculatedDamage, elementalResistanceSet.ElementalResistance[damage.ElementType]);
|
||||||
|
return Mathf.Max(1, calculatedDamage);
|
||||||
return calculatedDamage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double CalculateDefenseResistance(double incomingDamage, double defense)
|
private static int CalculateDefenseResistance(int incomingDamage, double defense)
|
||||||
{
|
{
|
||||||
return Mathf.Max(incomingDamage - defense, 0.0);
|
var result = incomingDamage - (int)(incomingDamage * (defense / 100));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double CalculateElementalResistance(
|
private static int CalculateElementalResistance(
|
||||||
double incomingDamage,
|
int incomingDamage,
|
||||||
ElementType incomingElementType,
|
double elementalResistance)
|
||||||
ElementalResistanceSet elementalResistanceSet)
|
|
||||||
{
|
{
|
||||||
var resistance = elementalResistanceSet.ElementalResistance[incomingElementType];
|
var result = incomingDamage - (int)(incomingDamage * (elementalResistance / 100));
|
||||||
return Mathf.Max(incomingDamage - (incomingDamage * resistance), 0.0);
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IDamageCalculator
|
|
||||||
{
|
|
||||||
public double CalculateDamage(double damage,
|
|
||||||
ElementType elementType,
|
|
||||||
double defense,
|
|
||||||
ElementalResistanceSet elementalResistanceSet,
|
|
||||||
bool isCriticalHit = false,
|
|
||||||
bool ignoreDefense = false,
|
|
||||||
bool ignoreElementalResistance = false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,8 @@ public enum ElementType
|
|||||||
Telluric,
|
Telluric,
|
||||||
Hydric,
|
Hydric,
|
||||||
Igneous,
|
Igneous,
|
||||||
Ferrum
|
Ferrum,
|
||||||
|
Holy,
|
||||||
|
Curse,
|
||||||
|
All
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Chickensoft.Collections;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IAttackComponent : IEntityComponent
|
||||||
|
{
|
||||||
|
public IAutoProp<int> CurrentAttack { get; }
|
||||||
|
|
||||||
|
public IAutoProp<int> MaximumAttack { get; }
|
||||||
|
|
||||||
|
public void Restore(int restoreAmount);
|
||||||
|
|
||||||
|
public void Reduce(int reduceAmount);
|
||||||
|
|
||||||
|
public void SetAttack(int attack);
|
||||||
|
|
||||||
|
public void RaiseMaximumAttack(int raiseAmount);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Chickensoft.Collections;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IDefenseComponent : IEntityComponent
|
||||||
|
{
|
||||||
|
public IAutoProp<int> CurrentDefense { get; }
|
||||||
|
|
||||||
|
public IAutoProp<int> MaximumDefense { get; }
|
||||||
|
|
||||||
|
public void Restore(int restoreAmount);
|
||||||
|
|
||||||
|
public void Reduce(int reduceAmount);
|
||||||
|
|
||||||
|
public void SetDefense(int attack);
|
||||||
|
|
||||||
|
public void RaiseMaximumDefense(int raiseAmount);
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IEntityComponent
|
||||||
|
{
|
||||||
|
public void Reset();
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using Chickensoft.Collections;
|
||||||
|
using Godot;
|
||||||
|
using Zennysoft.Ma.Adapter.Entity;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
public interface IEquipmentComponent : IEntityComponent
|
||||||
|
{
|
||||||
|
public IAutoProp<IWeapon> EquippedWeapon { get; }
|
||||||
|
|
||||||
|
public IAutoProp<IArmor> EquippedArmor { get; }
|
||||||
|
|
||||||
|
public IAutoProp<IAccessory> EquippedAccessory { get; }
|
||||||
|
|
||||||
|
public IAutoProp<IEquipableItem> EquippedAmmo { get; }
|
||||||
|
|
||||||
|
public void Equip(IEquipableItem equipable);
|
||||||
|
|
||||||
|
public void Unequip(IEquipableItem equipable);
|
||||||
|
|
||||||
|
public bool IsItemEquipped(IEquipableItem item);
|
||||||
|
|
||||||
|
public void UpdateEquipment(IEquipableItem equipable);
|
||||||
|
|
||||||
|
public bool AugmentableEquipmentExists();
|
||||||
|
|
||||||
|
public int BonusAttack { get; }
|
||||||
|
|
||||||
|
public int BonusDefense { get; }
|
||||||
|
|
||||||
|
public int BonusHP { get; }
|
||||||
|
|
||||||
|
public int BonusVT { get; }
|
||||||
|
|
||||||
|
public int BonusLuck { get; }
|
||||||
|
|
||||||
|
public ElementalResistanceSet ElementalResistance { get; }
|
||||||
|
|
||||||
|
public event Action<IEquipableItem> EquipmentChanged;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using Chickensoft.Collections;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IExperiencePointsComponent : IEntityComponent
|
||||||
|
{
|
||||||
|
public IAutoProp<int> CurrentExp { get; }
|
||||||
|
|
||||||
|
public IAutoProp<int> ExpToNextLevel { get; }
|
||||||
|
|
||||||
|
public IAutoProp<double> ExpGainRate { get; }
|
||||||
|
|
||||||
|
public IAutoProp<int> Level { get; }
|
||||||
|
|
||||||
|
public void ModifyExpGainRate(double newRate);
|
||||||
|
|
||||||
|
public void Gain(int baseExpGain);
|
||||||
|
|
||||||
|
public void GainUnmodified(int flateRateExpGain);
|
||||||
|
|
||||||
|
public void LevelUp();
|
||||||
|
|
||||||
|
public event Action PlayerLevelUp;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using Chickensoft.Collections;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IHealthComponent : IEntityComponent
|
||||||
|
{
|
||||||
|
public IAutoProp<int> CurrentHP { get; }
|
||||||
|
|
||||||
|
public IAutoProp<int> MaximumHP { get; }
|
||||||
|
|
||||||
|
public event Action? HealthReachedZero;
|
||||||
|
public event Action? DamageTaken;
|
||||||
|
|
||||||
|
public bool AtFullHealth { get; }
|
||||||
|
|
||||||
|
public void Heal(int healAmount);
|
||||||
|
|
||||||
|
public void Damage(int damageAmount);
|
||||||
|
|
||||||
|
public void SetCurrentHealth(int health);
|
||||||
|
|
||||||
|
public void SetMaximumHealth(int health);
|
||||||
|
|
||||||
|
public void RaiseMaximumHP(int raiseAmount, bool restoreHP = false);
|
||||||
|
}
|
||||||
10
Zennysoft.Game.Ma.Implementation/Components/LuckComponent.cs
Normal file
10
Zennysoft.Game.Ma.Implementation/Components/LuckComponent.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using Chickensoft.Collections;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface ILuckComponent : IEntityComponent
|
||||||
|
{
|
||||||
|
public IAutoProp<int> Luck { get; }
|
||||||
|
|
||||||
|
public void IncreaseLuck(int value);
|
||||||
|
}
|
||||||
22
Zennysoft.Game.Ma.Implementation/Components/VTComponent.cs
Normal file
22
Zennysoft.Game.Ma.Implementation/Components/VTComponent.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using Chickensoft.Collections;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IVTComponent : IEntityComponent
|
||||||
|
{
|
||||||
|
public IAutoProp<int> CurrentVT { get; }
|
||||||
|
|
||||||
|
public IAutoProp<int> MaximumVT { get; }
|
||||||
|
|
||||||
|
public bool AtFullVT { get; }
|
||||||
|
|
||||||
|
public void Restore(int restoreAmount);
|
||||||
|
|
||||||
|
public void Reduce(int reduceAmount);
|
||||||
|
|
||||||
|
public void SetVT(int vt);
|
||||||
|
|
||||||
|
public void RaiseMaximumVT(int raiseAmount, bool restoreVT = true);
|
||||||
|
|
||||||
|
public void SetMaximumVT(int vt);
|
||||||
|
}
|
||||||
3
Zennysoft.Game.Ma.Implementation/Entity/AttackData.cs
Normal file
3
Zennysoft.Game.Ma.Implementation/Entity/AttackData.cs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public record AttackData(int BaseDamage, ElementType ElementType, bool IgnoreDefense = false, bool IgnoreElementalResistance = false);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://ci7va4hsq6hyt
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://87d8kluait8y
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://c7e5g8l6wuph"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://87d8kluait8y" path="res://src/enemy/behaviors/PatrolBehavior.cs" id="1_lobva"]
|
||||||
|
|
||||||
|
[node name="NavigationAgent" type="NavigationAgent3D"]
|
||||||
|
avoidance_enabled = true
|
||||||
|
debug_enabled = true
|
||||||
|
script = ExtResource("1_lobva")
|
||||||
|
_patrolSpeed = 100.0
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
namespace Zennysoft.Ma.Adapter.Entity
|
using Chickensoft.Serialization;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter.Entity
|
||||||
{
|
{
|
||||||
public record ElementalResistanceSet
|
public record ElementalResistanceSet
|
||||||
{
|
{
|
||||||
|
[Save("elemental_resist_set")]
|
||||||
public Dictionary<ElementType, double> ElementalResistance { get; }
|
public Dictionary<ElementType, double> ElementalResistance { get; }
|
||||||
|
|
||||||
public ElementalResistanceSet(double aeolicResistance, double hydricResistance, double igneousResistance, double ferrumResistance, double telluricResistance)
|
public static ElementalResistanceSet None => new ElementalResistanceSet(0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
public ElementalResistanceSet(double aeolicResistance, double hydricResistance, double igneousResistance, double ferrumResistance, double telluricResistance, double holyResistance, double curseResistance)
|
||||||
{
|
{
|
||||||
ElementalResistance = new Dictionary<ElementType, double>
|
ElementalResistance = new Dictionary<ElementType, double>
|
||||||
{
|
{
|
||||||
@@ -14,7 +19,22 @@
|
|||||||
{ ElementType.Igneous, igneousResistance },
|
{ ElementType.Igneous, igneousResistance },
|
||||||
{ ElementType.Ferrum, ferrumResistance },
|
{ ElementType.Ferrum, ferrumResistance },
|
||||||
{ ElementType.Telluric, telluricResistance },
|
{ ElementType.Telluric, telluricResistance },
|
||||||
|
{ ElementType.Holy, holyResistance },
|
||||||
|
{ ElementType.Curse, curseResistance },
|
||||||
|
{ ElementType.All, aeolicResistance + hydricResistance + igneousResistance + ferrumResistance + telluricResistance + holyResistance + curseResistance },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ElementalResistanceSet operator +(ElementalResistanceSet left, ElementalResistanceSet right)
|
||||||
|
{
|
||||||
|
return new ElementalResistanceSet(
|
||||||
|
left.ElementalResistance[ElementType.Aeolic] + right.ElementalResistance[ElementType.Aeolic],
|
||||||
|
left.ElementalResistance[ElementType.Hydric] + right.ElementalResistance[ElementType.Hydric],
|
||||||
|
left.ElementalResistance[ElementType.Igneous] + right.ElementalResistance[ElementType.Igneous],
|
||||||
|
left.ElementalResistance[ElementType.Ferrum] + right.ElementalResistance[ElementType.Ferrum],
|
||||||
|
left.ElementalResistance[ElementType.Telluric] + right.ElementalResistance[ElementType.Telluric],
|
||||||
|
left.ElementalResistance[ElementType.Holy] + right.ElementalResistance[ElementType.Holy],
|
||||||
|
left.ElementalResistance[ElementType.Curse] + right.ElementalResistance[ElementType.Curse]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
42
Zennysoft.Game.Ma.Implementation/Entity/IEnemy.cs
Normal file
42
Zennysoft.Game.Ma.Implementation/Entity/IEnemy.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter.Entity
|
||||||
|
{
|
||||||
|
public interface IEnemy : ICharacterBody3D
|
||||||
|
{
|
||||||
|
public void Activate();
|
||||||
|
|
||||||
|
public void Idle();
|
||||||
|
|
||||||
|
public void Die();
|
||||||
|
|
||||||
|
public void PerformAction();
|
||||||
|
|
||||||
|
public void ReturnToDefaultState();
|
||||||
|
|
||||||
|
public void OnAbsorb();
|
||||||
|
|
||||||
|
public void OnMorph();
|
||||||
|
|
||||||
|
public IDungeonRoom GetCurrentRoom(ImmutableList<IDungeonRoom> dungeonRooms);
|
||||||
|
|
||||||
|
public void MoveEnemyToNewRoom(IDungeonRoom newRoom);
|
||||||
|
|
||||||
|
public IHealthComponent HealthComponent { get; }
|
||||||
|
|
||||||
|
public IAttackComponent AttackComponent { get; }
|
||||||
|
|
||||||
|
public IDefenseComponent DefenseComponent { get; }
|
||||||
|
|
||||||
|
public ElementalResistanceSet ElementalResistanceSet { get; }
|
||||||
|
|
||||||
|
public int InitialHP { get; }
|
||||||
|
|
||||||
|
public int InitialAttack { get; }
|
||||||
|
|
||||||
|
public int InitialDefense { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter.Entity
|
||||||
|
{
|
||||||
|
public interface IKnockbackable
|
||||||
|
{
|
||||||
|
void Knockback(float impulse, Vector3 direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
167
Zennysoft.Game.Ma.Implementation/Equipment/Augment.cs
Normal file
167
Zennysoft.Game.Ma.Implementation/Equipment/Augment.cs
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public class Augment
|
||||||
|
{
|
||||||
|
public JewelTags AugmentTag;
|
||||||
|
|
||||||
|
public Augment(JewelTags tag, IAugmentType augment)
|
||||||
|
{
|
||||||
|
AugmentTag = tag;
|
||||||
|
AugmentType = augment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAugmentType AugmentType { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HPRecoverySpeedAugment : IAugmentType
|
||||||
|
{
|
||||||
|
private readonly IPlayer _player;
|
||||||
|
|
||||||
|
public HPRecoverySpeedAugment(IPlayer player)
|
||||||
|
{
|
||||||
|
_player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply() => _player.HealthTimerHPRate += 2;
|
||||||
|
|
||||||
|
public void Remove() => _player.HealthTimerHPRate -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BasicAugment : IAugmentType
|
||||||
|
{
|
||||||
|
public void Apply()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HastenVTAugment : IAugmentType
|
||||||
|
{
|
||||||
|
private readonly IPlayer _player;
|
||||||
|
|
||||||
|
public HastenVTAugment(IPlayer player)
|
||||||
|
{
|
||||||
|
_player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply() => _player.ModifyHealthTimerSpeed(_player.HealthTimerSpeedModifier + 0.25f);
|
||||||
|
|
||||||
|
public void Remove() => _player.ModifyHealthTimerSpeed(_player.HealthTimerSpeedModifier - 0.25f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SlowVTReductionAugment : IAugmentType
|
||||||
|
{
|
||||||
|
private readonly IPlayer _player;
|
||||||
|
|
||||||
|
public SlowVTReductionAugment(IPlayer player)
|
||||||
|
{
|
||||||
|
_player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply() => _player.ModifyHealthTimerSpeed(_player.HealthTimerSpeedModifier - 0.25f);
|
||||||
|
|
||||||
|
public void Remove() => _player.ModifyHealthTimerSpeed(_player.HealthTimerSpeedModifier + 0.25f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IncreaseEXPRateAugment : IAugmentType
|
||||||
|
{
|
||||||
|
private readonly IPlayer _player;
|
||||||
|
|
||||||
|
public IncreaseEXPRateAugment(IPlayer player)
|
||||||
|
{
|
||||||
|
_player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply() => _player.ExperiencePointsComponent.ModifyExpGainRate(_player.ExperiencePointsComponent.ExpGainRate.Value + 0.25f);
|
||||||
|
public void Remove() => _player.ExperiencePointsComponent.ModifyExpGainRate(_player.ExperiencePointsComponent.ExpGainRate.Value - 0.25f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LowerEXPRateAugment : IAugmentType
|
||||||
|
{
|
||||||
|
private readonly IPlayer _player;
|
||||||
|
|
||||||
|
public LowerEXPRateAugment(IPlayer player)
|
||||||
|
{
|
||||||
|
_player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply() => _player.ExperiencePointsComponent.ModifyExpGainRate(_player.ExperiencePointsComponent.ExpGainRate.Value - 0.25f);
|
||||||
|
public void Remove() => _player.ExperiencePointsComponent.ModifyExpGainRate(_player.ExperiencePointsComponent.ExpGainRate.Value + 0.25f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LowerHPRecoveryAugment : IAugmentType
|
||||||
|
{
|
||||||
|
private readonly IPlayer _player;
|
||||||
|
|
||||||
|
public LowerHPRecoveryAugment(IPlayer player)
|
||||||
|
{
|
||||||
|
_player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply() => _player.HealthTimerHPRate -= 1;
|
||||||
|
public void Remove() => _player.HealthTimerHPRate += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentifyAllItemsAugment : IAugmentType
|
||||||
|
{
|
||||||
|
private readonly IPlayer _player;
|
||||||
|
|
||||||
|
public IdentifyAllItemsAugment(IPlayer player)
|
||||||
|
{
|
||||||
|
_player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply()
|
||||||
|
{
|
||||||
|
_player.AutoIdentifyItems = true;
|
||||||
|
foreach (var item in _player.Inventory.Items.ToList())
|
||||||
|
{
|
||||||
|
if (item.ItemTag == ItemTag.MysteryItem)
|
||||||
|
_player.IdentifyItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove()
|
||||||
|
{
|
||||||
|
var weaponAugment = _player.EquipmentComponent.EquippedWeapon.Value.Augment;
|
||||||
|
var armorAugment = _player.EquipmentComponent.EquippedArmor.Value.Augment;
|
||||||
|
var accessoryAugment = _player.EquipmentComponent.EquippedAccessory.Value.Augment;
|
||||||
|
var augments = new List<Augment?>() { weaponAugment, armorAugment, accessoryAugment };
|
||||||
|
if (augments.Count(x => x != null && x.AugmentTag == JewelTags.AutoIdentifyAllItems) > 1)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
_player.AutoIdentifyItems = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RevivePlayerAugment : IAugmentType
|
||||||
|
{
|
||||||
|
private readonly IPlayer _player;
|
||||||
|
|
||||||
|
public RevivePlayerAugment(IPlayer player)
|
||||||
|
{
|
||||||
|
_player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply()
|
||||||
|
{
|
||||||
|
_player.AutoRevive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove()
|
||||||
|
{
|
||||||
|
var weaponAugment = _player.EquipmentComponent.EquippedWeapon.Value.Augment;
|
||||||
|
var armorAugment = _player.EquipmentComponent.EquippedArmor.Value.Augment;
|
||||||
|
var accessoryAugment = _player.EquipmentComponent.EquippedAccessory.Value.Augment;
|
||||||
|
var augments = new List<Augment?>() { weaponAugment, armorAugment, accessoryAugment };
|
||||||
|
if (augments.Count(x => x != null && x.AugmentTag == JewelTags.ReviveUserOnce) > 1)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
_player.AutoRevive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
public interface IAugmentType
|
||||||
|
{
|
||||||
|
void Apply();
|
||||||
|
|
||||||
|
void Remove();
|
||||||
|
}
|
||||||
24
Zennysoft.Game.Ma.Implementation/Equipment/Tags/ItemTag.cs
Normal file
24
Zennysoft.Game.Ma.Implementation/Equipment/Tags/ItemTag.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public enum ItemTag
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
BreaksOnChange,
|
||||||
|
MysteryItem,
|
||||||
|
DamagesPlayer,
|
||||||
|
ContainsRestorative,
|
||||||
|
ContainsWeapon,
|
||||||
|
ContainsArmor,
|
||||||
|
ContainsBox,
|
||||||
|
RandomSpell,
|
||||||
|
ContainsAccessory,
|
||||||
|
DropTo1HPAndGainRareItem,
|
||||||
|
TradeOneRandomItem,
|
||||||
|
TradeAllRandomItems,
|
||||||
|
ContainsUnobtainedItem,
|
||||||
|
ContainsBasicItem,
|
||||||
|
RestrictUnequip,
|
||||||
|
UnequipAllItems,
|
||||||
|
EjectAllItems,
|
||||||
|
UseAllItems
|
||||||
|
}
|
||||||
21
Zennysoft.Game.Ma.Implementation/Equipment/Tags/JewelTags.cs
Normal file
21
Zennysoft.Game.Ma.Implementation/Equipment/Tags/JewelTags.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
public enum JewelTags
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
AeolicElement,
|
||||||
|
IncreaseHPRecovery,
|
||||||
|
HastenVT,
|
||||||
|
LowerEXPGain,
|
||||||
|
Glue,
|
||||||
|
ItemRescue,
|
||||||
|
HydricElement,
|
||||||
|
IgneousElement,
|
||||||
|
IncreaseEXPGain,
|
||||||
|
LowerHPRecovery,
|
||||||
|
SlowVTReduction,
|
||||||
|
AutoIdentifyAllItems,
|
||||||
|
ReviveUserOnce,
|
||||||
|
TelluricElement,
|
||||||
|
IncreaseAtkDefLuck,
|
||||||
|
IncreaseLuck
|
||||||
|
}
|
||||||
@@ -16,4 +16,9 @@ public enum UsableItemTag
|
|||||||
RaiseCurrentDefenseArmor,
|
RaiseCurrentDefenseArmor,
|
||||||
RaiseLevel,
|
RaiseLevel,
|
||||||
RandomEffect,
|
RandomEffect,
|
||||||
|
DoubleExp,
|
||||||
|
LowerTargetTo1HP,
|
||||||
|
CanChangeAffinity,
|
||||||
|
TeleportToRandomLocation,
|
||||||
|
WarpToExitIfFound
|
||||||
}
|
}
|
||||||
18
Zennysoft.Game.Ma.Implementation/Equipment/Tags/WeaponTag.cs
Normal file
18
Zennysoft.Game.Ma.Implementation/Equipment/Tags/WeaponTag.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public enum WeaponTag
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
SelfDamage,
|
||||||
|
IgnoreAffinity,
|
||||||
|
IgnoreDefense,
|
||||||
|
Knockback,
|
||||||
|
InverseHPAttackPower,
|
||||||
|
RustChanceSelfAndEnemy,
|
||||||
|
Instakill,
|
||||||
|
DegradeOnSwing,
|
||||||
|
DoubleAttack,
|
||||||
|
TripleAttack,
|
||||||
|
ElementalProjectile,
|
||||||
|
KineticProjectile
|
||||||
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using Chickensoft.Introspection;
|
|
||||||
using Chickensoft.Serialization;
|
|
||||||
using Zennysoft.Game.Ma;
|
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
[Meta, Id("game_data")]
|
|
||||||
public partial record GameData
|
|
||||||
{
|
|
||||||
[Save("player_data")]
|
|
||||||
public required PlayerData PlayerData { get; init; }
|
|
||||||
|
|
||||||
[Save("map_data")]
|
|
||||||
public required MapData MapData { get; init; }
|
|
||||||
|
|
||||||
[Save("rescued_items")]
|
|
||||||
public required RescuedItemDatabase RescuedItems { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using Chickensoft.Collections;
|
using Chickensoft.Collections;
|
||||||
using Godot;
|
using Godot;
|
||||||
using Zennysoft.Game.Abstractions;
|
using Zennysoft.Game.Abstractions;
|
||||||
|
using Zennysoft.Game.Implementation;
|
||||||
|
using Zennysoft.Ma.Adapter.Entity;
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
@@ -18,7 +20,7 @@ public interface IGameRepo : IDisposable
|
|||||||
|
|
||||||
event Action? DoubleExpTimeEnd;
|
event Action? DoubleExpTimeEnd;
|
||||||
|
|
||||||
event Action<InventoryItem>? RemoveItemFromInventoryEvent;
|
event Action<IBaseInventoryItem>? RemoveItemFromInventoryEvent;
|
||||||
|
|
||||||
event Action? PlayerAttack;
|
event Action? PlayerAttack;
|
||||||
|
|
||||||
@@ -26,11 +28,11 @@ public interface IGameRepo : IDisposable
|
|||||||
|
|
||||||
event Action? PlayerAttackedEnemy;
|
event Action? PlayerAttackedEnemy;
|
||||||
|
|
||||||
event Action<EquipableItem>? EquippedItem;
|
event Action<IEquipableItem>? EquippedItem;
|
||||||
|
|
||||||
event Action<EquipableItem>? UnequippedItem;
|
event Action<IEquipableItem>? UnequippedItem;
|
||||||
|
|
||||||
event Action<IHealthPack>? RestorativePickedUp;
|
event Action<IEnemy>? EnemyDied;
|
||||||
|
|
||||||
void Pause();
|
void Pause();
|
||||||
|
|
||||||
@@ -46,23 +48,21 @@ public interface IGameRepo : IDisposable
|
|||||||
|
|
||||||
public void AnnounceMessageInInventory(string message);
|
public void AnnounceMessageInInventory(string message);
|
||||||
|
|
||||||
public void RemoveItemFromInventory(InventoryItem item);
|
public void RemoveItemFromInventory(IBaseInventoryItem item);
|
||||||
|
|
||||||
public void OnPlayerAttack();
|
public void OnPlayerAttack();
|
||||||
|
|
||||||
public void OnPlayerAttackedWall();
|
public void OnPlayerAttackedWall();
|
||||||
|
|
||||||
public void OnPlayerAttackedEnemy();
|
|
||||||
|
|
||||||
public void OnRestorativePickedUp(IHealthPack restorative);
|
|
||||||
|
|
||||||
public void CloseInventory();
|
public void CloseInventory();
|
||||||
|
|
||||||
public void GameEnded();
|
public void GameEnded();
|
||||||
|
|
||||||
public void OnEquippedItem(EquipableItem item);
|
public void OnEquippedItem(IEquipableItem item);
|
||||||
|
|
||||||
public void OnUnequippedItem(EquipableItem item);
|
public void OnUnequippedItem(IEquipableItem item);
|
||||||
|
|
||||||
|
public void OnEnemyDied(IEnemy enemy);
|
||||||
|
|
||||||
public double ExpRate { get; }
|
public double ExpRate { get; }
|
||||||
}
|
}
|
||||||
@@ -75,13 +75,13 @@ public class GameRepo : IGameRepo
|
|||||||
public event Action<string>? AnnounceMessageInInventoryEvent;
|
public event Action<string>? AnnounceMessageInInventoryEvent;
|
||||||
public event Action<int>? DoubleExpTimeStart;
|
public event Action<int>? DoubleExpTimeStart;
|
||||||
public event Action? DoubleExpTimeEnd;
|
public event Action? DoubleExpTimeEnd;
|
||||||
public event Action<InventoryItem>? RemoveItemFromInventoryEvent;
|
public event Action<IBaseInventoryItem>? RemoveItemFromInventoryEvent;
|
||||||
public event Action? PlayerAttack;
|
public event Action? PlayerAttack;
|
||||||
public event Action? PlayerAttackedWall;
|
public event Action? PlayerAttackedWall;
|
||||||
public event Action? PlayerAttackedEnemy;
|
public event Action? PlayerAttackedEnemy;
|
||||||
public event Action<EquipableItem>? EquippedItem;
|
public event Action<IEquipableItem>? EquippedItem;
|
||||||
public event Action<EquipableItem>? UnequippedItem;
|
public event Action<IEquipableItem>? UnequippedItem;
|
||||||
public event Action<IHealthPack>? RestorativePickedUp;
|
public event Action<IEnemy>? EnemyDied;
|
||||||
public IAutoProp<bool> IsPaused => _isPaused;
|
public IAutoProp<bool> IsPaused => _isPaused;
|
||||||
private readonly AutoProp<bool> _isPaused;
|
private readonly AutoProp<bool> _isPaused;
|
||||||
|
|
||||||
@@ -111,14 +111,14 @@ public class GameRepo : IGameRepo
|
|||||||
{
|
{
|
||||||
AnnounceMessageInInventory("Experience points temporarily doubled.");
|
AnnounceMessageInInventory("Experience points temporarily doubled.");
|
||||||
DoubleExpTimeStart?.Invoke(lengthOfEffect.Seconds);
|
DoubleExpTimeStart?.Invoke(lengthOfEffect.Seconds);
|
||||||
ExpRate = 2;
|
ExpRate *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndDoubleExp()
|
public void EndDoubleExp()
|
||||||
{
|
{
|
||||||
AnnounceMessageOnMainScreen("Experience points effect wore off.");
|
AnnounceMessageOnMainScreen("Experience points effect wore off.");
|
||||||
DoubleExpTimeEnd?.Invoke();
|
DoubleExpTimeEnd?.Invoke();
|
||||||
ExpRate = 1;
|
ExpRate /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AnnounceMessageOnMainScreen(string message)
|
public void AnnounceMessageOnMainScreen(string message)
|
||||||
@@ -131,7 +131,7 @@ public class GameRepo : IGameRepo
|
|||||||
AnnounceMessageInInventoryEvent?.Invoke(message);
|
AnnounceMessageInInventoryEvent?.Invoke(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveItemFromInventory(InventoryItem item)
|
public void RemoveItemFromInventory(IBaseInventoryItem item)
|
||||||
{
|
{
|
||||||
RemoveItemFromInventoryEvent?.Invoke(item);
|
RemoveItemFromInventoryEvent?.Invoke(item);
|
||||||
}
|
}
|
||||||
@@ -146,24 +146,16 @@ public class GameRepo : IGameRepo
|
|||||||
PlayerAttackedWall?.Invoke();
|
PlayerAttackedWall?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnPlayerAttackedEnemy()
|
|
||||||
{
|
|
||||||
PlayerAttackedEnemy?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnRestorativePickedUp(IHealthPack restorative)
|
|
||||||
{
|
|
||||||
RestorativePickedUp?.Invoke(restorative);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CloseInventory()
|
public void CloseInventory()
|
||||||
{
|
{
|
||||||
CloseInventoryEvent?.Invoke();
|
CloseInventoryEvent?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnEquippedItem(EquipableItem item) => EquippedItem?.Invoke(item);
|
public void OnEquippedItem(IEquipableItem item) => EquippedItem?.Invoke(item);
|
||||||
|
|
||||||
public void OnUnequippedItem(EquipableItem item) => UnequippedItem?.Invoke(item);
|
public void OnUnequippedItem(IEquipableItem item) => UnequippedItem?.Invoke(item);
|
||||||
|
|
||||||
|
public void OnEnemyDied(IEnemy enemy) => EnemyDied?.Invoke(enemy);
|
||||||
|
|
||||||
public void GameEnded()
|
public void GameEnded()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ public partial class GameState
|
|||||||
|
|
||||||
public readonly record struct LoadGame;
|
public readonly record struct LoadGame;
|
||||||
|
|
||||||
public readonly record struct ContinueGame;
|
public readonly record struct ExitGame;
|
||||||
|
|
||||||
public readonly record struct ReturnToMainMenu;
|
|
||||||
|
|
||||||
public readonly record struct LoadNextFloor;
|
public readonly record struct LoadNextFloor;
|
||||||
|
|
||||||
public readonly record struct InventoryButtonPressed;
|
public readonly record struct InventoryButtonPressed;
|
||||||
|
|
||||||
|
public readonly record struct InteractButtonPressed;
|
||||||
|
|
||||||
public readonly record struct PauseButtonPressed;
|
public readonly record struct PauseButtonPressed;
|
||||||
|
|
||||||
public readonly record struct DebugButtonPressed;
|
public readonly record struct DebugButtonPressed;
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ public partial class GameState
|
|||||||
{
|
{
|
||||||
public readonly record struct InitializeGame;
|
public readonly record struct InitializeGame;
|
||||||
|
|
||||||
|
public readonly record struct ExitGame;
|
||||||
|
|
||||||
public readonly record struct LoadGameFromFile;
|
public readonly record struct LoadGameFromFile;
|
||||||
|
|
||||||
public readonly record struct OpenInventoryMenu;
|
public readonly record struct OpenInventoryMenu;
|
||||||
|
|||||||
@@ -16,11 +16,6 @@ public partial class GameState
|
|||||||
OnAttach(() => Get<IGameRepo>().Pause());
|
OnAttach(() => Get<IGameRepo>().Pause());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transition On(in Input.ReturnToMainMenu input)
|
|
||||||
{
|
|
||||||
return To<MainMenu>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transition On(in Input.UseTeleport input)
|
public Transition On(in Input.UseTeleport input)
|
||||||
{
|
{
|
||||||
Output(new Output.OpenFloorExitScreen());
|
Output(new Output.OpenFloorExitScreen());
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ 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 DebugMenu : State, IGet<Input.DebugButtonPressed>
|
public partial record DebugMenu : InGame, IGet<Input.DebugButtonPressed>
|
||||||
{
|
{
|
||||||
public Transition On(in Input.DebugButtonPressed input)
|
public Transition On(in Input.DebugButtonPressed input)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ 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 FloorExitScreen : State, IGet<Input.LoadNextFloor>, IGet<Input.ReturnToMainMenu>
|
public partial record FloorExitScreen : State, IGet<Input.LoadNextFloor>
|
||||||
{
|
{
|
||||||
public FloorExitScreen()
|
public FloorExitScreen()
|
||||||
{
|
{
|
||||||
@@ -20,11 +20,6 @@ public partial class GameState
|
|||||||
Output(new Output.LoadNextFloor());
|
Output(new Output.LoadNextFloor());
|
||||||
return To<InGame>();
|
return To<InGame>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transition On(in Input.ReturnToMainMenu input)
|
|
||||||
{
|
|
||||||
return To<MainMenu>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,17 +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 GameOver : State, IGet<Input.ContinueGame>, IGet<Input.ReturnToMainMenu>
|
public partial record GameOver : InGame, IGet<Input.NewGame>, IGet<Input.ExitGame>
|
||||||
{
|
{
|
||||||
public Transition On(in Input.ContinueGame input)
|
public Transition On(in Input.NewGame input)
|
||||||
{
|
{
|
||||||
Output(new Output.InitializeGame());
|
Output(new Output.InitializeGame());
|
||||||
return To<InGame>();
|
return To<InGame>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transition On(in Input.ReturnToMainMenu input)
|
public Transition On(in Input.ExitGame input)
|
||||||
{
|
{
|
||||||
return To<MainMenu>();
|
Output(new Output.ClosePauseScreen());
|
||||||
|
Output(new Output.ExitGame());
|
||||||
|
return To<State>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,15 @@ 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.InventoryButtonPressed>
|
public partial record InventoryScreen : State, IGet<Input.InteractButtonPressed>, IGet<Input.CloseInventory>
|
||||||
{
|
{
|
||||||
public Transition On(in Input.InventoryButtonPressed input)
|
public Transition On(in Input.InteractButtonPressed input)
|
||||||
|
{
|
||||||
|
Output(new Output.CloseInventoryMenu());
|
||||||
|
return To<InGame>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transition On(in Input.CloseInventory input)
|
||||||
{
|
{
|
||||||
Output(new Output.CloseInventoryMenu());
|
Output(new Output.CloseInventoryMenu());
|
||||||
return To<InGame>();
|
return To<InGame>();
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
using Chickensoft.Introspection;
|
|
||||||
using Chickensoft.LogicBlocks;
|
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
public partial class GameState
|
|
||||||
{
|
|
||||||
public partial record State
|
|
||||||
{
|
|
||||||
[Meta, LogicBlock(typeof(State), Diagram = true)]
|
|
||||||
public partial record MainMenu : State, IGet<Input.NewGame>, IGet<Input.ContinueGame>, IGet<Input.LoadGame>
|
|
||||||
{
|
|
||||||
public Transition On(in Input.NewGame input)
|
|
||||||
{
|
|
||||||
Output(new Output.InitializeGame());
|
|
||||||
return To<InGame>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transition On(in Input.ContinueGame input)
|
|
||||||
{
|
|
||||||
Output(new Output.InitializeGame());
|
|
||||||
return To<InGame>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transition On(in Input.LoadGame input)
|
|
||||||
{
|
|
||||||
Output(new Output.LoadGameFromFile());
|
|
||||||
return To<InGame>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Chickensoft.LogicBlocks;
|
using Chickensoft.LogicBlocks;
|
||||||
|
using static Zennysoft.Ma.Adapter.GameState.Output;
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
@@ -8,13 +9,20 @@ 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 PauseScreen : State, IGet<Input.PauseButtonPressed>
|
public partial record PauseScreen : State, IGet<Input.PauseButtonPressed>, IGet<Input.ExitGame>
|
||||||
{
|
{
|
||||||
public Transition On(in Input.PauseButtonPressed input)
|
public Transition On(in Input.PauseButtonPressed input)
|
||||||
{
|
{
|
||||||
Output(new Output.ClosePauseScreen());
|
Output(new Output.ClosePauseScreen());
|
||||||
return To<InGame>();
|
return To<InGame>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Transition On(in Input.ExitGame input)
|
||||||
|
{
|
||||||
|
Output(new Output.ClosePauseScreen());
|
||||||
|
Output(new Output.ExitGame());
|
||||||
|
return To<State>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
using Chickensoft.Introspection;
|
|
||||||
using Chickensoft.Serialization;
|
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
[Meta, Id("equipable_item")]
|
|
||||||
public abstract partial class EquipableItem : InventoryItem
|
|
||||||
{
|
|
||||||
[Save("equipable_item_is_equipped")]
|
|
||||||
public bool IsEquipped { get; set; }
|
|
||||||
}
|
|
||||||
5
Zennysoft.Game.Ma.Implementation/Item/IAccessory.cs
Normal file
5
Zennysoft.Game.Ma.Implementation/Item/IAccessory.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IAccessory : IEquipableItem, IAugmentableItem
|
||||||
|
{
|
||||||
|
}
|
||||||
5
Zennysoft.Game.Ma.Implementation/Item/IArmor.cs
Normal file
5
Zennysoft.Game.Ma.Implementation/Item/IArmor.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IArmor : IEquipableItem, IAugmentableItem
|
||||||
|
{
|
||||||
|
}
|
||||||
5
Zennysoft.Game.Ma.Implementation/Item/IAugmentItem.cs
Normal file
5
Zennysoft.Game.Ma.Implementation/Item/IAugmentItem.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
public interface IAugmentItem : IBaseInventoryItem
|
||||||
|
{
|
||||||
|
|
||||||
|
public IAugmentType Augment { get; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Zennysoft.Ma.Adapter
|
||||||
|
{
|
||||||
|
public interface IAugmentableItem
|
||||||
|
{
|
||||||
|
public Augment? Augment { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Zennysoft.Game.Ma.Implementation/Item/IBaseInventoryItem.cs
Normal file
15
Zennysoft.Game.Ma.Implementation/Item/IBaseInventoryItem.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
using Godot;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IBaseInventoryItem
|
||||||
|
{
|
||||||
|
public string ItemName { get; }
|
||||||
|
public string Description { get; }
|
||||||
|
public float SpawnRate { get; }
|
||||||
|
public int ThrowDamage { get; }
|
||||||
|
public float ThrowSpeed { get; }
|
||||||
|
public ItemTag ItemTag { get; }
|
||||||
|
|
||||||
|
public abstract Texture2D GetTexture();
|
||||||
|
}
|
||||||
9
Zennysoft.Game.Ma.Implementation/Item/IDroppedItem.cs
Normal file
9
Zennysoft.Game.Ma.Implementation/Item/IDroppedItem.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Zennysoft.Ma.Adapter
|
||||||
|
{
|
||||||
|
public interface IDroppedItem
|
||||||
|
{
|
||||||
|
void RescueItem();
|
||||||
|
|
||||||
|
public IBaseInventoryItem Item { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
14
Zennysoft.Game.Ma.Implementation/Item/IEquipableItem.cs
Normal file
14
Zennysoft.Game.Ma.Implementation/Item/IEquipableItem.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Zennysoft.Ma.Adapter.Entity;
|
||||||
|
|
||||||
|
public interface IEquipableItem : IBaseInventoryItem
|
||||||
|
{
|
||||||
|
public int BonusAttack { get; }
|
||||||
|
public int BonusDefense { get; }
|
||||||
|
public int BonusHP { get; }
|
||||||
|
public int BonusVT { get; }
|
||||||
|
public int BonusLuck { get; }
|
||||||
|
|
||||||
|
public bool Glued { get; set; }
|
||||||
|
|
||||||
|
public ElementalResistanceSet ElementalResistance { get; }
|
||||||
|
}
|
||||||
@@ -2,13 +2,20 @@
|
|||||||
|
|
||||||
public interface IInventory
|
public interface IInventory
|
||||||
{
|
{
|
||||||
public List<InventoryItem> Items { get; }
|
public bool PickUpItem(IBaseInventoryItem item);
|
||||||
|
|
||||||
public bool TryAdd(InventoryItem inventoryItem);
|
public List<IBaseInventoryItem> Items { get; }
|
||||||
|
|
||||||
public bool TryInsert(InventoryItem inventoryItem, int index);
|
public bool TryAdd(IBaseInventoryItem inventoryItem);
|
||||||
|
|
||||||
public void Remove(InventoryItem inventoryItem);
|
public bool TryInsert(IBaseInventoryItem inventoryItem, int index);
|
||||||
|
|
||||||
public void Sort();
|
public void Remove(IBaseInventoryItem inventoryItem);
|
||||||
|
|
||||||
|
public bool Sort(IWeapon currentWeapon, IArmor currentArmor, IAccessory currentAccessory, IEquipableItem ammo);
|
||||||
|
|
||||||
|
public bool AtCapacity();
|
||||||
|
|
||||||
|
public event Action<string> BroadcastMessage;
|
||||||
|
public event Action InventoryChanged;
|
||||||
}
|
}
|
||||||
|
|||||||
6
Zennysoft.Game.Ma.Implementation/Item/IThrownItem.cs
Normal file
6
Zennysoft.Game.Ma.Implementation/Item/IThrownItem.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IThrownItem
|
||||||
|
{
|
||||||
|
public IBaseInventoryItem ItemThatIsThrown { get; set; }
|
||||||
|
}
|
||||||
5
Zennysoft.Game.Ma.Implementation/Item/IWeapon.cs
Normal file
5
Zennysoft.Game.Ma.Implementation/Item/IWeapon.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IWeapon : IEquipableItem, IAugmentableItem
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
using Chickensoft.Introspection;
|
|
||||||
using Chickensoft.Serialization;
|
|
||||||
using Godot;
|
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
[Meta, Id("inventory_item")]
|
|
||||||
public abstract partial class InventoryItem : Node3D
|
|
||||||
{
|
|
||||||
[Save("inventory_item_id")]
|
|
||||||
public Guid ID => Guid.NewGuid();
|
|
||||||
[Save("inventory_item_name")]
|
|
||||||
public abstract string ItemName { get; }
|
|
||||||
[Save("inventory_item_description")]
|
|
||||||
public abstract string Description { get; }
|
|
||||||
[Save("inventory_item_spawn_rate")]
|
|
||||||
public abstract float SpawnRate { get; }
|
|
||||||
[Save("inventory_item_throw_damage")]
|
|
||||||
public abstract double ThrowDamage { get; }
|
|
||||||
[Save("inventory_item_throw_speed")]
|
|
||||||
public abstract float ThrowSpeed { get; }
|
|
||||||
[Save("inventory_item_tag")]
|
|
||||||
public abstract ItemTag ItemTag { get; }
|
|
||||||
|
|
||||||
public abstract Texture2D GetTexture();
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Chickensoft.Serialization;
|
using Chickensoft.Serialization;
|
||||||
using Zennysoft.Game.Abstractions;
|
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
@@ -8,10 +7,10 @@ namespace Zennysoft.Ma.Adapter;
|
|||||||
public partial class RescuedItemDatabase
|
public partial class RescuedItemDatabase
|
||||||
{
|
{
|
||||||
[Save("rescued_item_list")]
|
[Save("rescued_item_list")]
|
||||||
public List<InventoryItem> Items { get; init; }
|
public List<IBaseInventoryItem> Items { get; init; }
|
||||||
|
|
||||||
public RescuedItemDatabase()
|
public RescuedItemDatabase()
|
||||||
{
|
{
|
||||||
Items = new List<InventoryItem>();
|
Items = new List<IBaseInventoryItem>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
public enum ItemTag
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
BreaksOnChange,
|
|
||||||
MysteryItem
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
public enum ThrowableItemTag
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
DoubleExp,
|
|
||||||
LowerTargetTo1HP,
|
|
||||||
CanChangeAffinity,
|
|
||||||
TeleportToRandomLocation,
|
|
||||||
WarpToExitIfFound
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
public enum WeaponTag
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
SelfDamage,
|
|
||||||
IgnoreAffinity,
|
|
||||||
Knockback,
|
|
||||||
}
|
|
||||||
@@ -11,9 +11,6 @@ public partial class ItemTagEnumContext : JsonSerializerContext;
|
|||||||
[JsonSerializable(typeof(AccessoryTag))]
|
[JsonSerializable(typeof(AccessoryTag))]
|
||||||
public partial class AccessoryTagEnumContext : JsonSerializerContext;
|
public partial class AccessoryTagEnumContext : JsonSerializerContext;
|
||||||
|
|
||||||
[JsonSerializable(typeof(ThrowableItemTag))]
|
|
||||||
public partial class ThrowableItemTagEnumContext : JsonSerializerContext;
|
|
||||||
|
|
||||||
[JsonSerializable(typeof(UsableItemTag))]
|
[JsonSerializable(typeof(UsableItemTag))]
|
||||||
public partial class UsableItemTagEnumContext : JsonSerializerContext;
|
public partial class UsableItemTagEnumContext : JsonSerializerContext;
|
||||||
|
|
||||||
@@ -21,4 +18,4 @@ public partial class UsableItemTagEnumContext : JsonSerializerContext;
|
|||||||
public partial class BoxItemTagEnumContext : JsonSerializerContext;
|
public partial class BoxItemTagEnumContext : JsonSerializerContext;
|
||||||
|
|
||||||
[JsonSerializable(typeof(ElementType))]
|
[JsonSerializable(typeof(ElementType))]
|
||||||
public partial class ElementTypeEnumContext : JsonSerializerContext;
|
public partial class ElementTypeEnumContext : JsonSerializerContext;
|
||||||
17
Zennysoft.Game.Ma.Implementation/Map/IDungeonFloor.cs
Normal file
17
Zennysoft.Game.Ma.Implementation/Map/IDungeonFloor.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
|
namespace Zennysoft.Game.Ma;
|
||||||
|
public interface IDungeonFloor : INode3D
|
||||||
|
{
|
||||||
|
void InitializeDungeon();
|
||||||
|
|
||||||
|
public abstract (Vector3 Rotation, Vector3 Position) GetPlayerSpawnPoint();
|
||||||
|
|
||||||
|
public ImmutableList<IDungeonRoom> Rooms { get; }
|
||||||
|
|
||||||
|
public void FadeOutAudio();
|
||||||
|
|
||||||
|
public bool FloorIsLoaded { get; set; }
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using Chickensoft.GodotNodeInterfaces;
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
using Godot;
|
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using Zennysoft.Ma.Adapter.Entity;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
public interface IDungeonRoom : INode3D
|
public interface IDungeonRoom : INode3D
|
||||||
@@ -10,8 +10,8 @@ public class Module
|
|||||||
public static void Bootstrap(Container container)
|
public static void Bootstrap(Container container)
|
||||||
{
|
{
|
||||||
container.RegisterSingleton<IFileSystem, FileSystem>();
|
container.RegisterSingleton<IFileSystem, FileSystem>();
|
||||||
container.RegisterSingleton<ISaveFileManager<GameData>, SaveFileManager<GameData>>();
|
container.RegisterSingleton<ISaveFileManager, SaveFileManager>();
|
||||||
container.RegisterSingleton<IMaSaveFileManager<GameData>, MaSaveFileManager<GameData>>();
|
container.RegisterSingleton<IMaSaveFileManager, MaSaveFileManager>();
|
||||||
container.RegisterSingleton<IGameRepo, GameRepo>();
|
container.RegisterSingleton<IGameRepo, GameRepo>();
|
||||||
container.RegisterSingleton<IGameState, GameState>();
|
container.RegisterSingleton<IGameState, GameState>();
|
||||||
container.RegisterSingleton<IDimmableAudioStreamPlayer, DimmableAudioStreamPlayer>();
|
container.RegisterSingleton<IDimmableAudioStreamPlayer, DimmableAudioStreamPlayer>();
|
||||||
|
|||||||
@@ -1,64 +1,67 @@
|
|||||||
using Chickensoft.Collections;
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
using Godot;
|
using Godot;
|
||||||
using Zennysoft.Game.Abstractions;
|
using Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
public interface IPlayer : IKillable
|
public interface IPlayer : IKillable, ICharacterBody3D
|
||||||
{
|
{
|
||||||
public void InitializePlayerState();
|
public void ResetPlayerData();
|
||||||
|
|
||||||
public void Activate();
|
public void Activate();
|
||||||
|
|
||||||
public void Deactivate();
|
public void Deactivate();
|
||||||
|
|
||||||
public void Attack();
|
public void TakeDamage(AttackData damage);
|
||||||
|
|
||||||
public void TakeDamage(double damage, ElementType elementType = ElementType.None, bool isCriticalHit = false);
|
|
||||||
|
|
||||||
public void Knockback(float impulse);
|
public void Knockback(float impulse);
|
||||||
|
|
||||||
public void GainExp(double expGained);
|
|
||||||
|
|
||||||
public void LevelUp();
|
public void LevelUp();
|
||||||
|
|
||||||
public void Move(float delta);
|
public void TeleportPlayer((Vector3 Rotation, Vector3 Position) newTransform);
|
||||||
|
|
||||||
public void TeleportPlayer(Transform3D newTransform);
|
public void Equip(IEquipableItem equipable);
|
||||||
|
|
||||||
public void HealHP(int amount);
|
public void Unequip(IEquipableItem equipable);
|
||||||
|
|
||||||
public void RaiseHP(int amount);
|
public void PlayJumpScareAnimation();
|
||||||
|
|
||||||
public void HealVT(int amount);
|
public void ApplyNewAugment(IAugmentItem jewel, IAugmentableItem equipableItem);
|
||||||
|
|
||||||
public void RaiseVT(int amount);
|
public void IdentifyItem(IBaseInventoryItem unidentifiedItem);
|
||||||
|
|
||||||
public void ModifyBonusAttack(int amount);
|
|
||||||
|
|
||||||
public void ModifyBonusDefense(int amount);
|
|
||||||
|
|
||||||
public void ModifyMaximumHP(int amount);
|
|
||||||
|
|
||||||
public void ModifyMaximumVT(int amount);
|
|
||||||
|
|
||||||
public void ModifyBonusLuck(double amount);
|
|
||||||
|
|
||||||
public IInventory Inventory { get; }
|
public IInventory Inventory { get; }
|
||||||
|
|
||||||
public PlayerStats Stats { get; }
|
public IHealthComponent HealthComponent { get; }
|
||||||
|
|
||||||
public Vector3 CurrentPosition { get; }
|
public IVTComponent VTComponent { get; }
|
||||||
|
|
||||||
public Basis CurrentBasis { get; }
|
public IAttackComponent AttackComponent { get; }
|
||||||
|
|
||||||
public AutoProp<EquipableItem> EquippedWeapon { get; }
|
public IDefenseComponent DefenseComponent { get; }
|
||||||
|
|
||||||
public AutoProp<EquipableItem> EquippedArmor { get; }
|
public IExperiencePointsComponent ExperiencePointsComponent { get; }
|
||||||
|
|
||||||
public AutoProp<EquipableItem> EquippedAccessory { get; }
|
public ILuckComponent LuckComponent { get; }
|
||||||
|
|
||||||
public void Equip(EquipableItem equipable);
|
public IEquipmentComponent EquipmentComponent { get; }
|
||||||
|
|
||||||
public void Unequip(EquipableItem equipable);
|
public void SetHealthTimerStatus(bool isActive);
|
||||||
|
|
||||||
|
public void ModifyHealthTimerSpeed(float newModifier);
|
||||||
|
|
||||||
|
public bool AutoRevive { get; set; }
|
||||||
|
|
||||||
|
public int TotalAttack { get; }
|
||||||
|
public int TotalDefense { get; }
|
||||||
|
public int TotalLuck { get; }
|
||||||
|
|
||||||
|
public int HealthTimerHPRate { get; set; }
|
||||||
|
|
||||||
|
public float HealthTimerSpeedModifier { get; }
|
||||||
|
|
||||||
|
public bool AutoIdentifyItems { get; set; }
|
||||||
|
|
||||||
|
public event Action PlayerDied;
|
||||||
|
public delegate IBaseInventoryItem RerollItem(IBaseInventoryItem item);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
using Chickensoft.Introspection;
|
|
||||||
using Chickensoft.Serialization;
|
|
||||||
using Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
|
||||||
|
|
||||||
[Meta, Id("player_data")]
|
|
||||||
public partial record PlayerData
|
|
||||||
{
|
|
||||||
[Save("player_stats")]
|
|
||||||
public required PlayerStats PlayerStats { get; init; }
|
|
||||||
|
|
||||||
[Save("player_inventory")]
|
|
||||||
public required IInventory Inventory { get; init; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[Meta, Id("map_data")]
|
|
||||||
public partial record MapData
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
using Chickensoft.Collections;
|
|
||||||
using Godot;
|
|
||||||
|
|
||||||
public class PlayerStats
|
|
||||||
{
|
|
||||||
public PlayerStats(AutoProp<int> currentHP,
|
|
||||||
AutoProp<int> maximumHP,
|
|
||||||
AutoProp<int> currentVT,
|
|
||||||
AutoProp<int> maximumVT,
|
|
||||||
AutoProp<int> currentAttack,
|
|
||||||
AutoProp<int> maxAttack,
|
|
||||||
AutoProp<int> bonusAttack,
|
|
||||||
AutoProp<int> currentDefense,
|
|
||||||
AutoProp<int> maxDefense,
|
|
||||||
AutoProp<int> bonusDefense,
|
|
||||||
AutoProp<double> currentExp,
|
|
||||||
AutoProp<int> expToNextLevel,
|
|
||||||
AutoProp<int> currentLevel,
|
|
||||||
AutoProp<double> luck)
|
|
||||||
{
|
|
||||||
CurrentHP = currentHP;
|
|
||||||
MaximumHP = maximumHP;
|
|
||||||
CurrentVT = currentVT;
|
|
||||||
MaximumVT = maximumVT;
|
|
||||||
CurrentAttack = currentAttack;
|
|
||||||
MaxAttack = maxAttack;
|
|
||||||
BonusAttack = bonusAttack;
|
|
||||||
CurrentDefense = currentDefense;
|
|
||||||
MaxDefense = maxDefense;
|
|
||||||
BonusDefense = bonusDefense;
|
|
||||||
CurrentExp = currentExp;
|
|
||||||
ExpToNextLevel = expToNextLevel;
|
|
||||||
CurrentLevel = currentLevel;
|
|
||||||
Luck = luck;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AutoProp<int> CurrentHP { get; init; }
|
|
||||||
public AutoProp<int> MaximumHP { get; init; }
|
|
||||||
public AutoProp<int> CurrentVT { get; init; }
|
|
||||||
public AutoProp<int> MaximumVT { get; init; }
|
|
||||||
public AutoProp<int> CurrentAttack { get; init; }
|
|
||||||
public AutoProp<int> MaxAttack { get; init; }
|
|
||||||
public AutoProp<int> BonusAttack { get; init; }
|
|
||||||
public AutoProp<int> CurrentDefense { get; init; }
|
|
||||||
public AutoProp<int> MaxDefense { get; init; }
|
|
||||||
public AutoProp<int> BonusDefense { get; init; }
|
|
||||||
public AutoProp<double> CurrentExp { get; init; }
|
|
||||||
public AutoProp<int> ExpToNextLevel { get; init; }
|
|
||||||
public AutoProp<int> CurrentLevel { get; init; }
|
|
||||||
public AutoProp<double> Luck { get; init; }
|
|
||||||
|
|
||||||
public void SetCurrentHP(int newValue)
|
|
||||||
{
|
|
||||||
var clampedValue = Mathf.Clamp(newValue, 0, MaximumHP.Value);
|
|
||||||
CurrentHP.OnNext(clampedValue);
|
|
||||||
}
|
|
||||||
public void SetMaximumHP(int newValue)
|
|
||||||
{
|
|
||||||
MaximumHP.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetCurrentVT(int newValue)
|
|
||||||
{
|
|
||||||
var clampedValue = Mathf.Clamp(newValue, 0, MaximumVT.Value);
|
|
||||||
CurrentVT.OnNext(clampedValue);
|
|
||||||
}
|
|
||||||
public void SetMaximumVT(int newValue)
|
|
||||||
{
|
|
||||||
MaximumVT.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetCurrentExp(double newValue)
|
|
||||||
{
|
|
||||||
CurrentExp.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetCurrentLevel(int newValue)
|
|
||||||
{
|
|
||||||
CurrentLevel.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetCurrentAttack(int newValue)
|
|
||||||
{
|
|
||||||
var clampedValue = Mathf.Clamp(newValue, 0, MaxAttack.Value);
|
|
||||||
CurrentAttack.OnNext(clampedValue);
|
|
||||||
}
|
|
||||||
public void SetBonusAttack(int newValue)
|
|
||||||
{
|
|
||||||
BonusAttack.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetMaxAttack(int newValue)
|
|
||||||
{
|
|
||||||
MaxAttack.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetCurrentDefense(int newValue)
|
|
||||||
{
|
|
||||||
var clampedValue = Mathf.Clamp(newValue, 0, MaxDefense.Value);
|
|
||||||
CurrentDefense.OnNext(clampedValue);
|
|
||||||
}
|
|
||||||
public void SetBonusDefense(int newValue)
|
|
||||||
{
|
|
||||||
BonusDefense.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetMaxDefense(int newValue)
|
|
||||||
{
|
|
||||||
MaxDefense.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetExpToNextLevel(int newValue)
|
|
||||||
{
|
|
||||||
ExpToNextLevel.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetLuck(double newValue)
|
|
||||||
{
|
|
||||||
var clampedValue = Mathf.Clamp(newValue, 0, 1.0);
|
|
||||||
Luck.OnNext(clampedValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,14 +8,10 @@ public partial class PlayerLogic
|
|||||||
{
|
{
|
||||||
public readonly record struct PhysicsTick(double Delta);
|
public readonly record struct PhysicsTick(double Delta);
|
||||||
|
|
||||||
public readonly record struct Moved(Vector3 GlobalPosition, Transform3D GlobalTransform);
|
|
||||||
|
|
||||||
public readonly record struct Enable;
|
public readonly record struct Enable;
|
||||||
|
|
||||||
public readonly record struct Attack;
|
public readonly record struct Attack;
|
||||||
|
|
||||||
public readonly record struct AttackAnimationFinished;
|
|
||||||
|
|
||||||
public readonly record struct Die;
|
public readonly record struct Die;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ public interface IPlayerLogic : ILogicBlock<PlayerLogic.State>;
|
|||||||
[LogicBlock(typeof(State), Diagram = true)]
|
[LogicBlock(typeof(State), Diagram = true)]
|
||||||
public partial class PlayerLogic : LogicBlock<PlayerLogic.State>, IPlayerLogic
|
public partial class PlayerLogic : LogicBlock<PlayerLogic.State>, IPlayerLogic
|
||||||
{
|
{
|
||||||
public override Transition GetInitialState() => To<State.Idle>();
|
public override Transition GetInitialState() => To<State.Alive>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
using Chickensoft.Introspection;
|
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
public partial class PlayerLogic
|
|
||||||
{
|
|
||||||
public partial record State
|
|
||||||
{
|
|
||||||
[Meta]
|
|
||||||
public partial record Attacking : Alive, IGet<Input.AttackAnimationFinished>
|
|
||||||
{
|
|
||||||
public Transition On(in Input.AttackAnimationFinished input)
|
|
||||||
{
|
|
||||||
return To<Idle>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
using Chickensoft.Introspection;
|
|
||||||
using Godot;
|
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
public partial class PlayerLogic
|
|
||||||
{
|
|
||||||
public abstract partial record State
|
|
||||||
{
|
|
||||||
[Meta, Id("player_logic_state_alive_idle")]
|
|
||||||
public partial record Idle : Alive, IGet<Input.Attack>
|
|
||||||
{
|
|
||||||
|
|
||||||
public virtual Transition On(in Input.Attack input)
|
|
||||||
{
|
|
||||||
GD.Print("Attacking...");
|
|
||||||
Output(new Output.Animations.Attack());
|
|
||||||
return To<Attacking>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ public partial class PlayerLogic
|
|||||||
public partial record State
|
public partial record State
|
||||||
{
|
{
|
||||||
[Meta, Id("player_logic_alive")]
|
[Meta, Id("player_logic_alive")]
|
||||||
public abstract partial record Alive : State, IGet<Input.PhysicsTick>, IGet<Input.Die>
|
public partial record Alive : State, IGet<Input.PhysicsTick>, IGet<Input.Die>
|
||||||
{
|
{
|
||||||
public virtual Transition On(in Input.PhysicsTick input)
|
public virtual Transition On(in Input.PhysicsTick input)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public partial class PlayerLogic
|
|||||||
OnDetach(() => Get<IAppRepo>().GameEntered -= OnGameEntered);
|
OnDetach(() => Get<IAppRepo>().GameEntered -= OnGameEntered);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transition On(in Input.Enable input) => To<Idle>();
|
public Transition On(in Input.Enable input) => To<Alive>();
|
||||||
|
|
||||||
public void OnGameEntered() => Input(new Input.Enable());
|
public void OnGameEntered() => Input(new Input.Enable());
|
||||||
}
|
}
|
||||||
|
|||||||
14
Zennysoft.Game.Ma.Implementation/Quest/QuestData.cs
Normal file
14
Zennysoft.Game.Ma.Implementation/Quest/QuestData.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Chickensoft.Introspection;
|
||||||
|
using Chickensoft.Serialization;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
[Meta, Id("quest_data")]
|
||||||
|
public partial record QuestData
|
||||||
|
{
|
||||||
|
[Save("death_count")]
|
||||||
|
public int DeathCount { get; set; } = 0;
|
||||||
|
|
||||||
|
[Save("quest_data_1")]
|
||||||
|
public bool QuestMarker1 { get; set; } = false;
|
||||||
|
}
|
||||||
@@ -4,28 +4,28 @@ using Zennysoft.Game.Abstractions;
|
|||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
public interface IMaSaveFileManager<T>
|
public interface IMaSaveFileManager
|
||||||
{
|
{
|
||||||
Task Save(T gameData);
|
Task Save<T>(T gameData);
|
||||||
|
|
||||||
Task<T?> Load();
|
Task<T?> Load<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class MaSaveFileManager<T> : IMaSaveFileManager<T>
|
public sealed class MaSaveFileManager : IMaSaveFileManager
|
||||||
{
|
{
|
||||||
private readonly ISaveFileManager<T> _saveFileManager;
|
private readonly ISaveFileManager _saveFileManager;
|
||||||
private ImmutableList<IJsonTypeInfoResolver> _converters;
|
private ImmutableList<IJsonTypeInfoResolver> _converters;
|
||||||
|
|
||||||
public MaSaveFileManager(ISaveFileManager<T> saveFileManager)
|
public MaSaveFileManager(ISaveFileManager saveFileManager)
|
||||||
{
|
{
|
||||||
_saveFileManager = saveFileManager;
|
_saveFileManager = saveFileManager;
|
||||||
_converters = [WeaponTagEnumContext.Default, ItemTagEnumContext.Default, ElementTypeEnumContext.Default, AccessoryTagEnumContext.Default, ThrowableItemTagEnumContext.Default, UsableItemTagEnumContext.Default, BoxItemTagEnumContext.Default];
|
_converters = [WeaponTagEnumContext.Default, ItemTagEnumContext.Default, ElementTypeEnumContext.Default, AccessoryTagEnumContext.Default, UsableItemTagEnumContext.Default, BoxItemTagEnumContext.Default];
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Save(T gameData)
|
public async Task Save<T>(T gameData)
|
||||||
{
|
{
|
||||||
await _saveFileManager.WriteToFile(gameData, [.. _converters]);
|
await _saveFileManager.WriteToFile(gameData, [.. _converters]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T?> Load() => await _saveFileManager.ReadFromFile([.. _converters]);
|
public async Task<T?> Load<T>() => await _saveFileManager.ReadFromFile<T>([.. _converters]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Chickensoft.LogicBlocks;
|
using Chickensoft.LogicBlocks;
|
||||||
|
using Zennysoft.Game.Implementation;
|
||||||
|
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
@@ -37,7 +38,7 @@ public partial class InGameUILogic
|
|||||||
Output(new Output.AnnounceMessageInInventory(message));
|
Output(new Output.AnnounceMessageInInventory(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRemoveItemFromInventory(InventoryItem item) => Output(new Output.RemoveItemFromInventory(item));
|
private void OnRemoveItemFromInventory(IBaseInventoryItem item) => Output(new Output.RemoveItemFromInventory(item));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Zennysoft.Game.Ma;
|
using Zennysoft.Game.Implementation;
|
||||||
|
using Zennysoft.Game.Ma;
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
public partial class InGameUILogic
|
public partial class InGameUILogic
|
||||||
@@ -7,7 +8,7 @@ public partial class InGameUILogic
|
|||||||
{
|
{
|
||||||
public readonly record struct AnnounceMessageOnMainScreen(string Message);
|
public readonly record struct AnnounceMessageOnMainScreen(string Message);
|
||||||
public readonly record struct AnnounceMessageInInventory(string Message);
|
public readonly record struct AnnounceMessageInInventory(string Message);
|
||||||
public readonly record struct RemoveItemFromInventory(InventoryItem Item);
|
public readonly record struct RemoveItemFromInventory(IBaseInventoryItem Item);
|
||||||
public readonly record struct ShowInventory;
|
public readonly record struct ShowInventory;
|
||||||
public readonly record struct HideInventory;
|
public readonly record struct HideInventory;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,12 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Game\state\states\**" />
|
<Compile Remove="Actions\**" />
|
||||||
<Compile Remove="Map\**" />
|
<Compile Remove="Game\state\states\**" />
|
||||||
<EmbeddedResource Remove="Game\state\states\**" />
|
<EmbeddedResource Remove="Actions\**" />
|
||||||
<EmbeddedResource Remove="Map\**" />
|
<EmbeddedResource Remove="Game\state\states\**" />
|
||||||
<None Remove="Game\state\states\**" />
|
<None Remove="Actions\**" />
|
||||||
<None Remove="Map\**" />
|
<None Remove="Game\state\states\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
<Project Sdk="Godot.NET.Sdk/4.4.0">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
|
||||||
<!-- Use NativeAOT. -->
|
|
||||||
<PublishAot>true</PublishAot>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Remove="src\items\weapons\models\**" />
|
|
||||||
<EmbeddedResource Remove="src\items\weapons\models\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<!-- Root the assemblies to avoid trimming. -->
|
|
||||||
<TrimmerRootAssembly Include="GodotSharp" />
|
|
||||||
<TrimmerRootAssembly Include="$(TargetName)" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Chickensoft.AutoInject" Version="2.5.0" />
|
|
||||||
<PackageReference Include="Chickensoft.GodotNodeInterfaces" Version="2.4.0" />
|
|
||||||
<PackageReference Include="Chickensoft.Introspection" Version="2.2.0" />
|
|
||||||
<PackageReference Include="Chickensoft.Introspection.Generator" Version="2.2.0" />
|
|
||||||
<PackageReference Include="Chickensoft.LogicBlocks" Version="5.16.0" />
|
|
||||||
<PackageReference Include="Chickensoft.LogicBlocks.DiagramGenerator" Version="5.16.0" />
|
|
||||||
<PackageReference Include="Chickensoft.SaveFileBuilder" Version="1.1.0" />
|
|
||||||
<PackageReference Include="Chickensoft.Serialization.Godot" Version="0.7.6" />
|
|
||||||
<PackageReference Include="GodotSharp.SourceGenerators" Version="2.6.0-250131-2115.Release" />
|
|
||||||
<PackageReference Include="SimpleInjector" Version="5.5.0" />
|
|
||||||
<PackageReference Include="SSH.NET" Version="2024.2.0" />
|
|
||||||
<PackageReference Include="System.IO.Abstractions" Version="22.0.11" />
|
|
||||||
<PackageReference Include="Zeroconf" Version="3.7.16" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="src\ui\dialogue\" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include=".editorconfig" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Zennysoft.Game.Godot.Implementation\Zennysoft.Game.Implementation.csproj" />
|
|
||||||
<ProjectReference Include="..\Zennysoft.Game.Ma.Implementation\Zennysoft.Ma.Adapter.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Update="Godot.SourceGenerators" Version="4.4.0-dev.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Update="GodotSharp" Version="4.4.0-dev.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Update="GodotSharpEditor" Version="4.4.0-dev.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
using Godot.Collections;
|
|
||||||
using System.Linq;
|
|
||||||
using Zennysoft.Game.Ma;
|
|
||||||
|
|
||||||
[Tool]
|
|
||||||
public partial class DungeonFloorLayout : LayoutType
|
|
||||||
{
|
|
||||||
[Export]
|
|
||||||
public DungeonFloorSetType SetType
|
|
||||||
{
|
|
||||||
get => _setType;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_setType = value;
|
|
||||||
LayoutWithSpawnRate = [];
|
|
||||||
NotifyPropertyListChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ExportToolButton("Populate Map Data")]
|
|
||||||
public Callable PopulateMapList => Callable.From(() => PopulateDictionary(SetType));
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public Dictionary<string, float> LayoutWithSpawnRate { get; private set; }
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public Dictionary<EnemyType, float> EnemySpawnRates { get; set; } = default!;
|
|
||||||
|
|
||||||
private string _floorPath = "res://src/map/dungeon/floors/";
|
|
||||||
private DungeonFloorSetType _setType;
|
|
||||||
|
|
||||||
private void PopulateDictionary(DungeonFloorSetType setType)
|
|
||||||
{
|
|
||||||
var floorPath = _floorPath;
|
|
||||||
var floorType = string.Empty;
|
|
||||||
if (setType == DungeonFloorSetType.SetA)
|
|
||||||
floorType = "SetAFloors";
|
|
||||||
else if (setType == DungeonFloorSetType.SetB)
|
|
||||||
floorType = "SetBFloors";
|
|
||||||
|
|
||||||
var pathToScenes = $"{floorPath}/{floorType}";
|
|
||||||
|
|
||||||
var files = DirAccess.GetFilesAt(pathToScenes).Where(x => x.EndsWith(".tscn"));
|
|
||||||
|
|
||||||
var newMaps = new Dictionary<string, float>();
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
|
||||||
if (LayoutWithSpawnRate.ContainsKey($"{floorType}/{file}"))
|
|
||||||
{
|
|
||||||
var spawnRate = LayoutWithSpawnRate.TryGetValue($"{floorType}/{file}", out var currentSpawnRate);
|
|
||||||
newMaps.Add($"{floorType}/{file}", currentSpawnRate);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
newMaps.Add($"{floorType}/{file}", 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
LayoutWithSpawnRate = newMaps;
|
|
||||||
|
|
||||||
NotifyPropertyListChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum DungeonFloorSetType
|
|
||||||
{
|
|
||||||
SetA,
|
|
||||||
SetB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://ci7o3nn4mdo8o
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#if TOOLS
|
|
||||||
using Godot;
|
|
||||||
using Zennysoft.Game.Ma;
|
|
||||||
|
|
||||||
[Tool]
|
|
||||||
public partial class DungeonFloorLayoutNode : EditorPlugin
|
|
||||||
{
|
|
||||||
public override void _EnterTree()
|
|
||||||
{
|
|
||||||
// Initialization of the plugin goes here.
|
|
||||||
var script = GD.Load<Script>("res://addons/dungeon_floor_layout/DungeonFloorLayout.cs");
|
|
||||||
var texture = GD.Load<Texture2D>("res://addons/dungeon_floor_layout/icon.png");
|
|
||||||
AddCustomType(nameof(DungeonFloorLayout), nameof(LayoutType), script, texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _ExitTree()
|
|
||||||
{
|
|
||||||
// Clean-up of the plugin goes here.
|
|
||||||
RemoveCustomType(nameof(DungeonFloorLayout));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://f87ejxatyy2n
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 161 B |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user