Compare commits
169 Commits
b0f6aa176e
...
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 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -715,3 +715,8 @@ healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
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? DataViewerExited;
|
||||
|
||||
void SkipSplashScreen();
|
||||
|
||||
void OnMainMenuEntered();
|
||||
@@ -19,4 +21,6 @@ public interface IAppRepo : IDisposable
|
||||
void OnExitGame();
|
||||
|
||||
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 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;
|
||||
|
||||
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;
|
||||
|
||||
public class SaveFileManager<T> : ISaveFileManager<T>
|
||||
public class SaveFileManager : ISaveFileManager
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly JsonSerializerOptions _jsonOptions;
|
||||
private string _defaultSaveLocation;
|
||||
public const string DEFAULT_SAVE_FILE_NAME = "game.json";
|
||||
|
||||
@@ -23,27 +22,17 @@ public class SaveFileManager<T> : ISaveFileManager<T>
|
||||
|
||||
GodotSerialization.Setup();
|
||||
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))
|
||||
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))
|
||||
throw new FileNotFoundException();
|
||||
@@ -51,20 +40,42 @@ public class SaveFileManager<T> : ISaveFileManager<T>
|
||||
var json = await _fileSystem.File.ReadAllTextAsync(filePath);
|
||||
|
||||
var resolver = new SerializableTypeResolver();
|
||||
_jsonOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine([resolver, .. resolvers]);
|
||||
return JsonSerializer.Deserialize<T?>(json, _jsonOptions);
|
||||
var upgradeDependencies = new Blackboard();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
_jsonOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine([resolver, .. resolvers]);
|
||||
var json = JsonSerializer.Serialize(gameData, _jsonOptions);
|
||||
var upgradeDependencies = new Blackboard();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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="System.IO.Abstractions" Version="22.0.11" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Zennysoft.Game.Abstractions\Zennysoft.Game.Abstractions.csproj" />
|
||||
|
||||
@@ -8,6 +8,7 @@ public class AppRepo : IAppRepo
|
||||
public event Action? MainMenuEntered;
|
||||
public event Action? GameEntered;
|
||||
public event Action? GameExited;
|
||||
public event Action? DataViewerExited;
|
||||
|
||||
private bool _disposedValue;
|
||||
|
||||
@@ -21,6 +22,8 @@ public class AppRepo : IAppRepo
|
||||
|
||||
public void OnGameOver() => GameExited?.Invoke();
|
||||
|
||||
public void OnDataViewerExited() => DataViewerExited?.Invoke();
|
||||
|
||||
protected void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposedValue)
|
||||
|
||||
@@ -24,6 +24,8 @@ public partial class AppLogic
|
||||
|
||||
public readonly record struct EnemyViewerOpened;
|
||||
|
||||
public readonly record struct EnemyViewerExited;
|
||||
|
||||
public readonly record struct GalleryOpened;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ public partial class AppLogic
|
||||
{
|
||||
public static class Output
|
||||
{
|
||||
public readonly record struct Initialize;
|
||||
|
||||
public readonly record struct FadeToBlack;
|
||||
|
||||
public readonly record struct ShowSplashScreen;
|
||||
@@ -24,6 +26,8 @@ public partial class AppLogic
|
||||
|
||||
public readonly record struct ShowMainMenu;
|
||||
|
||||
public readonly record struct CloseGame;
|
||||
|
||||
public readonly record struct ExitGame;
|
||||
|
||||
public readonly record struct GameOver;
|
||||
@@ -32,6 +36,8 @@ public partial class AppLogic
|
||||
|
||||
public readonly record struct EnemyViewerOpened;
|
||||
|
||||
public readonly record struct EnemyViewerExited;
|
||||
|
||||
public readonly record struct GalleryOpened;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@ public interface IAppLogic : ILogicBlock<AppLogic.State>;
|
||||
[LogicBlock(typeof(State), Diagram = true)]
|
||||
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
|
||||
{
|
||||
[Meta]
|
||||
public partial record EnemyViewer : State
|
||||
public partial record EnemyViewer : State, IGet<Input.EnemyViewerExited>
|
||||
{
|
||||
public EnemyViewer()
|
||||
{
|
||||
@@ -18,7 +18,13 @@ public partial class AppLogic
|
||||
{
|
||||
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
|
||||
{
|
||||
[Meta]
|
||||
public partial record GameStarted : State
|
||||
public partial record GameStarted : State, IGet<Input.QuitGame>
|
||||
{
|
||||
public GameStarted()
|
||||
{
|
||||
@@ -26,6 +26,11 @@ public partial class AppLogic
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
[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()
|
||||
{
|
||||
OnAttach(() => Output(new Output.ShowMainMenu()));
|
||||
}
|
||||
|
||||
public Transition On(in Input.NewGame input) => To<GameStarted>();
|
||||
|
||||
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()));
|
||||
|
||||
OnAttach(
|
||||
() => Get<IAppRepo>().SplashScreenSkipped += OnSplashScreenSkipped
|
||||
);
|
||||
() =>
|
||||
{
|
||||
Get<IAppRepo>().SplashScreenSkipped += OnSplashScreenSkipped;
|
||||
});
|
||||
|
||||
OnDetach(
|
||||
() => 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() =>
|
||||
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
|
||||
{
|
||||
public class DamageCalculator : IDamageCalculator
|
||||
public static class DamageCalculator
|
||||
{
|
||||
public double CalculateDamage(double damage,
|
||||
ElementType elementType,
|
||||
double defense,
|
||||
ElementalResistanceSet elementalResistanceSet,
|
||||
bool isCriticalHit = false,
|
||||
bool ignoreDefense = false,
|
||||
bool ignoreElementalResistance = false)
|
||||
public static int CalculateDamage(AttackData damage, double defense, ElementalResistanceSet elementalResistanceSet)
|
||||
{
|
||||
var calculatedDamage = damage;
|
||||
if (!ignoreElementalResistance)
|
||||
calculatedDamage = CalculateElementalResistance(calculatedDamage, elementType, elementalResistanceSet);
|
||||
if (!ignoreDefense)
|
||||
var calculatedDamage = damage.BaseDamage;
|
||||
if (!damage.IgnoreDefense)
|
||||
calculatedDamage = CalculateDefenseResistance(calculatedDamage, defense);
|
||||
if (isCriticalHit)
|
||||
calculatedDamage *= 2;
|
||||
|
||||
return calculatedDamage;
|
||||
if (!damage.IgnoreElementalResistance)
|
||||
calculatedDamage = CalculateElementalResistance(calculatedDamage, elementalResistanceSet.ElementalResistance[damage.ElementType]);
|
||||
return Mathf.Max(1, 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(
|
||||
double incomingDamage,
|
||||
ElementType incomingElementType,
|
||||
ElementalResistanceSet elementalResistanceSet)
|
||||
private static int CalculateElementalResistance(
|
||||
int incomingDamage,
|
||||
double elementalResistance)
|
||||
{
|
||||
var resistance = elementalResistanceSet.ElementalResistance[incomingElementType];
|
||||
return Mathf.Max(incomingDamage - (incomingDamage * resistance), 0.0);
|
||||
var result = incomingDamage - (int)(incomingDamage * (elementalResistance / 100));
|
||||
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,
|
||||
Hydric,
|
||||
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
|
||||
{
|
||||
[Save("elemental_resist_set")]
|
||||
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>
|
||||
{
|
||||
@@ -14,7 +19,22 @@
|
||||
{ ElementType.Igneous, igneousResistance },
|
||||
{ ElementType.Ferrum, ferrumResistance },
|
||||
{ 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,
|
||||
RaiseLevel,
|
||||
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 Godot;
|
||||
using Zennysoft.Game.Abstractions;
|
||||
using Zennysoft.Game.Implementation;
|
||||
using Zennysoft.Ma.Adapter.Entity;
|
||||
|
||||
namespace Zennysoft.Ma.Adapter;
|
||||
|
||||
@@ -18,7 +20,7 @@ public interface IGameRepo : IDisposable
|
||||
|
||||
event Action? DoubleExpTimeEnd;
|
||||
|
||||
event Action<InventoryItem>? RemoveItemFromInventoryEvent;
|
||||
event Action<IBaseInventoryItem>? RemoveItemFromInventoryEvent;
|
||||
|
||||
event Action? PlayerAttack;
|
||||
|
||||
@@ -26,11 +28,11 @@ public interface IGameRepo : IDisposable
|
||||
|
||||
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();
|
||||
|
||||
@@ -46,23 +48,21 @@ public interface IGameRepo : IDisposable
|
||||
|
||||
public void AnnounceMessageInInventory(string message);
|
||||
|
||||
public void RemoveItemFromInventory(InventoryItem item);
|
||||
public void RemoveItemFromInventory(IBaseInventoryItem item);
|
||||
|
||||
public void OnPlayerAttack();
|
||||
|
||||
public void OnPlayerAttackedWall();
|
||||
|
||||
public void OnPlayerAttackedEnemy();
|
||||
|
||||
public void OnRestorativePickedUp(IHealthPack restorative);
|
||||
|
||||
public void CloseInventory();
|
||||
|
||||
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; }
|
||||
}
|
||||
@@ -75,13 +75,13 @@ public class GameRepo : IGameRepo
|
||||
public event Action<string>? AnnounceMessageInInventoryEvent;
|
||||
public event Action<int>? DoubleExpTimeStart;
|
||||
public event Action? DoubleExpTimeEnd;
|
||||
public event Action<InventoryItem>? RemoveItemFromInventoryEvent;
|
||||
public event Action<IBaseInventoryItem>? RemoveItemFromInventoryEvent;
|
||||
public event Action? PlayerAttack;
|
||||
public event Action? PlayerAttackedWall;
|
||||
public event Action? PlayerAttackedEnemy;
|
||||
public event Action<EquipableItem>? EquippedItem;
|
||||
public event Action<EquipableItem>? UnequippedItem;
|
||||
public event Action<IHealthPack>? RestorativePickedUp;
|
||||
public event Action<IEquipableItem>? EquippedItem;
|
||||
public event Action<IEquipableItem>? UnequippedItem;
|
||||
public event Action<IEnemy>? EnemyDied;
|
||||
public IAutoProp<bool> IsPaused => _isPaused;
|
||||
private readonly AutoProp<bool> _isPaused;
|
||||
|
||||
@@ -111,14 +111,14 @@ public class GameRepo : IGameRepo
|
||||
{
|
||||
AnnounceMessageInInventory("Experience points temporarily doubled.");
|
||||
DoubleExpTimeStart?.Invoke(lengthOfEffect.Seconds);
|
||||
ExpRate = 2;
|
||||
ExpRate *= 2;
|
||||
}
|
||||
|
||||
public void EndDoubleExp()
|
||||
{
|
||||
AnnounceMessageOnMainScreen("Experience points effect wore off.");
|
||||
DoubleExpTimeEnd?.Invoke();
|
||||
ExpRate = 1;
|
||||
ExpRate /= 2;
|
||||
}
|
||||
|
||||
public void AnnounceMessageOnMainScreen(string message)
|
||||
@@ -131,7 +131,7 @@ public class GameRepo : IGameRepo
|
||||
AnnounceMessageInInventoryEvent?.Invoke(message);
|
||||
}
|
||||
|
||||
public void RemoveItemFromInventory(InventoryItem item)
|
||||
public void RemoveItemFromInventory(IBaseInventoryItem item)
|
||||
{
|
||||
RemoveItemFromInventoryEvent?.Invoke(item);
|
||||
}
|
||||
@@ -146,24 +146,16 @@ public class GameRepo : IGameRepo
|
||||
PlayerAttackedWall?.Invoke();
|
||||
}
|
||||
|
||||
public void OnPlayerAttackedEnemy()
|
||||
{
|
||||
PlayerAttackedEnemy?.Invoke();
|
||||
}
|
||||
|
||||
public void OnRestorativePickedUp(IHealthPack restorative)
|
||||
{
|
||||
RestorativePickedUp?.Invoke(restorative);
|
||||
}
|
||||
|
||||
public void CloseInventory()
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
||||
@@ -8,14 +8,14 @@ public partial class GameState
|
||||
|
||||
public readonly record struct LoadGame;
|
||||
|
||||
public readonly record struct ContinueGame;
|
||||
|
||||
public readonly record struct ReturnToMainMenu;
|
||||
public readonly record struct ExitGame;
|
||||
|
||||
public readonly record struct LoadNextFloor;
|
||||
|
||||
public readonly record struct InventoryButtonPressed;
|
||||
|
||||
public readonly record struct InteractButtonPressed;
|
||||
|
||||
public readonly record struct PauseButtonPressed;
|
||||
|
||||
public readonly record struct DebugButtonPressed;
|
||||
@@ -28,6 +28,8 @@ public partial class GameState
|
||||
|
||||
public readonly record struct CloseTeleport;
|
||||
|
||||
public readonly record struct CloseInventory;
|
||||
|
||||
public readonly record struct GameOver;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ public partial class GameState
|
||||
{
|
||||
public readonly record struct InitializeGame;
|
||||
|
||||
public readonly record struct ExitGame;
|
||||
|
||||
public readonly record struct LoadGameFromFile;
|
||||
|
||||
public readonly record struct OpenInventoryMenu;
|
||||
|
||||
@@ -16,11 +16,6 @@ public partial class GameState
|
||||
OnAttach(() => Get<IGameRepo>().Pause());
|
||||
}
|
||||
|
||||
public Transition On(in Input.ReturnToMainMenu input)
|
||||
{
|
||||
return To<MainMenu>();
|
||||
}
|
||||
|
||||
public Transition On(in Input.UseTeleport input)
|
||||
{
|
||||
Output(new Output.OpenFloorExitScreen());
|
||||
|
||||
@@ -8,7 +8,7 @@ public partial class GameState
|
||||
public partial record State
|
||||
{
|
||||
[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)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ public partial class GameState
|
||||
public partial record State
|
||||
{
|
||||
[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()
|
||||
{
|
||||
@@ -20,11 +20,6 @@ public partial class GameState
|
||||
Output(new Output.LoadNextFloor());
|
||||
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
|
||||
{
|
||||
[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());
|
||||
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
|
||||
{
|
||||
[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());
|
||||
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.LogicBlocks;
|
||||
using static Zennysoft.Ma.Adapter.GameState.Output;
|
||||
|
||||
namespace Zennysoft.Ma.Adapter;
|
||||
|
||||
@@ -8,13 +9,20 @@ public partial class GameState
|
||||
public partial record State
|
||||
{
|
||||
[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)
|
||||
{
|
||||
Output(new Output.ClosePauseScreen());
|
||||
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 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.Serialization;
|
||||
using Zennysoft.Game.Abstractions;
|
||||
|
||||
namespace Zennysoft.Ma.Adapter;
|
||||
|
||||
@@ -8,10 +7,10 @@ namespace Zennysoft.Ma.Adapter;
|
||||
public partial class RescuedItemDatabase
|
||||
{
|
||||
[Save("rescued_item_list")]
|
||||
public List<InventoryItem> Items { get; init; }
|
||||
public List<IBaseInventoryItem> Items { get; init; }
|
||||
|
||||
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))]
|
||||
public partial class AccessoryTagEnumContext : JsonSerializerContext;
|
||||
|
||||
[JsonSerializable(typeof(ThrowableItemTag))]
|
||||
public partial class ThrowableItemTagEnumContext : JsonSerializerContext;
|
||||
|
||||
[JsonSerializable(typeof(UsableItemTag))]
|
||||
public partial class UsableItemTagEnumContext : JsonSerializerContext;
|
||||
|
||||
@@ -21,4 +18,4 @@ public partial class UsableItemTagEnumContext : JsonSerializerContext;
|
||||
public partial class BoxItemTagEnumContext : JsonSerializerContext;
|
||||
|
||||
[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 Godot;
|
||||
using System.Collections.Immutable;
|
||||
using Zennysoft.Ma.Adapter.Entity;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
public interface IDungeonRoom : INode3D
|
||||
@@ -10,8 +10,8 @@ public class Module
|
||||
public static void Bootstrap(Container container)
|
||||
{
|
||||
container.RegisterSingleton<IFileSystem, FileSystem>();
|
||||
container.RegisterSingleton<ISaveFileManager<GameData>, SaveFileManager<GameData>>();
|
||||
container.RegisterSingleton<IMaSaveFileManager<GameData>, MaSaveFileManager<GameData>>();
|
||||
container.RegisterSingleton<ISaveFileManager, SaveFileManager>();
|
||||
container.RegisterSingleton<IMaSaveFileManager, MaSaveFileManager>();
|
||||
container.RegisterSingleton<IGameRepo, GameRepo>();
|
||||
container.RegisterSingleton<IGameState, GameState>();
|
||||
container.RegisterSingleton<IDimmableAudioStreamPlayer, DimmableAudioStreamPlayer>();
|
||||
|
||||
@@ -1,66 +1,67 @@
|
||||
using Chickensoft.Collections;
|
||||
using Chickensoft.GodotNodeInterfaces;
|
||||
using Godot;
|
||||
using Zennysoft.Game.Abstractions;
|
||||
|
||||
namespace Zennysoft.Ma.Adapter;
|
||||
|
||||
public interface IPlayer : IKillable
|
||||
public interface IPlayer : IKillable, ICharacterBody3D
|
||||
{
|
||||
public void InitializePlayerState();
|
||||
public void ResetPlayerData();
|
||||
|
||||
public void Activate();
|
||||
|
||||
public void Deactivate();
|
||||
|
||||
public void Attack();
|
||||
|
||||
public void TakeDamage(double damage, ElementType elementType = ElementType.None, bool isCriticalHit = false);
|
||||
public void TakeDamage(AttackData damage);
|
||||
|
||||
public void Knockback(float impulse);
|
||||
|
||||
public void GainExp(double expGained);
|
||||
|
||||
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 ModifyBonusAttack(int amount);
|
||||
|
||||
public void ModifyBonusDefense(int amount);
|
||||
|
||||
public void ModifyMaximumHP(int amount);
|
||||
|
||||
public void ModifyMaximumVT(int amount);
|
||||
|
||||
public void ModifyBonusLuck(double amount);
|
||||
|
||||
public void SetHealthTimerStatus(bool isActive);
|
||||
public void IdentifyItem(IBaseInventoryItem unidentifiedItem);
|
||||
|
||||
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 Moved(Vector3 GlobalPosition, Transform3D GlobalTransform);
|
||||
|
||||
public readonly record struct Enable;
|
||||
|
||||
public readonly record struct Attack;
|
||||
|
||||
public readonly record struct AttackAnimationFinished;
|
||||
|
||||
public readonly record struct Die;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@ public interface IPlayerLogic : ILogicBlock<PlayerLogic.State>;
|
||||
[LogicBlock(typeof(State), Diagram = true)]
|
||||
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
|
||||
{
|
||||
[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)
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ public partial class PlayerLogic
|
||||
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());
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
public MaSaveFileManager(ISaveFileManager<T> saveFileManager)
|
||||
public MaSaveFileManager(ISaveFileManager 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]);
|
||||
}
|
||||
|
||||
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.LogicBlocks;
|
||||
using Zennysoft.Game.Implementation;
|
||||
|
||||
|
||||
namespace Zennysoft.Ma.Adapter;
|
||||
@@ -37,7 +38,7 @@ public partial class InGameUILogic
|
||||
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;
|
||||
public partial class InGameUILogic
|
||||
@@ -7,7 +8,7 @@ public partial class InGameUILogic
|
||||
{
|
||||
public readonly record struct AnnounceMessageOnMainScreen(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 HideInventory;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Game\state\states\**" />
|
||||
<Compile Remove="Map\**" />
|
||||
<EmbeddedResource Remove="Game\state\states\**" />
|
||||
<EmbeddedResource Remove="Map\**" />
|
||||
<None Remove="Game\state\states\**" />
|
||||
<None Remove="Map\**" />
|
||||
<Compile Remove="Actions\**" />
|
||||
<Compile Remove="Game\state\states\**" />
|
||||
<EmbeddedResource Remove="Actions\**" />
|
||||
<EmbeddedResource Remove="Game\state\states\**" />
|
||||
<None Remove="Actions\**" />
|
||||
<None Remove="Game\state\states\**" />
|
||||
</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