Compare commits
38 Commits
eed50bc04e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 |
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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,4 +11,8 @@ public interface ISaveFileManager
|
|||||||
public Task<T?> ReadFromFile<T>(params IJsonTypeInfoResolver?[] resolvers);
|
public Task<T?> ReadFromFile<T>(params IJsonTypeInfoResolver?[] resolvers);
|
||||||
|
|
||||||
public Task<T?> ReadFromFile<T>(string filePath, params IJsonTypeInfoResolver?[] resolvers);
|
public Task<T?> ReadFromFile<T>(string filePath, params IJsonTypeInfoResolver?[] resolvers);
|
||||||
|
|
||||||
|
public void DeleteSaveData(string filePath);
|
||||||
|
|
||||||
|
public void DeleteSaveData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,4 +74,8 @@ public class SaveFileManager : ISaveFileManager
|
|||||||
var json = JsonSerializer.Serialize(gameData, jsonOptions);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,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 +34,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,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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ public partial class AppLogic
|
|||||||
public partial record State
|
public partial record State
|
||||||
{
|
{
|
||||||
[Meta]
|
[Meta]
|
||||||
public partial record MainMenu : State, IGet<Input.NewGame>, IGet<Input.LoadGame>, IGet<Input.EnemyViewerOpened>
|
public partial record MainMenu : State, IGet<Input.NewGame>, IGet<Input.EnemyViewerOpened>, IGet<Input.QuitGame>
|
||||||
{
|
{
|
||||||
public MainMenu()
|
public MainMenu()
|
||||||
{
|
{
|
||||||
@@ -16,7 +16,11 @@ public partial class AppLogic
|
|||||||
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.LoadGame input) => To<LoadingSaveFile>();
|
public Transition On(in Input.QuitGame input)
|
||||||
|
{
|
||||||
|
Output(new Output.ExitGame());
|
||||||
|
return ToSelf();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Chickensoft.Collections;
|
using Chickensoft.Collections;
|
||||||
|
using Godot;
|
||||||
using Zennysoft.Ma.Adapter.Entity;
|
using Zennysoft.Ma.Adapter.Entity;
|
||||||
|
|
||||||
namespace Zennysoft.Ma.Adapter;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
@@ -28,4 +29,5 @@ public interface IEquipmentComponent : IEntityComponent
|
|||||||
|
|
||||||
public ElementalResistanceSet ElementalResistance { get; }
|
public ElementalResistanceSet ElementalResistance { get; }
|
||||||
|
|
||||||
|
public event Action<EquipableItem> EquipmentChanged;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,5 +21,5 @@ public interface IHealthComponent : IEntityComponent
|
|||||||
|
|
||||||
public void SetMaximumHealth(int health);
|
public void SetMaximumHealth(int health);
|
||||||
|
|
||||||
public void RaiseMaximumHP(int raiseAmount);
|
public void RaiseMaximumHP(int raiseAmount, bool restoreHP = false);
|
||||||
}
|
}
|
||||||
@@ -16,5 +16,7 @@ public interface IVTComponent : IEntityComponent
|
|||||||
|
|
||||||
public void SetVT(int vt);
|
public void SetVT(int vt);
|
||||||
|
|
||||||
public void RaiseMaximumVT(int raiseAmount);
|
public void RaiseMaximumVT(int raiseAmount, bool restoreVT = true);
|
||||||
|
|
||||||
|
public void SetMaximumVT(int vt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ namespace Zennysoft.Ma.Adapter.Entity
|
|||||||
|
|
||||||
public void ReturnToDefaultState();
|
public void ReturnToDefaultState();
|
||||||
|
|
||||||
|
public void OnAbsorb();
|
||||||
|
|
||||||
|
public void OnMorph();
|
||||||
|
|
||||||
public IDungeonRoom GetCurrentRoom(ImmutableList<IDungeonRoom> dungeonRooms);
|
public IDungeonRoom GetCurrentRoom(ImmutableList<IDungeonRoom> dungeonRooms);
|
||||||
|
|
||||||
public void MoveEnemyToNewRoom(IDungeonRoom newRoom);
|
public void MoveEnemyToNewRoom(IDungeonRoom newRoom);
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ public partial class GameState
|
|||||||
|
|
||||||
public readonly record struct LoadGame;
|
public readonly record struct LoadGame;
|
||||||
|
|
||||||
|
public readonly record struct ExitGame;
|
||||||
|
|
||||||
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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ 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>
|
||||||
{
|
{
|
||||||
public Transition On(in Input.InventoryButtonPressed input)
|
public Transition On(in Input.InteractButtonPressed input)
|
||||||
{
|
{
|
||||||
Output(new Output.CloseInventoryMenu());
|
Output(new Output.CloseInventoryMenu());
|
||||||
return To<InGame>();
|
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>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ public interface IInventory
|
|||||||
|
|
||||||
public void Remove(InventoryItem inventoryItem);
|
public void Remove(InventoryItem inventoryItem);
|
||||||
|
|
||||||
public void Sort(EquipableItem currentWeapon, EquipableItem currentArmor, EquipableItem currentAccessory);
|
public bool Sort(EquipableItem currentWeapon, EquipableItem currentArmor, EquipableItem currentAccessory);
|
||||||
|
|
||||||
public event Action<string> BroadcastMessage;
|
public event Action<string> BroadcastMessage;
|
||||||
|
public event Action InventoryChanged;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ public interface IPlayer : IKillable, ICharacterBody3D
|
|||||||
|
|
||||||
public IEquipmentComponent EquipmentComponent { get; }
|
public IEquipmentComponent EquipmentComponent { get; }
|
||||||
|
|
||||||
|
public void PlayTestAnimation();
|
||||||
|
|
||||||
public event Action PlayerDied;
|
public event Action PlayerDied;
|
||||||
public delegate InventoryItem RerollItem(InventoryItem item);
|
public delegate InventoryItem RerollItem(InventoryItem item);
|
||||||
}
|
}
|
||||||
|
|||||||
38
Zennysoft.Game.Ma/Ma.csproj.old.1
Normal file
38
Zennysoft.Game.Ma/Ma.csproj.old.1
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<Project Sdk="Godot.NET.Sdk/4.4.0">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
<WarningsAsErrors>CS9057</WarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
38
Zennysoft.Game.Ma/Ma.csproj.old.2
Normal file
38
Zennysoft.Game.Ma/Ma.csproj.old.2
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<Project Sdk="Godot.NET.Sdk/4.4.0">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
<WarningsAsErrors>CS9057</WarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
38
Zennysoft.Game.Ma/Ma.csproj.old.3
Normal file
38
Zennysoft.Game.Ma/Ma.csproj.old.3
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<Project Sdk="Godot.NET.Sdk/4.4.1">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
<WarningsAsErrors>CS9057</WarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
38
Zennysoft.Game.Ma/Ma.csproj.old.4
Normal file
38
Zennysoft.Game.Ma/Ma.csproj.old.4
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<Project Sdk="Godot.NET.Sdk/4.4.0">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
<WarningsAsErrors>CS9057</WarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
38
Zennysoft.Game.Ma/Ma.csproj.old.5
Normal file
38
Zennysoft.Game.Ma/Ma.csproj.old.5
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<Project Sdk="Godot.NET.Sdk/4.4.1">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
<WarningsAsErrors>CS9057</WarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
287
Zennysoft.Game.Ma/addons/input_helper/InputHelper.cs
Normal file
287
Zennysoft.Game.Ma/addons/input_helper/InputHelper.cs
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
using Godot;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace NathanHoad
|
||||||
|
{
|
||||||
|
public static class InputHelper
|
||||||
|
{
|
||||||
|
public delegate void DeviceChangedEventHandler(string device, int deviceIndex);
|
||||||
|
public delegate void KeyboardInputChangedEventHandler(string action, InputEvent input);
|
||||||
|
public delegate void JoypadInputChangedEventHandler(string action, InputEvent input);
|
||||||
|
public delegate void JoypadChangedEventHandler(int deviceIndex, bool isConnected);
|
||||||
|
|
||||||
|
public static DeviceChangedEventHandler? DeviceChanged;
|
||||||
|
public static KeyboardInputChangedEventHandler? KeyboardInputChanged;
|
||||||
|
public static JoypadInputChangedEventHandler? JoypadInputChanged;
|
||||||
|
public static JoypadChangedEventHandler? JoypadChanged;
|
||||||
|
|
||||||
|
|
||||||
|
public const string DEVICE_KEYBOARD = "keyboard";
|
||||||
|
public const string DEVICE_XBOX_CONTROLLER = "xbox";
|
||||||
|
public const string DEVICE_SWITCH_CONTROLLER = "switch";
|
||||||
|
public const string DEVICE_PLAYSTATION_CONTROLLER = "playstation";
|
||||||
|
public const string DEVICE_STEAMDECK_CONTROLLER = "steamdeck";
|
||||||
|
public const string DEVICE_GENERIC = "generic";
|
||||||
|
|
||||||
|
public const string SUB_DEVICE_XBOX_ONE_CONTROLLER = "xbox_one";
|
||||||
|
public const string SUB_DEVICE_XBOX_SERIES_CONTROLLER = "xbox_series";
|
||||||
|
public const string SUB_DEVICE_PLAYSTATION3_CONTROLLER = "playstation3";
|
||||||
|
public const string SUB_DEVICE_PLAYSTATION4_CONTROLLER = "playstation4";
|
||||||
|
public const string SUB_DEVICE_PLAYSTATION5_CONTROLLER = "playstation5";
|
||||||
|
public const string SUB_DEVICE_SWITCH_JOYCON_LEFT_CONTROLLER = "switch_left_joycon";
|
||||||
|
public const string SUB_DEVICE_SWITCH_JOYCON_RIGHT_CONTROLLER = "switch_right_joycon";
|
||||||
|
|
||||||
|
|
||||||
|
private static Node instance;
|
||||||
|
public static Node Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (instance == null)
|
||||||
|
{
|
||||||
|
instance = (Node)Engine.GetSingleton("InputHelper");
|
||||||
|
instance.Connect("device_changed", Callable.From((string device, int deviceIndex) => DeviceChanged?.Invoke(device, deviceIndex)));
|
||||||
|
instance.Connect("keyboard_input_changed", Callable.From((string action, InputEvent input) => KeyboardInputChanged?.Invoke(action, input)));
|
||||||
|
instance.Connect("joypad_input_changed", Callable.From((string action, InputEvent input) => JoypadInputChanged?.Invoke(action, input)));
|
||||||
|
instance.Connect("joypad_changed", Callable.From((int deviceIndex, bool isConnected) => JoypadChanged?.Invoke(deviceIndex, isConnected)));
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string Device
|
||||||
|
{
|
||||||
|
get => (string)Instance.Get("device");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static int DeviceIndex
|
||||||
|
{
|
||||||
|
get => (int)Instance.Get("device_index");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string LastKnownJoypadDevice
|
||||||
|
{
|
||||||
|
get => (string)Instance.Get("last_known_joypad_device");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string LastKnownJoypadIndex
|
||||||
|
{
|
||||||
|
get => (string)Instance.Get("last_known_joypad_index");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static float Deadzone
|
||||||
|
{
|
||||||
|
get => (float)Instance.Get("deadzone");
|
||||||
|
set => Instance.Set("deadzone", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static int MouseMotionThreshold
|
||||||
|
{
|
||||||
|
get => (int)Instance.Get("mouse_motion_threshold");
|
||||||
|
set => Instance.Set("mouse_motion_threshold", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string GetSimplifiedDeviceName(string rawName)
|
||||||
|
{
|
||||||
|
return (string)Instance.Call("get_simplified_device_name", rawName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string GetDeviceFromEvent(InputEvent @event)
|
||||||
|
{
|
||||||
|
return (string)Instance.Call("get_device_from_event", @event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static int GetDeviceIndexFromEvent(InputEvent @event)
|
||||||
|
{
|
||||||
|
return (int)Instance.Call("get_device_index_from_event", @event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static bool HasJoypad()
|
||||||
|
{
|
||||||
|
return (bool)Instance.Call("has_joypad");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string GuessDeviceName()
|
||||||
|
{
|
||||||
|
return (string)Instance.Call("guess_device_name");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void ResetAllActions()
|
||||||
|
{
|
||||||
|
Instance.Call("reset_all_actions");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void SetKeyboardOrJoypadInputForAction(string action, InputEvent input, bool swapIfTaken = true)
|
||||||
|
{
|
||||||
|
Instance.Call("set_keyboard_or_joypad_input_for_action", action, input, swapIfTaken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static InputEvent GetKeyboardOrJoypadInputForAction(string action, InputEvent input, bool swapIfTaken = true)
|
||||||
|
{
|
||||||
|
return (InputEvent)Instance.Call("get_keyboard_or_joypad_input_for_action", action, input, swapIfTaken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Array<InputEvent> GetKeyboardOrJoypadInputsForAction(string action)
|
||||||
|
{
|
||||||
|
return (Array<InputEvent>)Instance.Call("get_keyboard_or_joypad_inputs_for_action", action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string GetLabelForInput(InputEvent input)
|
||||||
|
{
|
||||||
|
return (string)Instance.Call("get_label_for_input", input);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string SerializeInputsForAction(string action)
|
||||||
|
{
|
||||||
|
return (string)Instance.Call("serialize_inputs_for_action", action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string SerializeInputsForActions(Array<string> actions = null)
|
||||||
|
{
|
||||||
|
if (actions == null)
|
||||||
|
{
|
||||||
|
actions = new Array<string>();
|
||||||
|
}
|
||||||
|
return (string)Instance.Call("serialize_inputs_for_actions", actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void DeserializeInputsForAction(string action, string serializedInputs)
|
||||||
|
{
|
||||||
|
Instance.Call("desserialize_inputs_for_action", action, serializedInputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeserializeInputsForActions(string serializedInputs)
|
||||||
|
{
|
||||||
|
Instance.Call("deserialize_inputs_for_actions", serializedInputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Keyboard/Mouse
|
||||||
|
|
||||||
|
public static Array<InputEvent> GetKeyboardInputsForAction(string action)
|
||||||
|
{
|
||||||
|
return (Array<InputEvent>)Instance.Call("get_keyboard_inputs_for_action", action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static InputEvent GetKeyboardInputForAction(string action)
|
||||||
|
{
|
||||||
|
return (InputEvent)Instance.Call("get_keyboard_input_for_action", action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void SetKeyboardInputForAction(string action, InputEvent input, bool swapIfTaken = true)
|
||||||
|
{
|
||||||
|
Instance.Call("set_keyboard_input_for_action", action, input, swapIfTaken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void ReplaceKeyboardInputForAction(string action, InputEvent currentInput, InputEvent input, bool swapIfTaken = true)
|
||||||
|
{
|
||||||
|
Instance.Call("replace_keyboard_input_for_action", action, currentInput, input, swapIfTaken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void ReplaceKeyboardInputAtIndex(string action, int index, InputEvent input, bool swapIfTaken = true)
|
||||||
|
{
|
||||||
|
Instance.Call("replace_keyboard_input_at_index", action, index, input, swapIfTaken);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Joypad
|
||||||
|
|
||||||
|
public static Array<InputEvent> GetJoypadInputsForAction(string action)
|
||||||
|
{
|
||||||
|
return (Array<InputEvent>)Instance.Call("get_joypad_inputs_for_action", action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static InputEvent GetJoypadInputForAction(string action)
|
||||||
|
{
|
||||||
|
return (InputEvent)Instance.Call("get_joypad_input_for_action", action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void SetJoypadInputForAction(string action, InputEvent input, bool swapIfTaken = true)
|
||||||
|
{
|
||||||
|
Instance.Call("set_joypad_input_for_action", action, input, swapIfTaken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void ReplaceJoypadInputForAction(string action, InputEvent currentInput, InputEvent input, bool swapIfTaken = true)
|
||||||
|
{
|
||||||
|
Instance.Call("replace_joypad_input_for_action", action, currentInput, input, swapIfTaken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void ReplaceJoypadInputAtIndex(string action, int index, InputEvent input, bool swapIfTaken = true)
|
||||||
|
{
|
||||||
|
Instance.Call("replace_joypad_input_at_index", action, index, input, swapIfTaken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void RumbleSmall(int targetDevice = 0)
|
||||||
|
{
|
||||||
|
Instance.Call("rumble_small", targetDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void RumbleMedium(int targetDevice = 0)
|
||||||
|
{
|
||||||
|
Instance.Call("rumble_medium", targetDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void RumbleLarge(int targetDevice = 0)
|
||||||
|
{
|
||||||
|
Instance.Call("rumble_large", targetDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void StartRumbleSmall(int targetDevice = 0)
|
||||||
|
{
|
||||||
|
Instance.Call("start_rumble_small", targetDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void StartRumbleMedium(int targetDevice = 0)
|
||||||
|
{
|
||||||
|
Instance.Call("start_rumble_medium", targetDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void StartRumbleLarge(int targetDevice = 0)
|
||||||
|
{
|
||||||
|
Instance.Call("start_rumble_large", targetDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void StopRumble(int targetDevice = 0)
|
||||||
|
{
|
||||||
|
Instance.Call("stop_rumble", targetDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
1
Zennysoft.Game.Ma/addons/input_helper/InputHelper.cs.uid
Normal file
1
Zennysoft.Game.Ma/addons/input_helper/InputHelper.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cfs4dgwrfvb11
|
||||||
21
Zennysoft.Game.Ma/addons/input_helper/LICENSE
Normal file
21
Zennysoft.Game.Ma/addons/input_helper/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022-present Nathan Hoad
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
230
Zennysoft.Game.Ma/addons/input_helper/assets/update.svg
Normal file
230
Zennysoft.Game.Ma/addons/input_helper/assets/update.svg
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="300"
|
||||||
|
height="80"
|
||||||
|
viewBox="0 0 79.374999 21.166667"
|
||||||
|
version="1.1"
|
||||||
|
id="svg291"
|
||||||
|
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
|
||||||
|
sodipodi:docname="update.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview293"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
showgrid="false"
|
||||||
|
width="1920px"
|
||||||
|
units="px"
|
||||||
|
borderlayer="true"
|
||||||
|
inkscape:showpageshadow="false"
|
||||||
|
inkscape:zoom="4"
|
||||||
|
inkscape:cx="121.625"
|
||||||
|
inkscape:cy="43.25"
|
||||||
|
inkscape:window-width="2560"
|
||||||
|
inkscape:window-height="1377"
|
||||||
|
inkscape:window-x="2552"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showguides="true">
|
||||||
|
<sodipodi:guide
|
||||||
|
position="-15.575132,19.553027"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide2089"
|
||||||
|
inkscape:locked="false" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<defs
|
||||||
|
id="defs288" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<g
|
||||||
|
id="g2335"
|
||||||
|
transform="matrix(0.93072355,0,0,0.92874157,17.062816,18.409989)"
|
||||||
|
style="stroke-width:0.85374062;stroke-dasharray:none;stroke:none">
|
||||||
|
<path
|
||||||
|
id="rect2095"
|
||||||
|
style="fill:#349684;fill-opacity:1;stroke:#152f2c;stroke-width:0.56916041;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:normal"
|
||||||
|
d="m 24.364404,-16.012976 a 1.7811118,1.7811118 0 0 0 -1.568379,0.938961 1.7811118,1.7811118 0 0 0 -1.557528,-0.918291 1.7811118,1.7811118 0 0 0 -1.383895,0.660942 c -1.816891,-1.243302 -4.115395,-0.49791 -5.162476,1.678967 l -2.844787,5.914368 c -1.050638,2.1842718 -0.431729,4.957652 1.388029,6.2187419 1.819758,1.26108987 4.130958,0.5177068 5.181596,-1.666565 l 1.240234,-2.5786539 h 6.335531 l 1.240234,2.5786539 c 1.050638,2.1842718 3.361322,2.92765487 5.181079,1.666565 1.819758,-1.2610899 2.439184,-4.0344701 1.388546,-6.2187419 L 30.9578,-13.652397 c -1.050637,-2.184271 -3.361838,-2.927654 -5.181596,-1.666565 -1.97e-4,1.37e-4 -3.19e-4,3.8e-4 -5.16e-4,5.17e-4 a 1.7811118,1.7811118 0 0 0 -1.411284,-0.694531 z" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.85374062;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="rect2101"
|
||||||
|
width="1.403165"
|
||||||
|
height="4.2796535"
|
||||||
|
x="17.394386"
|
||||||
|
y="-13.427068"
|
||||||
|
ry="0.75541198"
|
||||||
|
rx="0.75380331" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.85374062;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="rect2103"
|
||||||
|
width="1.403165"
|
||||||
|
height="4.2796535"
|
||||||
|
x="-11.988823"
|
||||||
|
y="-20.235798"
|
||||||
|
ry="0.75380331"
|
||||||
|
rx="0.75541198"
|
||||||
|
transform="rotate(90)" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.85374062;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="ellipse2105"
|
||||||
|
cx="28.192503"
|
||||||
|
cy="2.7587082"
|
||||||
|
rx="0.82257289"
|
||||||
|
ry="0.79261416"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.85374062;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="ellipse2107"
|
||||||
|
cx="28.216581"
|
||||||
|
cy="4.7943339"
|
||||||
|
rx="0.82257289"
|
||||||
|
ry="0.79261416"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.85374062;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="ellipse2109"
|
||||||
|
cx="30.279696"
|
||||||
|
cy="2.6987464"
|
||||||
|
rx="0.82257289"
|
||||||
|
ry="0.79261416"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.85374062;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="ellipse2111"
|
||||||
|
cx="30.320311"
|
||||||
|
cy="4.767447"
|
||||||
|
rx="0.82257289"
|
||||||
|
ry="0.79261416"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.85374062;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="rect2117"
|
||||||
|
width="1.109892"
|
||||||
|
height="2.1669323"
|
||||||
|
x="22.090807"
|
||||||
|
y="-10.531444"
|
||||||
|
ry="0.52878839"
|
||||||
|
rx="0.52766228" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
id="rect1625"
|
||||||
|
style="fill:#50fa7b;fill-opacity:1;stroke:#0f451d;stroke-width:0.593381;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
|
d="m 50.52517,5.3570989 c -0.643062,0 -1.160653,0.5900216 -1.160653,1.3229166 v 1.0764201 h -1.07642 c -0.732895,0 -1.322916,0.5175908 -1.322916,1.1606533 0,0.643061 0.590021,1.1611691 1.322916,1.1611691 h 1.07642 v 1.076421 c 0,0.732895 0.517591,1.322917 1.160653,1.322917 0.643062,0 1.160653,-0.590022 1.160653,-1.322917 v -1.076421 h 1.076937 c 0.732895,0 1.322916,-0.5181081 1.322916,-1.1611691 0,-0.6430625 -0.590021,-1.1606533 -1.322916,-1.1606533 H 51.685823 V 6.6800155 c 0,-0.732895 -0.517591,-1.3229166 -1.160653,-1.3229166 z" />
|
||||||
|
<path
|
||||||
|
id="path2678"
|
||||||
|
style="fill:#50fa7b;fill-opacity:1;stroke:#0f451d;stroke-width:0.593381;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
|
d="m 57.791691,5.357099 c -0.643062,0 -1.160653,0.5900216 -1.160653,1.3229166 v 1.0764201 h -1.07642 c -0.732895,0 -1.322916,0.5175908 -1.322916,1.1606522 0,0.643062 0.590021,1.1611701 1.322916,1.1611701 h 1.07642 v 1.076421 c 0,0.732895 0.517591,1.322917 1.160653,1.322917 0.643062,0 1.160653,-0.590022 1.160653,-1.322917 v -1.076421 h 1.076937 c 0.732895,0 1.322916,-0.5181081 1.322916,-1.1611701 0,-0.6430614 -0.590021,-1.1606522 -1.322916,-1.1606522 H 58.952344 V 6.6800156 c 0,-0.732895 -0.517591,-1.3229166 -1.160653,-1.3229166 z" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke-width:0.72829;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:0.3;paint-order:markers stroke fill"
|
||||||
|
id="rect413"
|
||||||
|
width="10.200269"
|
||||||
|
height="8.7847834"
|
||||||
|
x="-21.316095"
|
||||||
|
y="3.0372066" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke-width:0.622475;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:0.3;paint-order:markers stroke fill"
|
||||||
|
id="rect415"
|
||||||
|
width="7.9928446"
|
||||||
|
height="15.312933"
|
||||||
|
x="-20.546837"
|
||||||
|
y="12.977094"
|
||||||
|
ry="4.375123"
|
||||||
|
transform="matrix(0.82192626,0.56959391,-0.43346431,0.90117073,0,0)"
|
||||||
|
rx="4.375123" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke-width:0.622475;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:0.3;paint-order:markers stroke fill"
|
||||||
|
id="rect471"
|
||||||
|
width="7.9928446"
|
||||||
|
height="15.312933"
|
||||||
|
x="9.1578636"
|
||||||
|
y="-5.7980561"
|
||||||
|
ry="4.375123"
|
||||||
|
transform="matrix(-0.82192626,0.56959391,0.43346431,0.90117073,0,0)"
|
||||||
|
rx="4.375123" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="rect1137"
|
||||||
|
width="1.403165"
|
||||||
|
height="4.2796535"
|
||||||
|
x="-22.240166"
|
||||||
|
y="3.9990206"
|
||||||
|
ry="0.70158249"
|
||||||
|
rx="0.70158249" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="rect1295"
|
||||||
|
width="1.403165"
|
||||||
|
height="4.2796535"
|
||||||
|
x="5.4372649"
|
||||||
|
y="19.398754"
|
||||||
|
ry="0.70158249"
|
||||||
|
rx="0.70158249"
|
||||||
|
transform="rotate(90)" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="ellipse1297"
|
||||||
|
cx="-13.849753"
|
||||||
|
cy="-1.3102485"
|
||||||
|
rx="0.82257289"
|
||||||
|
ry="0.79261416"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="ellipse1299"
|
||||||
|
cx="-13.825675"
|
||||||
|
cy="0.72537726"
|
||||||
|
rx="0.82257289"
|
||||||
|
ry="0.79261416"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="ellipse1301"
|
||||||
|
cx="-11.762562"
|
||||||
|
cy="-1.3702103"
|
||||||
|
rx="0.82257289"
|
||||||
|
ry="0.79261416"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="ellipse1303"
|
||||||
|
cx="-11.721946"
|
||||||
|
cy="0.69849032"
|
||||||
|
rx="0.82257289"
|
||||||
|
ry="0.79261416"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<circle
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="path2085"
|
||||||
|
cx="-17.863199"
|
||||||
|
cy="3.3752983"
|
||||||
|
r="1.7811118" />
|
||||||
|
<circle
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="circle2087"
|
||||||
|
cx="-14.737003"
|
||||||
|
cy="3.3542202"
|
||||||
|
r="1.7811118" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0.3;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
id="rect2091"
|
||||||
|
width="0.98221546"
|
||||||
|
height="1.917659"
|
||||||
|
x="-16.946886"
|
||||||
|
y="7.1795278"
|
||||||
|
ry="0.49110773"
|
||||||
|
rx="0.49110773" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 11 KiB |
@@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://bodfblud4kea3"
|
uid="uid://ddixs2ish5bi6"
|
||||||
path="res://.godot/imported/slash_0003_Classic_27.png-6f445ce101e9ea54bfeda842ed6b0aba.ctex"
|
path="res://.godot/imported/update.svg-3137f1f7d53c08c0ae65aabe138d898b.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://src/vfx/slash/slash_0003_Classic_27.png"
|
source_file="res://addons/input_helper/assets/update.svg"
|
||||||
dest_files=["res://.godot/imported/slash_0003_Classic_27.png-6f445ce101e9ea54bfeda842ed6b0aba.ctex"]
|
dest_files=["res://.godot/imported/update.svg-3137f1f7d53c08c0ae65aabe138d898b.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
@@ -32,3 +32,6 @@ process/hdr_as_srgb=false
|
|||||||
process/hdr_clamp_exposure=false
|
process/hdr_clamp_exposure=false
|
||||||
process/size_limit=0
|
process/size_limit=0
|
||||||
detect_3d/compress_to=1
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
@tool
|
||||||
|
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
|
||||||
|
signal failed()
|
||||||
|
signal updated(updated_to_version: String)
|
||||||
|
|
||||||
|
|
||||||
|
const TEMP_FILE_NAME = "user://temp.zip"
|
||||||
|
|
||||||
|
|
||||||
|
@onready var logo: TextureRect = %Logo
|
||||||
|
@onready var label: Label = $VBox/Label
|
||||||
|
@onready var http_request: HTTPRequest = $HTTPRequest
|
||||||
|
@onready var download_button: Button = %DownloadButton
|
||||||
|
|
||||||
|
var next_version: String = "":
|
||||||
|
set(next_next_version):
|
||||||
|
next_version = next_next_version
|
||||||
|
label.text = "Version %s is available for download!" % next_version
|
||||||
|
get:
|
||||||
|
return next_version
|
||||||
|
|
||||||
|
|
||||||
|
func save_zip(bytes: PackedByteArray) -> void:
|
||||||
|
var file: FileAccess = FileAccess.open(TEMP_FILE_NAME, FileAccess.WRITE)
|
||||||
|
file.store_buffer(bytes)
|
||||||
|
file.flush()
|
||||||
|
|
||||||
|
|
||||||
|
### Signals
|
||||||
|
|
||||||
|
|
||||||
|
func _on_download_button_pressed() -> void:
|
||||||
|
# Safeguard the actual input helper repo from accidentally updating itself
|
||||||
|
if FileAccess.file_exists("res://examples/device_tester.gd"):
|
||||||
|
prints("You can't update the input helper from within itself.")
|
||||||
|
failed.emit()
|
||||||
|
return
|
||||||
|
|
||||||
|
http_request.request("https://github.com/nathanhoad/godot_input_helper/archive/refs/tags/v%s.zip" % next_version)
|
||||||
|
download_button.disabled = true
|
||||||
|
download_button.text = "Downloading..."
|
||||||
|
|
||||||
|
|
||||||
|
func _on_http_request_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||||
|
if result != HTTPRequest.RESULT_SUCCESS:
|
||||||
|
failed.emit()
|
||||||
|
return
|
||||||
|
|
||||||
|
# Save the downloaded zip
|
||||||
|
save_zip(body)
|
||||||
|
|
||||||
|
OS.move_to_trash(ProjectSettings.globalize_path("res://addons/input_helper"))
|
||||||
|
|
||||||
|
var zip_reader: ZIPReader = ZIPReader.new()
|
||||||
|
zip_reader.open(TEMP_FILE_NAME)
|
||||||
|
var files: PackedStringArray = zip_reader.get_files()
|
||||||
|
|
||||||
|
var base_path = files[1]
|
||||||
|
# Remove archive folder
|
||||||
|
files.remove_at(0)
|
||||||
|
# Remove assets folder
|
||||||
|
files.remove_at(0)
|
||||||
|
|
||||||
|
for path in files:
|
||||||
|
var new_file_path: String = path.replace(base_path, "")
|
||||||
|
if path.ends_with("/"):
|
||||||
|
DirAccess.make_dir_recursive_absolute("res://addons/%s" % new_file_path)
|
||||||
|
else:
|
||||||
|
var file: FileAccess = FileAccess.open("res://addons/%s" % new_file_path, FileAccess.WRITE)
|
||||||
|
file.store_buffer(zip_reader.read_file(path))
|
||||||
|
|
||||||
|
zip_reader.close()
|
||||||
|
|
||||||
|
DirAccess.remove_absolute(TEMP_FILE_NAME)
|
||||||
|
|
||||||
|
updated.emit(next_version)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_notes_button_pressed() -> void:
|
||||||
|
OS.shell_open("https://github.com/nathanhoad/godot_input_helper/releases/tag/v%s" % next_version)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dcff0mowkn6km
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://b7mst0qu7vjk1"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://dcff0mowkn6km" path="res://addons/input_helper/components/download_update_panel.gd" id="1_4tm1k"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://ddixs2ish5bi6" path="res://addons/input_helper/assets/update.svg" id="2_j7shv"]
|
||||||
|
|
||||||
|
[node name="DownloadUpdatePanel" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_4tm1k")
|
||||||
|
|
||||||
|
[node name="HTTPRequest" type="HTTPRequest" parent="."]
|
||||||
|
|
||||||
|
[node name="VBox" type="VBoxContainer" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -1.0
|
||||||
|
offset_top = 9.0
|
||||||
|
offset_right = -1.0
|
||||||
|
offset_bottom = 9.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
theme_override_constants/separation = 10
|
||||||
|
|
||||||
|
[node name="Logo" type="TextureRect" parent="VBox"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
clip_contents = true
|
||||||
|
custom_minimum_size = Vector2(300, 80)
|
||||||
|
layout_mode = 2
|
||||||
|
texture = ExtResource("2_j7shv")
|
||||||
|
stretch_mode = 5
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="VBox"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "v1.2.3 is available for download."
|
||||||
|
horizontal_alignment = 1
|
||||||
|
|
||||||
|
[node name="Center" type="CenterContainer" parent="VBox"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="DownloadButton" type="Button" parent="VBox/Center"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Download and install update"
|
||||||
|
|
||||||
|
[node name="Center2" type="CenterContainer" parent="VBox"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="NotesButton" type="LinkButton" parent="VBox/Center2"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Read release notes..."
|
||||||
|
|
||||||
|
[connection signal="request_completed" from="HTTPRequest" to="." method="_on_http_request_request_completed"]
|
||||||
|
[connection signal="pressed" from="VBox/Center/DownloadButton" to="." method="_on_download_button_pressed"]
|
||||||
|
[connection signal="pressed" from="VBox/Center2/NotesButton" to="." method="_on_notes_button_pressed"]
|
||||||
601
Zennysoft.Game.Ma/addons/input_helper/input_helper.gd
Normal file
601
Zennysoft.Game.Ma/addons/input_helper/input_helper.gd
Normal file
@@ -0,0 +1,601 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
|
signal device_changed(device: String, device_index: int)
|
||||||
|
signal keyboard_input_changed(action: String, input: InputEvent)
|
||||||
|
signal joypad_input_changed(action: String, input: InputEvent)
|
||||||
|
signal joypad_changed(device_index: int, is_connected: bool)
|
||||||
|
|
||||||
|
|
||||||
|
const DEVICE_KEYBOARD = "keyboard"
|
||||||
|
const DEVICE_XBOX_CONTROLLER = "xbox"
|
||||||
|
const DEVICE_SWITCH_CONTROLLER = "switch"
|
||||||
|
const DEVICE_PLAYSTATION_CONTROLLER = "playstation"
|
||||||
|
const DEVICE_STEAMDECK_CONTROLLER = "steamdeck"
|
||||||
|
const DEVICE_GENERIC = "generic"
|
||||||
|
|
||||||
|
const SUB_DEVICE_XBOX_ONE_CONTROLLER = "xbox_one"
|
||||||
|
const SUB_DEVICE_XBOX_SERIES_CONTROLLER = "xbox_series"
|
||||||
|
|
||||||
|
const SUB_DEVICE_PLAYSTATION3_CONTROLLER = "playstation3"
|
||||||
|
const SUB_DEVICE_PLAYSTATION4_CONTROLLER = "playstation4"
|
||||||
|
const SUB_DEVICE_PLAYSTATION5_CONTROLLER = "playstation5"
|
||||||
|
|
||||||
|
const SUB_DEVICE_SWITCH_JOYCON_LEFT_CONTROLLER = "switch_left_joycon"
|
||||||
|
const SUB_DEVICE_SWITCH_JOYCON_RIGHT_CONTROLLER = "switch_right_joycon"
|
||||||
|
|
||||||
|
const XBOX_BUTTON_LABELS = ["A", "B", "X", "Y", "Back", "Guide", "Start", "Left Stick", "Right Stick", "LB", "RB", "Up", "Down", "Left", "Right", "Share", "Paddle 1", "Paddle 2", "Paddle 3", "Paddle 4"]
|
||||||
|
const XBOX_ONE_BUTTON_LABELS = ["A", "B", "X", "Y", "View", "Guide", "Menu", "Left Stick", "Right Stick", "LB", "RB", "Up", "Down", "Left", "Right", "Share", "Paddle 1", "Paddle 2", "Paddle 3", "Paddle 4"]
|
||||||
|
const XBOX_SERIES_BUTTON_LABELS = ["A", "B", "X", "Y", "View", "Guide", "Menu", "Left Stick", "Right Stick", "LB", "RB", "Up", "Down", "Left", "Right", "Share", "Paddle 1", "Paddle 2", "Paddle 3", "Paddle 4"]
|
||||||
|
const STEAMDECK_BUTTON_LABELS = ["A", "B", "X", "Y", "View", "?", "Options", "Left Stick", "Right Stick", "L1", "R1", "Up", "Down", "Left", "Right", "", "", "", "", ""]
|
||||||
|
# Note: share and home buttons are not recognized
|
||||||
|
const SWITCH_BUTTON_LABELS = ["B", "A", "Y", "X", "Minus", "", "Plus", "Left Stick", "Right Stick", "LS", "RS", "Up", "Down", "Left", "Right", "Capture"]
|
||||||
|
# Mapping for left and right joypad connected together (extended gamepad)
|
||||||
|
# Left Stick is Axis 0 and 1
|
||||||
|
# Right Stick is Axis 2 and 3
|
||||||
|
# ZL and ZR are Axis 4 and 5
|
||||||
|
const SWITCH_EXTENDED_GAMEPAD_BUTTON_LABELS = ["B", "A", "Y", "X", "Minus", "", "Plus", "Left Stick", "Right Stick", "L", "R", "Up", "Down", "Left", "Right", "Capture"]
|
||||||
|
const PLAYSTATION_3_4_BUTTON_LABELS = ["Cross", "Circle", "Square", "Triangle", "Share", "PS", "Options", "L3", "R3", "L1", "R1", "Up", "Down", "Left", "Right", "Microphone", "", "", "", "", "Touchpad"]
|
||||||
|
# Note: Microphone does not work on PC / touchpad is not recognized
|
||||||
|
const PLAYSTATION_5_BUTTON_LABELS = ["Cross", "Circle", "Square", "Triangle", "Create", "PS", "Options", "L3", "R3", "L1", "R1", "Up", "Down", "Left", "Right", "Microphone", "", "", "", "", "Touchpad"]
|
||||||
|
|
||||||
|
const SERIAL_VERSION = 1
|
||||||
|
|
||||||
|
## The deadzone to ignore for joypad motion
|
||||||
|
var deadzone: float = 0.5
|
||||||
|
## The mouse distance to ignore before movement is assumed
|
||||||
|
var mouse_motion_threshold: int = 100
|
||||||
|
## The last known joypad device name (or "" if no joypad detected)
|
||||||
|
var last_known_joypad_device: String = get_simplified_device_name(Input.get_joy_name(0))
|
||||||
|
## The last known joypad index
|
||||||
|
var last_known_joypad_index: int = 0 if Input.get_connected_joypads().size() > 0 else -1
|
||||||
|
|
||||||
|
## Used internally
|
||||||
|
var device_last_changed_at: int = 0
|
||||||
|
var _last_known_granular_joypad_device: String = get_simplified_device_name(Input.get_joy_name(0), true)
|
||||||
|
|
||||||
|
@onready var device: String = guess_device_name()
|
||||||
|
@onready var device_index: int = 0 if has_joypad() else -1
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||||
|
|
||||||
|
if not Engine.has_singleton("InputHelper"):
|
||||||
|
Engine.register_singleton("InputHelper", self)
|
||||||
|
|
||||||
|
Input.joy_connection_changed.connect(func(device_index, is_connected): joypad_changed.emit(device_index, is_connected))
|
||||||
|
|
||||||
|
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
var next_device: String = device
|
||||||
|
var next_device_index: int = device_index
|
||||||
|
|
||||||
|
# Did we just press a key on the keyboard or move the mouse?
|
||||||
|
if event is InputEventKey \
|
||||||
|
or event is InputEventMouseButton \
|
||||||
|
or (event is InputEventMouseMotion and (event as InputEventMouseMotion).relative.length_squared() > mouse_motion_threshold):
|
||||||
|
next_device = DEVICE_KEYBOARD
|
||||||
|
next_device_index = -1
|
||||||
|
|
||||||
|
# Did we just use a joypad?
|
||||||
|
elif event is InputEventJoypadButton \
|
||||||
|
or (event is InputEventJoypadMotion and abs(event.axis_value) > deadzone):
|
||||||
|
next_device = get_simplified_device_name(get_joy_name(event.device))
|
||||||
|
last_known_joypad_device = next_device
|
||||||
|
next_device_index = event.device
|
||||||
|
last_known_joypad_index = next_device_index
|
||||||
|
|
||||||
|
_last_known_granular_joypad_device = get_simplified_device_name(get_joy_name(event.device), true)
|
||||||
|
|
||||||
|
# Debounce changes for 1 second because some joypads register twice in Windows for some reason
|
||||||
|
var not_changed_in_last_second = Engine.get_frames_drawn() - device_last_changed_at > Engine.get_frames_per_second()
|
||||||
|
if (next_device != device or next_device_index != device_index) and not_changed_in_last_second:
|
||||||
|
device_last_changed_at = Engine.get_frames_drawn()
|
||||||
|
|
||||||
|
device = next_device
|
||||||
|
device_index = next_device_index
|
||||||
|
device_changed.emit(device, device_index)
|
||||||
|
|
||||||
|
|
||||||
|
## Get the name of a joypad
|
||||||
|
func get_joy_name(at_device_index: int) -> String:
|
||||||
|
var joy_name: String = Input.get_joy_name(at_device_index)
|
||||||
|
if joy_name == "" and Input.get_joy_info(at_device_index).size() > 0 and "xinput" in Input.get_joy_info(at_device_index).keys()[0]:
|
||||||
|
joy_name = "XInput"
|
||||||
|
return joy_name
|
||||||
|
|
||||||
|
|
||||||
|
## Get the device name for an event
|
||||||
|
func get_device_from_event(event: InputEvent) -> String:
|
||||||
|
if event is InputEventKey or event is InputEventMouseButton or event is InputEventMouseMotion:
|
||||||
|
return DEVICE_KEYBOARD
|
||||||
|
elif event is InputEventJoypadButton or event is InputEventJoypadMotion:
|
||||||
|
return get_simplified_device_name(get_joy_name(event.device))
|
||||||
|
else:
|
||||||
|
return DEVICE_GENERIC
|
||||||
|
|
||||||
|
|
||||||
|
## Get the device name for an event
|
||||||
|
func get_device_index_from_event(event: InputEvent) -> int:
|
||||||
|
if event is InputEventJoypadButton or event is InputEventJoypadMotion:
|
||||||
|
return event.device
|
||||||
|
else:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
|
## Convert a Godot device identifier to a simplified string
|
||||||
|
func get_simplified_device_name(raw_name: String, force_granular_identifier: bool = false) -> String:
|
||||||
|
var use_granular_identifier: bool = force_granular_identifier or InputHelperSettings.get_setting(InputHelperSettings.USE_GRANULAR_DEVICE_IDENTIFIERS, false)
|
||||||
|
|
||||||
|
var keywords: Dictionary = {
|
||||||
|
SUB_DEVICE_XBOX_ONE_CONTROLLER: ["Xbox One Controller"],
|
||||||
|
SUB_DEVICE_XBOX_SERIES_CONTROLLER: ["Xbox Series Controller", "Xbox Wireless Controller"],
|
||||||
|
DEVICE_XBOX_CONTROLLER: ["XInput", "XBox"],
|
||||||
|
SUB_DEVICE_PLAYSTATION3_CONTROLLER: ["PS3"],
|
||||||
|
SUB_DEVICE_PLAYSTATION4_CONTROLLER:["Nacon Revolution Unlimited Pro Controller", "PS4", "DUALSHOCK 4"],
|
||||||
|
SUB_DEVICE_PLAYSTATION5_CONTROLLER:["Sony DualSense", "PS5", "DualSense Wireless Controller"],
|
||||||
|
DEVICE_STEAMDECK_CONTROLLER: ["Steam"],
|
||||||
|
DEVICE_SWITCH_CONTROLLER: ["Switch", "Joy-Con (L/R)", "PowerA Core Controller"],
|
||||||
|
SUB_DEVICE_SWITCH_JOYCON_LEFT_CONTROLLER: ["Joy-Con (L)"],
|
||||||
|
SUB_DEVICE_SWITCH_JOYCON_RIGHT_CONTROLLER: ["joy-Con (R)"],
|
||||||
|
} if use_granular_identifier else {
|
||||||
|
DEVICE_XBOX_CONTROLLER: ["XBox", "XInput"],
|
||||||
|
DEVICE_PLAYSTATION_CONTROLLER: ["Sony", "PS3", "PS5", "PS4", "DUALSHOCK 4", "DualSense", "Nacon Revolution Unlimited Pro Controller"],
|
||||||
|
DEVICE_STEAMDECK_CONTROLLER: ["Steam"],
|
||||||
|
DEVICE_SWITCH_CONTROLLER: ["Switch", "Joy-Con", "PowerA Core Controller"],
|
||||||
|
}
|
||||||
|
|
||||||
|
for device_key in keywords:
|
||||||
|
for keyword in keywords[device_key]:
|
||||||
|
if keyword.to_lower() in raw_name.to_lower():
|
||||||
|
return device_key
|
||||||
|
|
||||||
|
return DEVICE_GENERIC
|
||||||
|
|
||||||
|
|
||||||
|
## Check if there is a connected joypad
|
||||||
|
func has_joypad() -> bool:
|
||||||
|
return Input.get_connected_joypads().size() > 0
|
||||||
|
|
||||||
|
|
||||||
|
## Guess the initial input device
|
||||||
|
func guess_device_name() -> String:
|
||||||
|
if has_joypad():
|
||||||
|
return get_simplified_device_name(get_joy_name(0))
|
||||||
|
else:
|
||||||
|
return DEVICE_KEYBOARD
|
||||||
|
|
||||||
|
|
||||||
|
#region Mapping
|
||||||
|
|
||||||
|
|
||||||
|
func reset_all_actions() -> void:
|
||||||
|
InputMap.load_from_project_settings()
|
||||||
|
for action in InputMap.get_actions():
|
||||||
|
var input: InputEvent = get_joypad_input_for_action(action)
|
||||||
|
if input != null:
|
||||||
|
joypad_input_changed.emit(action, input)
|
||||||
|
|
||||||
|
input = get_keyboard_input_for_action(action)
|
||||||
|
if input != null:
|
||||||
|
keyboard_input_changed.emit(action, input)
|
||||||
|
|
||||||
|
|
||||||
|
## Set the key or button for an action
|
||||||
|
func set_keyboard_or_joypad_input_for_action(action: String, event: InputEvent, swap_if_taken: bool = true) -> void:
|
||||||
|
if event is InputEventKey or event is InputEventMouse:
|
||||||
|
set_keyboard_input_for_action(action, event, swap_if_taken)
|
||||||
|
elif event is InputEventJoypadButton:
|
||||||
|
set_joypad_input_for_action(action, event, swap_if_taken)
|
||||||
|
|
||||||
|
|
||||||
|
## Get the key or button for a given action depending on the current device
|
||||||
|
func get_keyboard_or_joypad_input_for_action(action: String) -> InputEvent:
|
||||||
|
if device == DEVICE_KEYBOARD:
|
||||||
|
return get_keyboard_input_for_action(action)
|
||||||
|
else:
|
||||||
|
return get_joypad_input_for_action(action)
|
||||||
|
|
||||||
|
|
||||||
|
## Get the key or button for a given action depending on the current device
|
||||||
|
func get_keyboard_or_joypad_inputs_for_action(action: String) -> Array[InputEvent]:
|
||||||
|
if device == DEVICE_KEYBOARD:
|
||||||
|
return get_keyboard_inputs_for_action(action)
|
||||||
|
else:
|
||||||
|
return get_joypad_inputs_for_action(action)
|
||||||
|
|
||||||
|
|
||||||
|
## Get a text label for a given input
|
||||||
|
func get_label_for_input(input: InputEvent) -> String:
|
||||||
|
if input == null: return ""
|
||||||
|
|
||||||
|
if input is InputEventKey:
|
||||||
|
if input.physical_keycode > 0 :
|
||||||
|
var keycode: Key = DisplayServer.keyboard_get_keycode_from_physical(input.physical_keycode) if DisplayServer.keyboard_get_current_layout() > -1 else input.physical_keycode
|
||||||
|
return OS.get_keycode_string(keycode)
|
||||||
|
elif input.keycode > 0:
|
||||||
|
return OS.get_keycode_string(input.keycode)
|
||||||
|
else:
|
||||||
|
return input.as_text()
|
||||||
|
|
||||||
|
elif input is InputEventMouseButton:
|
||||||
|
match input.button_index:
|
||||||
|
MOUSE_BUTTON_LEFT:
|
||||||
|
return "Mouse Left Button"
|
||||||
|
MOUSE_BUTTON_MIDDLE:
|
||||||
|
return "Mouse Middle Button"
|
||||||
|
MOUSE_BUTTON_RIGHT:
|
||||||
|
return "Mouse Right Button"
|
||||||
|
return "Mouse Button %d" % input.button_index
|
||||||
|
|
||||||
|
elif input is InputEventJoypadButton:
|
||||||
|
var labels = []
|
||||||
|
match _last_known_granular_joypad_device:
|
||||||
|
DEVICE_XBOX_CONTROLLER, DEVICE_GENERIC:
|
||||||
|
labels = XBOX_BUTTON_LABELS
|
||||||
|
SUB_DEVICE_XBOX_ONE_CONTROLLER:
|
||||||
|
labels = XBOX_ONE_BUTTON_LABELS
|
||||||
|
SUB_DEVICE_XBOX_SERIES_CONTROLLER:
|
||||||
|
labels = XBOX_SERIES_BUTTON_LABELS
|
||||||
|
SUB_DEVICE_SWITCH_JOYCON_LEFT_CONTROLLER, SUB_DEVICE_SWITCH_JOYCON_RIGHT_CONTROLLER:
|
||||||
|
labels = SWITCH_BUTTON_LABELS
|
||||||
|
DEVICE_SWITCH_CONTROLLER:
|
||||||
|
labels = SWITCH_EXTENDED_GAMEPAD_BUTTON_LABELS
|
||||||
|
SUB_DEVICE_PLAYSTATION3_CONTROLLER, SUB_DEVICE_PLAYSTATION4_CONTROLLER:
|
||||||
|
labels = PLAYSTATION_3_4_BUTTON_LABELS
|
||||||
|
DEVICE_PLAYSTATION_CONTROLLER, SUB_DEVICE_PLAYSTATION5_CONTROLLER:
|
||||||
|
labels = PLAYSTATION_5_BUTTON_LABELS
|
||||||
|
DEVICE_STEAMDECK_CONTROLLER:
|
||||||
|
labels = STEAMDECK_BUTTON_LABELS
|
||||||
|
if input.button_index < labels.size():
|
||||||
|
return "%s Button" % labels[input.button_index]
|
||||||
|
else:
|
||||||
|
return "Button %d" % input.button_index
|
||||||
|
|
||||||
|
elif input is InputEventJoypadMotion:
|
||||||
|
var motion: InputEventJoypadMotion = input as InputEventJoypadMotion
|
||||||
|
match motion.axis:
|
||||||
|
JOY_AXIS_LEFT_X:
|
||||||
|
return "Left Stick %s" % ("Left" if motion.axis_value < 0 else "Right")
|
||||||
|
JOY_AXIS_LEFT_Y:
|
||||||
|
return "Left Stick %s" % ("Up" if motion.axis_value < 0 else "Down")
|
||||||
|
JOY_AXIS_RIGHT_X:
|
||||||
|
return "Right Stick %s" % ("Left" if motion.axis_value < 0 else "Right")
|
||||||
|
JOY_AXIS_RIGHT_Y:
|
||||||
|
return "Right Stick %s" % ("Up" if motion.axis_value < 0 else "Down")
|
||||||
|
JOY_AXIS_TRIGGER_LEFT:
|
||||||
|
return "Left Trigger"
|
||||||
|
JOY_AXIS_TRIGGER_RIGHT:
|
||||||
|
return "Right Trigger"
|
||||||
|
|
||||||
|
return input.as_text()
|
||||||
|
|
||||||
|
|
||||||
|
## Serialize a single action's inputs.
|
||||||
|
func serialize_inputs_for_action(action: StringName) -> String:
|
||||||
|
var action_inputs: PackedStringArray = []
|
||||||
|
var inputs: Array[InputEvent] = InputMap.action_get_events(action)
|
||||||
|
for input in inputs:
|
||||||
|
if input is InputEventKey:
|
||||||
|
var s: String = get_label_for_input(input)
|
||||||
|
var modifiers: Array[String] = []
|
||||||
|
if input.alt_pressed:
|
||||||
|
modifiers.append("alt")
|
||||||
|
if input.shift_pressed:
|
||||||
|
modifiers.append("shift")
|
||||||
|
if input.ctrl_pressed:
|
||||||
|
modifiers.append("ctrl")
|
||||||
|
if input.meta_pressed:
|
||||||
|
modifiers.append("meta")
|
||||||
|
if not modifiers.is_empty():
|
||||||
|
s += "|" + ",".join(modifiers)
|
||||||
|
action_inputs.append("key:%s" % s)
|
||||||
|
elif input is InputEventMouseButton:
|
||||||
|
action_inputs.append("mouse:%d" % input.button_index)
|
||||||
|
elif input is InputEventJoypadButton:
|
||||||
|
action_inputs.append("joypad:%d" % input.button_index)
|
||||||
|
elif input is InputEventJoypadMotion:
|
||||||
|
action_inputs.append("joypad:%d|%f" % [input.axis, input.axis_value])
|
||||||
|
|
||||||
|
return ";".join(action_inputs)
|
||||||
|
|
||||||
|
|
||||||
|
## Serialize a list of action inputs to string. If actions is empty then it will serialize
|
||||||
|
## all actions.
|
||||||
|
func serialize_inputs_for_actions(actions: PackedStringArray = []) -> String:
|
||||||
|
if actions == null or actions.is_empty():
|
||||||
|
actions = InputMap.get_actions()
|
||||||
|
|
||||||
|
var map: Dictionary = {}
|
||||||
|
for action in actions:
|
||||||
|
map[action] = serialize_inputs_for_action(action)
|
||||||
|
|
||||||
|
return JSON.stringify({
|
||||||
|
version = SERIAL_VERSION,
|
||||||
|
map = map
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
## Deserialize a single action's inputs.
|
||||||
|
func deserialize_inputs_for_action(action: String, string: String) -> void:
|
||||||
|
InputMap.action_erase_events(action)
|
||||||
|
var action_inputs: PackedStringArray = string.split(";")
|
||||||
|
for action_input in action_inputs:
|
||||||
|
var bits: PackedStringArray = action_input.split(":")
|
||||||
|
|
||||||
|
# Ignore any empty actions
|
||||||
|
if bits.size() < 2: continue
|
||||||
|
|
||||||
|
var input_type: String = bits[0]
|
||||||
|
var input_details: String = bits[1]
|
||||||
|
|
||||||
|
match input_type:
|
||||||
|
"key":
|
||||||
|
var keyboard_input = InputEventKey.new()
|
||||||
|
if "|" in input_details:
|
||||||
|
var detail_bits = input_details.split("|")
|
||||||
|
keyboard_input.keycode = OS.find_keycode_from_string(detail_bits[0])
|
||||||
|
detail_bits = detail_bits[1].split(",")
|
||||||
|
if detail_bits.has("alt"):
|
||||||
|
keyboard_input.alt_pressed = true
|
||||||
|
if detail_bits.has("shift"):
|
||||||
|
keyboard_input.shift_pressed = true
|
||||||
|
if detail_bits.has("ctrl"):
|
||||||
|
keyboard_input.ctrl_pressed = true
|
||||||
|
if detail_bits.has("meta"):
|
||||||
|
keyboard_input.meta_pressed = true
|
||||||
|
else:
|
||||||
|
keyboard_input.keycode = OS.find_keycode_from_string(input_details)
|
||||||
|
InputMap.action_add_event(action, keyboard_input)
|
||||||
|
keyboard_input_changed.emit(action, keyboard_input)
|
||||||
|
|
||||||
|
"mouse":
|
||||||
|
var mouse_input = InputEventMouseButton.new()
|
||||||
|
mouse_input.button_index = int(input_details)
|
||||||
|
InputMap.action_add_event(action, mouse_input)
|
||||||
|
keyboard_input_changed.emit(action, mouse_input)
|
||||||
|
|
||||||
|
"joypad":
|
||||||
|
if "|" in str(input_details):
|
||||||
|
var joypad_motion_input = InputEventJoypadMotion.new()
|
||||||
|
var joypad_bits = input_details.split("|")
|
||||||
|
joypad_motion_input.axis = int(joypad_bits[0])
|
||||||
|
joypad_motion_input.axis_value = float(joypad_bits[1])
|
||||||
|
InputMap.action_add_event(action, joypad_motion_input)
|
||||||
|
joypad_input_changed.emit(action, joypad_motion_input)
|
||||||
|
else:
|
||||||
|
var joypad_input = InputEventJoypadButton.new()
|
||||||
|
joypad_input.button_index = int(input_details)
|
||||||
|
InputMap.action_add_event(action, joypad_input)
|
||||||
|
joypad_input_changed.emit(action, joypad_input)
|
||||||
|
|
||||||
|
|
||||||
|
## Deserialise a list of actions' inputs.
|
||||||
|
func deserialize_inputs_for_actions(string: String) -> void:
|
||||||
|
var data: Dictionary = JSON.parse_string(string)
|
||||||
|
|
||||||
|
# Use legacy deserialization
|
||||||
|
if not data.has("version"):
|
||||||
|
_deprecated_deserialize_inputs_for_actions(string)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Version 1
|
||||||
|
for action in data.map.keys():
|
||||||
|
deserialize_inputs_for_action(action, data.map[action])
|
||||||
|
|
||||||
|
|
||||||
|
# Load inputs from a serialized string. [deprecated]
|
||||||
|
func _deprecated_deserialize_inputs_for_actions(string: String) -> void:
|
||||||
|
var map: Dictionary = JSON.parse_string(string)
|
||||||
|
for action in map.keys():
|
||||||
|
InputMap.action_erase_events(action)
|
||||||
|
|
||||||
|
for key in map[action]["keyboard"]:
|
||||||
|
var keyboard_input = InputEventKey.new()
|
||||||
|
if "|" in key:
|
||||||
|
var bits = key.split("|")
|
||||||
|
keyboard_input.keycode = OS.find_keycode_from_string(bits[0])
|
||||||
|
bits = bits[1].split(",")
|
||||||
|
if bits.has("alt"):
|
||||||
|
keyboard_input.alt_pressed = true
|
||||||
|
if bits.has("shift"):
|
||||||
|
keyboard_input.shift_pressed = true
|
||||||
|
if bits.has("ctrl"):
|
||||||
|
keyboard_input.ctrl_pressed = true
|
||||||
|
if bits.has("meta"):
|
||||||
|
keyboard_input.meta_pressed = true
|
||||||
|
else:
|
||||||
|
keyboard_input.keycode = OS.find_keycode_from_string(key)
|
||||||
|
InputMap.action_add_event(action, keyboard_input)
|
||||||
|
|
||||||
|
for button_index in map[action]["mouse"]:
|
||||||
|
var mouse_input = InputEventMouseButton.new()
|
||||||
|
mouse_input.button_index = int(button_index)
|
||||||
|
InputMap.action_add_event(action, mouse_input)
|
||||||
|
|
||||||
|
for button_index_or_motion in map[action]["joypad"]:
|
||||||
|
if "|" in str(button_index_or_motion):
|
||||||
|
var joypad_motion_input = InputEventJoypadMotion.new()
|
||||||
|
var bits = button_index_or_motion.split("|")
|
||||||
|
joypad_motion_input.axis = int(bits[0])
|
||||||
|
joypad_motion_input.axis_value = float(bits[1])
|
||||||
|
InputMap.action_add_event(action, joypad_motion_input)
|
||||||
|
else:
|
||||||
|
var joypad_input = InputEventJoypadButton.new()
|
||||||
|
joypad_input.button_index = int(button_index_or_motion)
|
||||||
|
InputMap.action_add_event(action, joypad_input)
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Keyboard/mouse input
|
||||||
|
|
||||||
|
|
||||||
|
## Get all of the keys/mouse buttons used for an action.
|
||||||
|
func get_keyboard_inputs_for_action(action: String) -> Array[InputEvent]:
|
||||||
|
return InputMap.action_get_events(action).filter(func(event):
|
||||||
|
return event is InputEventKey or event is InputEventMouseButton
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
## Get the first key for an action
|
||||||
|
func get_keyboard_input_for_action(action: String) -> InputEvent:
|
||||||
|
var inputs: Array[InputEvent] = get_keyboard_inputs_for_action(action)
|
||||||
|
return null if inputs.is_empty() else inputs[0]
|
||||||
|
|
||||||
|
|
||||||
|
## Set the key used for an action
|
||||||
|
func set_keyboard_input_for_action(action: String, input: InputEvent, swap_if_taken: bool = true) -> Error:
|
||||||
|
return _update_keyboard_input_for_action(action, input, swap_if_taken, null)
|
||||||
|
|
||||||
|
|
||||||
|
## Replace a specific key with another key
|
||||||
|
func replace_keyboard_input_for_action(action: String, current_input: InputEvent, input: InputEvent, swap_if_taken: bool = true) -> Error:
|
||||||
|
return _update_keyboard_input_for_action(action, input, swap_if_taken, current_input)
|
||||||
|
|
||||||
|
|
||||||
|
## Replace a specific key, given its index
|
||||||
|
func replace_keyboard_input_at_index(action: String, index: int, input: InputEvent, swap_if_taken: bool = true) -> Error:
|
||||||
|
var inputs: Array[InputEvent] = get_keyboard_inputs_for_action(action)
|
||||||
|
var replacing_input = InputEventKey.new() if (inputs.is_empty() or inputs.size() <= index) else inputs[index]
|
||||||
|
return _update_keyboard_input_for_action(action, input, swap_if_taken, replacing_input)
|
||||||
|
|
||||||
|
|
||||||
|
func _update_keyboard_input_for_action(action: String, input: InputEvent, swap_if_taken: bool, replacing_input: InputEvent = null) -> Error:
|
||||||
|
if not (input is InputEventKey or input is InputEventMouseButton): return ERR_INVALID_DATA
|
||||||
|
|
||||||
|
var is_valid_keyboard_event = func(event):
|
||||||
|
return event is InputEventKey or event is InputEventMouseButton
|
||||||
|
|
||||||
|
return _update_input_for_action(action, input, swap_if_taken, replacing_input, is_valid_keyboard_event, keyboard_input_changed)
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Joypad input
|
||||||
|
|
||||||
|
|
||||||
|
## Get all buttons used for an action
|
||||||
|
func get_joypad_inputs_for_action(action: String) -> Array[InputEvent]:
|
||||||
|
return InputMap.action_get_events(action).filter(func(event):
|
||||||
|
return event is InputEventJoypadButton or event is InputEventJoypadMotion
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
## Get the first button for an action
|
||||||
|
func get_joypad_input_for_action(action: String) -> InputEvent:
|
||||||
|
var buttons: Array[InputEvent] = get_joypad_inputs_for_action(action)
|
||||||
|
return null if buttons.is_empty() else buttons[0]
|
||||||
|
|
||||||
|
|
||||||
|
## Set the button for an action
|
||||||
|
func set_joypad_input_for_action(action: String, input: InputEvent, swap_if_taken: bool = true) -> Error:
|
||||||
|
return _update_joypad_input_for_action(action, input, swap_if_taken, null)
|
||||||
|
|
||||||
|
|
||||||
|
## Replace a specific button for an action
|
||||||
|
func replace_joypad_input_for_action(action: String, current_input: InputEvent, input: InputEventJoypadButton, swap_if_taken: bool = true) -> Error:
|
||||||
|
return _update_joypad_input_for_action(action, input, swap_if_taken, current_input)
|
||||||
|
|
||||||
|
|
||||||
|
## Replace a button, given its index
|
||||||
|
func replace_joypad_input_at_index(action: String, index: int, input: InputEvent, swap_if_taken: bool = true) -> Error:
|
||||||
|
var inputs: Array[InputEvent] = get_joypad_inputs_for_action(action)
|
||||||
|
var replacing_input
|
||||||
|
if inputs.is_empty() or inputs.size() <= index:
|
||||||
|
replacing_input = InputEventJoypadButton.new()
|
||||||
|
replacing_input.button_index = JOY_BUTTON_INVALID
|
||||||
|
else:
|
||||||
|
replacing_input = inputs[index]
|
||||||
|
return _update_joypad_input_for_action(action, input, swap_if_taken, replacing_input)
|
||||||
|
|
||||||
|
|
||||||
|
## Set the action used for a button
|
||||||
|
func _update_joypad_input_for_action(action: String, input: InputEvent, swap_if_taken: bool = true, replacing_input: InputEvent = null) -> Error:
|
||||||
|
var is_valid_keyboard_event = func(event):
|
||||||
|
return event is InputEventJoypadButton or event is InputEventJoypadMotion
|
||||||
|
|
||||||
|
return _update_input_for_action(action, input, swap_if_taken, replacing_input, is_valid_keyboard_event, joypad_input_changed)
|
||||||
|
|
||||||
|
|
||||||
|
func _update_input_for_action(action: String, input: InputEvent, swap_if_taken: bool, replacing_input: InputEvent, check_is_valid: Callable, did_change_signal: Signal) -> Error:
|
||||||
|
# Find any action that is already mapped to this input
|
||||||
|
var clashing_action = ""
|
||||||
|
var clashing_event
|
||||||
|
if swap_if_taken:
|
||||||
|
for other_action in InputMap.get_actions():
|
||||||
|
if other_action == action: continue
|
||||||
|
|
||||||
|
for event in InputMap.action_get_events(other_action):
|
||||||
|
if event.is_match(input):
|
||||||
|
clashing_action = other_action
|
||||||
|
clashing_event = event
|
||||||
|
|
||||||
|
# Find the key based event for the target action
|
||||||
|
var action_events: Array[InputEvent] = InputMap.action_get_events(action)
|
||||||
|
var is_replacing: bool = false
|
||||||
|
for i in range(0, action_events.size()):
|
||||||
|
var event: InputEvent = action_events[i]
|
||||||
|
if check_is_valid.call(event):
|
||||||
|
if replacing_input != null and not event.is_match(replacing_input):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Remap the other event if there is a clashing one
|
||||||
|
if clashing_action:
|
||||||
|
_update_input_for_action(clashing_action, event, false, clashing_event, check_is_valid, did_change_signal)
|
||||||
|
|
||||||
|
# Replace the event
|
||||||
|
action_events[i] = input
|
||||||
|
is_replacing = true
|
||||||
|
break
|
||||||
|
|
||||||
|
# If we were trying to replace something but didn't find it then just add it to the end
|
||||||
|
if not is_replacing:
|
||||||
|
action_events.append(input)
|
||||||
|
|
||||||
|
# Apply the changes
|
||||||
|
InputMap.action_erase_events(action)
|
||||||
|
for event in action_events:
|
||||||
|
if event != null:
|
||||||
|
InputMap.action_add_event(action, event)
|
||||||
|
|
||||||
|
did_change_signal.emit(action, input)
|
||||||
|
|
||||||
|
return OK
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Rumbling
|
||||||
|
|
||||||
|
|
||||||
|
func rumble_small(target_device: int = 0) -> void:
|
||||||
|
Input.start_joy_vibration(target_device, 0.4, 0, 0.1)
|
||||||
|
|
||||||
|
|
||||||
|
func rumble_medium(target_device: int = 0) -> void:
|
||||||
|
Input.start_joy_vibration(target_device, 0, 0.7, 0.1)
|
||||||
|
|
||||||
|
|
||||||
|
func rumble_large(target_device: int = 0) -> void:
|
||||||
|
Input.start_joy_vibration(target_device, 0, 1, 0.1)
|
||||||
|
|
||||||
|
|
||||||
|
func start_rumble_small(target_device: int = 0) -> void:
|
||||||
|
Input.start_joy_vibration(target_device, 0.4, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
func start_rumble_medium(target_device: int = 0) -> void:
|
||||||
|
Input.start_joy_vibration(target_device, 0, 0.7, 0)
|
||||||
|
|
||||||
|
|
||||||
|
func start_rumble_large(target_device: int = 0) -> void:
|
||||||
|
Input.start_joy_vibration(target_device, 0, 1, 0)
|
||||||
|
|
||||||
|
|
||||||
|
func stop_rumble(target_device: int = 0) -> void:
|
||||||
|
Input.stop_joy_vibration(target_device)
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://cholww48njaeh
|
||||||
7
Zennysoft.Game.Ma/addons/input_helper/plugin.cfg
Normal file
7
Zennysoft.Game.Ma/addons/input_helper/plugin.cfg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[plugin]
|
||||||
|
|
||||||
|
name="Input Helper"
|
||||||
|
description="Detect which input device the player is using and manage input actions"
|
||||||
|
author="Nathan Hoad"
|
||||||
|
version="4.7.0"
|
||||||
|
script="plugin.gd"
|
||||||
112
Zennysoft.Game.Ma/addons/input_helper/plugin.gd
Normal file
112
Zennysoft.Game.Ma/addons/input_helper/plugin.gd
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
@tool
|
||||||
|
extends EditorPlugin
|
||||||
|
|
||||||
|
|
||||||
|
const REMOTE_RELEASES_URL = "https://api.github.com/repos/nathanhoad/godot_input_helper/releases"
|
||||||
|
const LOCAL_CONFIG_PATH = "res://addons/input_helper/plugin.cfg"
|
||||||
|
|
||||||
|
const DownloadDialogScene = preload("res://addons/input_helper/views/download_dialog.tscn")
|
||||||
|
|
||||||
|
|
||||||
|
var http_request: HTTPRequest = HTTPRequest.new()
|
||||||
|
var next_version: String = ""
|
||||||
|
|
||||||
|
|
||||||
|
func _enter_tree():
|
||||||
|
add_autoload_singleton("InputHelper", "res://addons/input_helper/input_helper.gd")
|
||||||
|
|
||||||
|
# Configure settings
|
||||||
|
InputHelperSettings.prepare()
|
||||||
|
|
||||||
|
# Check for updates on GitHub
|
||||||
|
get_editor_interface().get_base_control().add_child(http_request)
|
||||||
|
http_request.request_completed.connect(_on_http_request_request_completed)
|
||||||
|
http_request.request(REMOTE_RELEASES_URL)
|
||||||
|
|
||||||
|
|
||||||
|
func _exit_tree():
|
||||||
|
remove_autoload_singleton("InputHelper")
|
||||||
|
|
||||||
|
if next_version != "":
|
||||||
|
remove_tool_menu_item("Update Input Helper to v%s" % next_version)
|
||||||
|
|
||||||
|
|
||||||
|
# Get the current version
|
||||||
|
func get_version() -> String:
|
||||||
|
var config: ConfigFile = ConfigFile.new()
|
||||||
|
config.load(LOCAL_CONFIG_PATH)
|
||||||
|
return config.get_value("plugin", "version")
|
||||||
|
|
||||||
|
|
||||||
|
# Convert a version number to an actually comparable number
|
||||||
|
func version_to_number(version: String) -> int:
|
||||||
|
var bits = version.split(".")
|
||||||
|
return bits[0].to_int() * 1000000 + bits[1].to_int() * 1000 + bits[2].to_int()
|
||||||
|
|
||||||
|
|
||||||
|
### Signals
|
||||||
|
|
||||||
|
|
||||||
|
func _on_http_request_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||||
|
http_request.queue_free()
|
||||||
|
|
||||||
|
if result != HTTPRequest.RESULT_SUCCESS: return
|
||||||
|
|
||||||
|
var current_version: String = get_version()
|
||||||
|
|
||||||
|
# Work out the next version from the releases information on GitHub
|
||||||
|
var response = JSON.parse_string(body.get_string_from_utf8())
|
||||||
|
if typeof(response) != TYPE_ARRAY: return
|
||||||
|
|
||||||
|
# GitHub releases are in order of creation, not order of version
|
||||||
|
var versions = (response as Array).filter(func(release):
|
||||||
|
var version: String = release.tag_name.substr(1)
|
||||||
|
return version_to_number(version) > version_to_number(current_version)
|
||||||
|
)
|
||||||
|
if versions.size() > 0:
|
||||||
|
next_version = versions[0].tag_name.substr(1)
|
||||||
|
add_tool_menu_item("Update Input Helper to v%s" % next_version, _update_input_helper)
|
||||||
|
|
||||||
|
|
||||||
|
func _update_input_helper() -> void:
|
||||||
|
var download_dialog := DownloadDialogScene.instantiate()
|
||||||
|
download_dialog.next_version = next_version
|
||||||
|
|
||||||
|
var scale: float = get_editor_interface().get_editor_scale()
|
||||||
|
download_dialog.min_size = Vector2(300, 250) * scale
|
||||||
|
|
||||||
|
download_dialog.update_finished.connect(_on_download_dialog_update_finished)
|
||||||
|
download_dialog.update_failed.connect(_on_download_dialog_update_failed)
|
||||||
|
|
||||||
|
get_editor_interface().get_base_control().add_child(download_dialog)
|
||||||
|
download_dialog.show()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_download_dialog_update_finished() -> void:
|
||||||
|
remove_tool_menu_item("Update Input Helper to v%s" % next_version)
|
||||||
|
|
||||||
|
get_editor_interface().get_resource_filesystem().scan()
|
||||||
|
|
||||||
|
print_rich("\n[b]Updated Input Helper to v%s[/b]\n" % next_version)
|
||||||
|
|
||||||
|
var finished_dialog: AcceptDialog = AcceptDialog.new()
|
||||||
|
finished_dialog.dialog_text = "Your Input Helper is now up to date."
|
||||||
|
|
||||||
|
var restart_addon = func():
|
||||||
|
finished_dialog.queue_free()
|
||||||
|
get_editor_interface().call_deferred("set_plugin_enabled", "input_helper", true)
|
||||||
|
get_editor_interface().set_plugin_enabled("input_helper", false)
|
||||||
|
|
||||||
|
finished_dialog.canceled.connect(restart_addon)
|
||||||
|
finished_dialog.confirmed.connect(restart_addon)
|
||||||
|
get_editor_interface().get_base_control().add_child(finished_dialog)
|
||||||
|
finished_dialog.popup_centered()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_download_dialog_update_failed() -> void:
|
||||||
|
var failed_dialog: AcceptDialog = AcceptDialog.new()
|
||||||
|
failed_dialog.dialog_text = "There was a problem downloading the update."
|
||||||
|
failed_dialog.canceled.connect(func(): failed_dialog.queue_free())
|
||||||
|
failed_dialog.confirmed.connect(func(): failed_dialog.queue_free())
|
||||||
|
get_editor_interface().get_base_control().add_child(failed_dialog)
|
||||||
|
failed_dialog.popup_centered()
|
||||||
1
Zennysoft.Game.Ma/addons/input_helper/plugin.gd.uid
Normal file
1
Zennysoft.Game.Ma/addons/input_helper/plugin.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cul6evy00vr55
|
||||||
42
Zennysoft.Game.Ma/addons/input_helper/settings.gd
Normal file
42
Zennysoft.Game.Ma/addons/input_helper/settings.gd
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
class_name InputHelperSettings extends Node
|
||||||
|
|
||||||
|
const USE_GRANULAR_DEVICE_IDENTIFIERS = "devices/use_granular_device_identifiers"
|
||||||
|
|
||||||
|
const SETTINGS_CONFIGURATION = {
|
||||||
|
USE_GRANULAR_DEVICE_IDENTIFIERS: {
|
||||||
|
value = false,
|
||||||
|
type = TYPE_BOOL,
|
||||||
|
is_advanced = true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static func prepare() -> void:
|
||||||
|
for key: String in SETTINGS_CONFIGURATION:
|
||||||
|
var setting_config: Dictionary = SETTINGS_CONFIGURATION[key]
|
||||||
|
var setting_name: String = "input_helper/%s" % key
|
||||||
|
if not ProjectSettings.has_setting(setting_name):
|
||||||
|
ProjectSettings.set_setting(setting_name, setting_config.value)
|
||||||
|
ProjectSettings.set_initial_value(setting_name, setting_config.value)
|
||||||
|
ProjectSettings.add_property_info({
|
||||||
|
"name" = setting_name,
|
||||||
|
"type" = setting_config.type,
|
||||||
|
"hint" = setting_config.get("hint", PROPERTY_HINT_NONE),
|
||||||
|
"hint_string" = setting_config.get("hint_string", "")
|
||||||
|
})
|
||||||
|
ProjectSettings.set_as_basic(setting_name, not setting_config.has("is_advanced"))
|
||||||
|
ProjectSettings.set_as_internal(setting_name, setting_config.has("is_hidden"))
|
||||||
|
|
||||||
|
|
||||||
|
static func set_setting(key: String, value) -> void:
|
||||||
|
if get_setting(key, value) != value:
|
||||||
|
ProjectSettings.set_setting("input_helper/%s" % key, value)
|
||||||
|
ProjectSettings.set_initial_value("input_helper/%s" % key, SETTINGS_CONFIGURATION[key].value)
|
||||||
|
ProjectSettings.save()
|
||||||
|
|
||||||
|
|
||||||
|
static func get_setting(key: String, default):
|
||||||
|
if ProjectSettings.has_setting("input_helper/%s" % key):
|
||||||
|
return ProjectSettings.get_setting("input_helper/%s" % key)
|
||||||
|
else:
|
||||||
|
return default
|
||||||
1
Zennysoft.Game.Ma/addons/input_helper/settings.gd.uid
Normal file
1
Zennysoft.Game.Ma/addons/input_helper/settings.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://yqplm6a6focp
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
@tool
|
||||||
|
|
||||||
|
extends AcceptDialog
|
||||||
|
|
||||||
|
|
||||||
|
signal update_finished()
|
||||||
|
signal update_failed()
|
||||||
|
|
||||||
|
|
||||||
|
@onready var download_update_panel := $DownloadUpdatePanel
|
||||||
|
|
||||||
|
|
||||||
|
var next_version: String
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
download_update_panel.next_version = next_version
|
||||||
|
|
||||||
|
|
||||||
|
### Signals
|
||||||
|
|
||||||
|
|
||||||
|
func _on_download_update_panel_updated(updated_to_version) -> void:
|
||||||
|
update_finished.emit()
|
||||||
|
queue_free()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_download_update_panel_failed() -> void:
|
||||||
|
update_failed.emit()
|
||||||
|
queue_free()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://1t3qhgrro2es
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://bownbkcmm43gn"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://b7mst0qu7vjk1" path="res://addons/input_helper/components/download_update_panel.tscn" id="1_37q37"]
|
||||||
|
[ext_resource type="Script" uid="uid://1t3qhgrro2es" path="res://addons/input_helper/views/download_dialog.gd" id="1_ltktf"]
|
||||||
|
|
||||||
|
[node name="DownloadDialog" type="AcceptDialog"]
|
||||||
|
initial_position = 2
|
||||||
|
ok_button_text = "Close"
|
||||||
|
script = ExtResource("1_ltktf")
|
||||||
|
|
||||||
|
[node name="DownloadUpdatePanel" parent="." instance=ExtResource("1_37q37")]
|
||||||
|
|
||||||
|
[connection signal="failed" from="DownloadUpdatePanel" to="." method="_on_download_update_panel_failed"]
|
||||||
|
[connection signal="updated" from="DownloadUpdatePanel" to="." method="_on_download_update_panel_updated"]
|
||||||
@@ -1,7 +1,26 @@
|
|||||||
[gd_resource type="AudioBusLayout" format=3 uid="uid://c2mk6c27y0mdf"]
|
[gd_resource type="AudioBusLayout" load_steps=4 format=3 uid="uid://c2mk6c27y0mdf"]
|
||||||
|
|
||||||
|
[sub_resource type="AudioEffectLimiter" id="AudioEffectLimiter_j3pel"]
|
||||||
|
resource_name = "Limiter"
|
||||||
|
soft_clip_db = 1.0
|
||||||
|
|
||||||
|
[sub_resource type="AudioEffectReverb" id="AudioEffectReverb_j3pel"]
|
||||||
|
resource_name = "Reverb"
|
||||||
|
room_size = 0.5
|
||||||
|
damping = 0.9
|
||||||
|
dry = 0.99
|
||||||
|
wet = 0.05
|
||||||
|
|
||||||
|
[sub_resource type="AudioEffectLimiter" id="AudioEffectLimiter_g28q7"]
|
||||||
|
resource_name = "Limiter"
|
||||||
|
ceiling_db = -0.5
|
||||||
|
threshold_db = -0.6
|
||||||
|
soft_clip_db = 1.5
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
bus/0/volume_db = -0.130497
|
bus/0/volume_db = -0.130497
|
||||||
|
bus/0/effect/0/effect = SubResource("AudioEffectLimiter_j3pel")
|
||||||
|
bus/0/effect/0/enabled = true
|
||||||
bus/1/name = &"AMBIENT"
|
bus/1/name = &"AMBIENT"
|
||||||
bus/1/solo = false
|
bus/1/solo = false
|
||||||
bus/1/mute = false
|
bus/1/mute = false
|
||||||
@@ -14,6 +33,10 @@ bus/2/mute = false
|
|||||||
bus/2/bypass_fx = false
|
bus/2/bypass_fx = false
|
||||||
bus/2/volume_db = 0.0
|
bus/2/volume_db = 0.0
|
||||||
bus/2/send = &"Master"
|
bus/2/send = &"Master"
|
||||||
|
bus/2/effect/0/effect = SubResource("AudioEffectReverb_j3pel")
|
||||||
|
bus/2/effect/0/enabled = true
|
||||||
|
bus/2/effect/1/effect = SubResource("AudioEffectLimiter_g28q7")
|
||||||
|
bus/2/effect/1/enabled = true
|
||||||
bus/3/name = &"MUSIC"
|
bus/3/name = &"MUSIC"
|
||||||
bus/3/solo = false
|
bus/3/solo = false
|
||||||
bus/3/mute = false
|
bus/3/mute = false
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ DialogueManager="*res://addons/dialogue_manager/dialogue_manager.gd"
|
|||||||
DialogueController="*res://src/game/DialogueController.cs"
|
DialogueController="*res://src/game/DialogueController.cs"
|
||||||
AudioManager="*res://src/audio/AudioManager.cs"
|
AudioManager="*res://src/audio/AudioManager.cs"
|
||||||
BgmPlayer="*res://src/audio/BGMPlayer.cs"
|
BgmPlayer="*res://src/audio/BGMPlayer.cs"
|
||||||
|
InputHelper="*res://addons/input_helper/input_helper.gd"
|
||||||
|
SfxDatabase="*res://src/audio/SFXDatabase.tscn"
|
||||||
|
|
||||||
[dialogue_manager]
|
[dialogue_manager]
|
||||||
|
|
||||||
@@ -34,8 +36,7 @@ runtime/advanced/uses_dotnet=true
|
|||||||
|
|
||||||
window/size/viewport_width=1920
|
window/size/viewport_width=1920
|
||||||
window/size/viewport_height=1080
|
window/size/viewport_height=1080
|
||||||
window/stretch/mode="viewport"
|
window/stretch/mode="canvas_items"
|
||||||
window/stretch/aspect="expand"
|
|
||||||
|
|
||||||
[dotnet]
|
[dotnet]
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ project/assembly_name="Ma"
|
|||||||
|
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
enabled=PackedStringArray("res://addons/dialogue_manager/plugin.cfg", "res://addons/dungeon_floor_layout/plugin.cfg", "res://addons/special_floor_layout_node/plugin.cfg")
|
enabled=PackedStringArray("res://addons/dialogue_manager/plugin.cfg", "res://addons/input_helper/plugin.cfg")
|
||||||
|
|
||||||
[file_customization]
|
[file_customization]
|
||||||
|
|
||||||
@@ -72,9 +73,7 @@ texture={
|
|||||||
ui_accept={
|
ui_accept={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
|
||||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null)
|
||||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":3,"pressure":0.0,"pressed":false,"script":null)
|
|
||||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
ui_select={
|
ui_select={
|
||||||
@@ -83,58 +82,69 @@ ui_select={
|
|||||||
}
|
}
|
||||||
ui_cancel={
|
ui_cancel={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194305,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null)
|
||||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
||||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
|
|
||||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null)
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
ui_focus_next={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": []
|
||||||
|
}
|
||||||
|
ui_focus_prev={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": []
|
||||||
|
}
|
||||||
ui_left={
|
ui_left={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
ui_right={
|
ui_right={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
ui_up={
|
ui_up={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
ui_down={
|
ui_down={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
MoveUp={
|
MoveUp={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
|
||||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
|
||||||
|
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
MoveLeft={
|
MoveLeft={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
|
||||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||||
|
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
MoveRight={
|
MoveRight={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
|
||||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
|
||||||
|
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
MoveDown={
|
MoveDown={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
|
||||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||||
|
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Attack={
|
Attack={
|
||||||
@@ -218,10 +228,30 @@ AltAttack={
|
|||||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
CameraForward={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
CameraBack={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
EnemyViewerIdle={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
EnemyViewerWalk={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
[internationalization]
|
[internationalization]
|
||||||
|
|
||||||
locale/translations_pot_files=PackedStringArray("res://src/dialog/Dialogue.dialogue", "res://src/npc/Ran/ran.dialogue", "res://src/npc/Rat/ratdialogue.dialogue")
|
locale/translations_pot_files=PackedStringArray("res://src/dialog/Dialogue.dialogue", "res://src/npc/Ran/ran.dialogue", "res://src/npc/Rat/ratdialogue.dialogue", "res://src/dialog/Altar.dialogue")
|
||||||
|
|
||||||
[layer_names]
|
[layer_names]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using Chickensoft.Collections;
|
using Chickensoft.Collections;
|
||||||
|
using Godot;
|
||||||
|
using System;
|
||||||
using Zennysoft.Ma.Adapter;
|
using Zennysoft.Ma.Adapter;
|
||||||
using Zennysoft.Ma.Adapter.Entity;
|
using Zennysoft.Ma.Adapter.Entity;
|
||||||
|
|
||||||
@@ -17,6 +19,8 @@ public class EquipmentComponent : IEquipmentComponent
|
|||||||
|
|
||||||
public AutoProp<EquipableItem> _equippedAccessory;
|
public AutoProp<EquipableItem> _equippedAccessory;
|
||||||
|
|
||||||
|
public event Action<EquipableItem> EquipmentChanged;
|
||||||
|
|
||||||
public int BonusAttack => _equippedWeapon.Value.BonusAttack + _equippedArmor.Value.BonusAttack + _equippedAccessory.Value.BonusAttack;
|
public int BonusAttack => _equippedWeapon.Value.BonusAttack + _equippedArmor.Value.BonusAttack + _equippedAccessory.Value.BonusAttack;
|
||||||
|
|
||||||
public int BonusDefense => _equippedWeapon.Value.BonusDefense + _equippedArmor.Value.BonusDefense + _equippedAccessory.Value.BonusDefense;
|
public int BonusDefense => _equippedWeapon.Value.BonusDefense + _equippedArmor.Value.BonusDefense + _equippedAccessory.Value.BonusDefense;
|
||||||
@@ -51,6 +55,7 @@ public class EquipmentComponent : IEquipmentComponent
|
|||||||
_equippedArmor.OnNext(armor);
|
_equippedArmor.OnNext(armor);
|
||||||
if (equipable is Accessory accessory)
|
if (equipable is Accessory accessory)
|
||||||
_equippedAccessory.OnNext(accessory);
|
_equippedAccessory.OnNext(accessory);
|
||||||
|
EquipmentChanged?.Invoke(equipable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unequip(EquipableItem equipable)
|
public void Unequip(EquipableItem equipable)
|
||||||
@@ -61,6 +66,7 @@ public class EquipmentComponent : IEquipmentComponent
|
|||||||
_equippedArmor.OnNext(new Armor());
|
_equippedArmor.OnNext(new Armor());
|
||||||
if (equipable is Accessory accessory)
|
if (equipable is Accessory accessory)
|
||||||
_equippedAccessory.OnNext(new Accessory());
|
_equippedAccessory.OnNext(new Accessory());
|
||||||
|
EquipmentChanged?.Invoke(equipable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsItemEquipped(InventoryItem item)
|
public bool IsItemEquipped(InventoryItem item)
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public class ExperiencePointsComponent : IExperiencePointsComponent
|
|||||||
|
|
||||||
public void LevelUp()
|
public void LevelUp()
|
||||||
{
|
{
|
||||||
|
SfxDatabase.Instance.Play(SoundEffect.LevelUp);
|
||||||
_level.OnNext(_level.Value + 1);
|
_level.OnNext(_level.Value + 1);
|
||||||
var expToNextLevel = ExpToNextLevelCalculation(_level.Value);
|
var expToNextLevel = ExpToNextLevelCalculation(_level.Value);
|
||||||
_currentExp.OnNext(_currentExp.Value - _expToNextLevel.Value);
|
_currentExp.OnNext(_currentExp.Value - _expToNextLevel.Value);
|
||||||
|
|||||||
@@ -36,12 +36,18 @@ public class HealthComponent : IHealthComponent
|
|||||||
|
|
||||||
public void Heal(int healAmount)
|
public void Heal(int healAmount)
|
||||||
{
|
{
|
||||||
|
if (CurrentHP.Value <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
var cappedAmount = Math.Min(healAmount + _currentHP.Value, _maximumHP.Value);
|
var cappedAmount = Math.Min(healAmount + _currentHP.Value, _maximumHP.Value);
|
||||||
_currentHP.OnNext(cappedAmount);
|
_currentHP.OnNext(cappedAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Damage(int damageAmount)
|
public void Damage(int damageAmount)
|
||||||
{
|
{
|
||||||
|
if (CurrentHP.Value <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
var cappedAmount = Math.Max(_currentHP.Value - damageAmount, 0);
|
var cappedAmount = Math.Max(_currentHP.Value - damageAmount, 0);
|
||||||
_currentHP.OnNext(cappedAmount);
|
_currentHP.OnNext(cappedAmount);
|
||||||
|
|
||||||
@@ -60,11 +66,15 @@ public class HealthComponent : IHealthComponent
|
|||||||
public void SetMaximumHealth(int health)
|
public void SetMaximumHealth(int health)
|
||||||
{
|
{
|
||||||
_maximumHP.OnNext(health);
|
_maximumHP.OnNext(health);
|
||||||
|
|
||||||
|
if (_currentHP.Value > _maximumHP.Value)
|
||||||
|
_currentHP.OnNext(_maximumHP.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RaiseMaximumHP(int raiseAmount)
|
public void RaiseMaximumHP(int raiseAmount, bool restoreHP = true)
|
||||||
{
|
{
|
||||||
_maximumHP.OnNext(raiseAmount);
|
_maximumHP.OnNext(_maximumHP.Value + raiseAmount);
|
||||||
|
if (restoreHP)
|
||||||
Heal(raiseAmount);
|
Heal(raiseAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,9 +49,18 @@ public class VTComponent : IVTComponent
|
|||||||
_currentVT.OnNext(cappedAmount);
|
_currentVT.OnNext(cappedAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RaiseMaximumVT(int raiseAmount)
|
public void RaiseMaximumVT(int raiseAmount, bool restoreVT = true)
|
||||||
{
|
{
|
||||||
_maximumVT.OnNext(raiseAmount);
|
_maximumVT.OnNext(_maximumVT.Value + raiseAmount);
|
||||||
|
if (restoreVT)
|
||||||
Restore(raiseAmount);
|
Restore(raiseAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetMaximumVT(int vt)
|
||||||
|
{
|
||||||
|
_maximumVT.OnNext(vt);
|
||||||
|
|
||||||
|
if (_currentVT.Value > _maximumVT.Value)
|
||||||
|
_currentVT.OnNext(_maximumVT.Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,10 @@ namespace Zennysoft.Game.Ma;
|
|||||||
|
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
using System.Reflection;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public partial class Main : Node
|
public partial class Main : Node
|
||||||
{
|
{
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
// If we don't need to run tests, we can just switch to the game scene.
|
|
||||||
CallDeferred("RunScene");
|
CallDeferred("RunScene");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
using Chickensoft.AutoInject;
|
using Chickensoft.AutoInject;
|
||||||
using Chickensoft.Collections;
|
|
||||||
using Chickensoft.GodotNodeInterfaces;
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Godot;
|
using Godot;
|
||||||
using Godot.Collections;
|
using NathanHoad;
|
||||||
using SimpleInjector.Lifestyles;
|
using SimpleInjector.Lifestyles;
|
||||||
using System.Linq;
|
using System.IO.Abstractions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Zennysoft.Game.Abstractions;
|
using Zennysoft.Game.Abstractions;
|
||||||
|
using Zennysoft.Game.Implementation;
|
||||||
using Zennysoft.Ma.Adapter;
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
@@ -26,7 +27,9 @@ public partial class App : Node, IApp
|
|||||||
|
|
||||||
[Node] private LoadingScreen LoadingScreen { get; set; } = default!;
|
[Node] private LoadingScreen LoadingScreen { get; set; } = default!;
|
||||||
|
|
||||||
public IInstantiator Instantiator { get; set; } = default!;
|
[Node] private OptionsMenu OptionsMenu { get; set; }
|
||||||
|
|
||||||
|
[Node] private GalleryMenu GalleryMenu { get; set; }
|
||||||
|
|
||||||
IAppRepo IProvide<IAppRepo>.Value() => AppRepo;
|
IAppRepo IProvide<IAppRepo>.Value() => AppRepo;
|
||||||
|
|
||||||
@@ -34,41 +37,98 @@ public partial class App : Node, IApp
|
|||||||
public IAppLogic AppLogic { get; set; } = default!;
|
public IAppLogic AppLogic { get; set; } = default!;
|
||||||
public AppLogic.IBinding AppBinding { get; set; } = default!;
|
public AppLogic.IBinding AppBinding { get; set; } = default!;
|
||||||
|
|
||||||
private Array _progress;
|
private Godot.Collections.Array _progress;
|
||||||
|
private SimpleInjector.Container _container;
|
||||||
|
|
||||||
private AutoProp<string> _loadedScene = new(string.Empty);
|
private DataViewer _dataViewer;
|
||||||
private bool _loadingGame = false;
|
private bool _loadingGame = false;
|
||||||
private bool _loadingEnemyViewer = false;
|
private bool _loadingEnemyViewer = false;
|
||||||
|
private string _optionsSavePath = string.Empty;
|
||||||
|
private string _controllerSavePath = string.Empty;
|
||||||
|
private ISaveFileManager _saveFileManager;
|
||||||
|
private IGame _game;
|
||||||
|
private IDataViewer _enemyViewer;
|
||||||
|
|
||||||
|
private double _reportedProgress = 0;
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
var container = new SimpleInjector.Container();
|
_container = new SimpleInjector.Container();
|
||||||
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
|
_container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
|
||||||
container.RegisterSingleton<IAppRepo, AppRepo>();
|
_container.RegisterSingleton<IAppRepo, AppRepo>();
|
||||||
container.RegisterSingleton<IAppLogic, AppLogic>();
|
_container.RegisterSingleton<IAppLogic, AppLogic>();
|
||||||
|
_container.RegisterSingleton<IFileSystem, FileSystem>();
|
||||||
|
_container.RegisterSingleton<ISaveFileManager, SaveFileManager>();
|
||||||
|
|
||||||
|
_saveFileManager = _container.GetInstance<ISaveFileManager>();
|
||||||
|
_optionsSavePath = $"{OS.GetUserDataDir()}/options.json";
|
||||||
|
_controllerSavePath = $"{OS.GetUserDataDir()}/controls.json";
|
||||||
|
|
||||||
|
Task.Run(() => _saveFileManager.ReadFromFile<OptionsData>(_optionsSavePath).ContinueWith((data) =>
|
||||||
|
{
|
||||||
|
if (data.IsCompletedSuccessfully)
|
||||||
|
OptionsMenu.CallDeferred("Load", data.Result);
|
||||||
|
}));
|
||||||
|
|
||||||
|
Task.Run(() => _saveFileManager.ReadFromFile<string>(_controllerSavePath).ContinueWith((data) =>
|
||||||
|
{
|
||||||
|
if (data.IsCompletedSuccessfully)
|
||||||
|
OptionsMenu.Controller.CallDeferred(nameof(OptionsMenu.Controller.LoadControllerInput), data.Result);
|
||||||
|
}));
|
||||||
|
|
||||||
MainMenu.StartGame += OnStartGame;
|
MainMenu.StartGame += OnStartGame;
|
||||||
MainMenu.EnemyViewer += OnEnemyViewer;
|
MainMenu.EnemyViewer += OnEnemyViewer;
|
||||||
|
MainMenu.Gallery += OnGallery;
|
||||||
|
MainMenu.Options += OnOptions;
|
||||||
MainMenu.Quit += OnQuit;
|
MainMenu.Quit += OnQuit;
|
||||||
_loadedScene.Changed += OnGameLoaded;
|
|
||||||
|
|
||||||
AppRepo = container.GetInstance<IAppRepo>();
|
GalleryMenu.GalleryExited += GalleryExited;
|
||||||
AppLogic = container.GetInstance<IAppLogic>();
|
|
||||||
|
OptionsMenu.OptionsMenuExited += OptionsMenu_OptionsMenuExited;
|
||||||
|
OptionsMenu.DeleteSaveData += DeleteSaveData;
|
||||||
|
AppRepo = _container.GetInstance<IAppRepo>();
|
||||||
|
AppLogic = _container.GetInstance<IAppLogic>();
|
||||||
|
|
||||||
AppLogic.Set(AppRepo);
|
AppLogic.Set(AppRepo);
|
||||||
AppLogic.Set(new AppLogic.Data());
|
AppLogic.Set(new AppLogic.Data());
|
||||||
|
|
||||||
|
AppRepo.DataViewerExited += DataViewerExited;
|
||||||
|
|
||||||
Input.MouseMode = Input.MouseModeEnum.Visible;
|
Input.MouseMode = Input.MouseModeEnum.Visible;
|
||||||
_progress = [];
|
_progress = [];
|
||||||
this.Provide();
|
this.Provide();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGameLoaded(string sceneName)
|
private void GameExitRequested()
|
||||||
{
|
{
|
||||||
LoadingScreen.Hide();
|
AppLogic.Input(new AppLogic.Input.QuitGame());
|
||||||
var scene = (PackedScene)ResourceLoader.LoadThreadedGet(sceneName);
|
}
|
||||||
var node = scene.Instantiate();
|
|
||||||
AddChild(node);
|
private void DeleteSaveData()
|
||||||
|
{
|
||||||
|
var saveFileManager = _container.GetInstance<ISaveFileManager>();
|
||||||
|
saveFileManager.DeleteSaveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DataViewerExited()
|
||||||
|
{
|
||||||
|
AppLogic.Input(new AppLogic.Input.EnemyViewerExited());
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OptionsMenu_OptionsMenuExited()
|
||||||
|
{
|
||||||
|
var saveFileManager = _container.GetInstance<ISaveFileManager>();
|
||||||
|
await saveFileManager.WriteToFile(OptionsMenu.OptionsData, _optionsSavePath);
|
||||||
|
var controllerOutput = InputHelper.SerializeInputsForActions();
|
||||||
|
await saveFileManager.WriteToFile(controllerOutput, _controllerSavePath);
|
||||||
|
OptionsMenu.Hide();
|
||||||
|
MainMenu.OptionsButton.GrabFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GalleryExited()
|
||||||
|
{
|
||||||
|
GalleryMenu.Hide();
|
||||||
|
MainMenu.GalleryButton.GrabFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnReady()
|
public void OnReady()
|
||||||
@@ -84,24 +144,35 @@ public partial class App : Node, IApp
|
|||||||
})
|
})
|
||||||
.Handle((in AppLogic.Output.SetupGameScene _) =>
|
.Handle((in AppLogic.Output.SetupGameScene _) =>
|
||||||
{
|
{
|
||||||
ResourceLoader.LoadThreadedRequest(GAME_SCENE_PATH);
|
LoadingScreen.Show();
|
||||||
_loadingGame = true;
|
LoadGame(GAME_SCENE_PATH);
|
||||||
MainMenu.Hide();
|
|
||||||
})
|
})
|
||||||
.Handle((in AppLogic.Output.ShowMainMenu _) =>
|
.Handle((in AppLogic.Output.ShowMainMenu _) =>
|
||||||
{
|
{
|
||||||
})
|
})
|
||||||
.Handle((in AppLogic.Output.ShowGame _) =>
|
.Handle((in AppLogic.Output.CloseGame _) =>
|
||||||
{
|
{
|
||||||
|
LoadingScreen.Hide();
|
||||||
|
_game.GameExitRequested -= GameExitRequested;
|
||||||
|
MainMenu.StartGameButton.GrabFocus();
|
||||||
|
_game.CallDeferred(MethodName.QueueFree, []);
|
||||||
|
GetTree().Paused = false;
|
||||||
})
|
})
|
||||||
.Handle((in AppLogic.Output.StartLoadingSaveFile _) =>
|
.Handle((in AppLogic.Output.StartLoadingSaveFile _) =>
|
||||||
{
|
{
|
||||||
})
|
})
|
||||||
.Handle((in AppLogic.Output.EnemyViewerOpened _) =>
|
.Handle((in AppLogic.Output.EnemyViewerOpened _) =>
|
||||||
{
|
{
|
||||||
ResourceLoader.LoadThreadedRequest(ENEMY_VIEWER_PATH);
|
LoadingScreen.Show();
|
||||||
_loadingEnemyViewer = true;
|
LoadEnemyViewer(ENEMY_VIEWER_PATH);
|
||||||
MainMenu.Hide();
|
})
|
||||||
|
.Handle((in AppLogic.Output.EnemyViewerExited _) =>
|
||||||
|
{
|
||||||
|
LoadingScreen.Hide();
|
||||||
|
if (_enemyViewer != null && _enemyViewer is DataViewer enemyViewer)
|
||||||
|
enemyViewer.CallDeferred(MethodName.QueueFree);
|
||||||
|
MainMenu.Show();
|
||||||
|
MainMenu.EnemyViewerButton.GrabFocus();
|
||||||
})
|
})
|
||||||
.Handle((in AppLogic.Output.ExitGame _) =>
|
.Handle((in AppLogic.Output.ExitGame _) =>
|
||||||
{
|
{
|
||||||
@@ -109,33 +180,66 @@ public partial class App : Node, IApp
|
|||||||
});
|
});
|
||||||
|
|
||||||
AppLogic.Start();
|
AppLogic.Start();
|
||||||
MainMenu.Show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
if (_loadingGame)
|
if (_reportedProgress < 1)
|
||||||
{
|
LoadingScreen.ProgressBar.Value = Mathf.RoundToInt(Mathf.Lerp(LoadingScreen.ProgressBar.Value, _reportedProgress * 100, (float)delta * 2));
|
||||||
ResourceLoader.LoadThreadedGetStatus(GAME_SCENE_PATH, _progress);
|
else
|
||||||
LoadingScreen.ProgressBar.Value = (double)_progress.Single();
|
LoadingScreen.ProgressBar.Value = Mathf.RoundToInt(Mathf.Lerp(LoadingScreen.ProgressBar.Value, 200, (float)delta * 5));
|
||||||
if ((double)_progress.Single() == 1)
|
|
||||||
_loadedScene.OnNext(GAME_SCENE_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_loadingEnemyViewer)
|
|
||||||
{
|
|
||||||
ResourceLoader.LoadThreadedGetStatus(ENEMY_VIEWER_PATH, _progress);
|
|
||||||
LoadingScreen.ProgressBar.Value = (double)_progress.Single();
|
|
||||||
if ((double)_progress.Single() == 1)
|
|
||||||
_loadedScene.OnNext(ENEMY_VIEWER_PATH);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnStartGame() => AppLogic.Input(new AppLogic.Input.NewGame());
|
public void OnStartGame() => AppLogic.Input(new AppLogic.Input.NewGame());
|
||||||
|
|
||||||
private void OnEnemyViewer() => AppLogic.Input(new AppLogic.Input.EnemyViewerOpened());
|
private void OnEnemyViewer() => AppLogic.Input(new AppLogic.Input.EnemyViewerOpened());
|
||||||
|
|
||||||
private void OnLoadGame() => AppLogic.Input(new AppLogic.Input.LoadGame());
|
private void OnGalleryViewer() => AppLogic.Input(new AppLogic.Input.GalleryOpened());
|
||||||
|
|
||||||
|
private async void LoadGame(string sceneName)
|
||||||
|
{
|
||||||
|
var scene = await LoadSceneInternal(sceneName);
|
||||||
|
_game = scene as IGame;
|
||||||
|
_game.GameExitRequested += GameExitRequested;
|
||||||
|
await ToSignal(GetTree().CreateTimer(0.8f), "timeout");
|
||||||
|
CallDeferred(MethodName.AddChild, scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void LoadEnemyViewer(string sceneName)
|
||||||
|
{
|
||||||
|
var scene = await LoadSceneInternal(sceneName);
|
||||||
|
_enemyViewer = scene as IDataViewer;
|
||||||
|
await ToSignal(GetTree().CreateTimer(0.8f), "timeout");
|
||||||
|
CallDeferred(MethodName.AddChild, scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Node> LoadSceneInternal(string sceneName)
|
||||||
|
{
|
||||||
|
LoadingScreen.Show();
|
||||||
|
LoadingScreen.ProgressBar.Value = 0;
|
||||||
|
var sceneLoader = new SceneLoader();
|
||||||
|
CallDeferred(MethodName.AddChild, sceneLoader);
|
||||||
|
sceneLoader.LoadSceneRequest(sceneName);
|
||||||
|
sceneLoader.SceneReportedProgress += SceneLoader_SceneReportedProgress;
|
||||||
|
await ToSignal(sceneLoader, SceneLoader.SignalName.SceneLoaded);
|
||||||
|
var result = sceneLoader.LoadedScene;
|
||||||
|
sceneLoader.QueueFree();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SceneLoader_SceneReportedProgress(double progress) => _reportedProgress = progress;
|
||||||
|
|
||||||
|
private async void OnOptions()
|
||||||
|
{
|
||||||
|
OptionsMenu.Show();
|
||||||
|
OptionsMenu.GameTab.GrabFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnGallery()
|
||||||
|
{
|
||||||
|
GalleryMenu.Show();
|
||||||
|
GalleryMenu.ItemButton1.GrabFocus();
|
||||||
|
}
|
||||||
|
|
||||||
public void OnQuit() => AppLogic.Input(new AppLogic.Input.QuitGame());
|
public void OnQuit() => AppLogic.Input(new AppLogic.Input.QuitGame());
|
||||||
|
|
||||||
@@ -153,6 +257,5 @@ public partial class App : Node, IApp
|
|||||||
MainMenu.StartGame -= OnStartGame;
|
MainMenu.StartGame -= OnStartGame;
|
||||||
MainMenu.EnemyViewer -= OnEnemyViewer;
|
MainMenu.EnemyViewer -= OnEnemyViewer;
|
||||||
MainMenu.Quit -= OnQuit;
|
MainMenu.Quit -= OnQuit;
|
||||||
_loadedScene.Changed -= OnGameLoaded;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,140 +1,42 @@
|
|||||||
|
// Attach to a ColorRect in front of texture/background
|
||||||
|
|
||||||
shader_type canvas_item;
|
shader_type canvas_item;
|
||||||
|
|
||||||
// Handles the resolution changes, color depth, and dithering
|
// Handles the concentric ripples
|
||||||
group_uniforms resolution_and_colors;
|
uniform float frequency: hint_range(0, 15, 0.01) = 4.0;
|
||||||
uniform bool change_color_depth = false;
|
uniform float amplitude: hint_range(0, 3, 0.1) = 2.0;
|
||||||
uniform int target_color_depth : hint_range(1, 8) = 5;
|
uniform float ripple_rate : hint_range(0, 20.0, 1) = 5;
|
||||||
uniform bool dithering = false;
|
|
||||||
uniform bool scale_resolution = false;
|
|
||||||
uniform int target_resolution_scale = 3;
|
|
||||||
|
|
||||||
// Handles the LUTish recoloring
|
// Handles the waves themselves
|
||||||
group_uniforms gradient_recoloring;
|
uniform float wave_amplitude: hint_range(0.001, 0.1, 0.001) = 0.05;
|
||||||
uniform bool enable_recolor = false;
|
uniform float wave_frequency: hint_range(0, 15, 0.01) = 4.0;
|
||||||
uniform sampler2D to_gradient: hint_default_black;
|
|
||||||
|
|
||||||
int dithering_pattern(ivec2 fragcoord) {
|
uniform sampler2D noise;
|
||||||
const int pattern[] = {
|
|
||||||
-4, +0, -3, +1,
|
|
||||||
+2, -2, +3, -1,
|
|
||||||
-3, +1, -4, +0,
|
|
||||||
+3, -1, +2, -2
|
|
||||||
};
|
|
||||||
|
|
||||||
int x = fragcoord.x % 4;
|
uniform sampler2D SCREEN_TEXTURE: hint_screen_texture, filter_linear_mipmap;
|
||||||
int y = fragcoord.y % 4;
|
|
||||||
|
|
||||||
return pattern[y * 4 + x];
|
vec2 wave(vec2 uv, float time) {
|
||||||
}
|
return vec2(
|
||||||
|
uv.x + sin(uv.y * wave_frequency + time) * wave_amplitude,
|
||||||
vec3 rgb2hsv(vec3 rgb) { //Converts RGB values to HSV
|
uv.y + sin(uv.x * wave_frequency + time) * wave_amplitude
|
||||||
float r = rgb.r;
|
);
|
||||||
float g = rgb.g;
|
|
||||||
float b = rgb.b;
|
|
||||||
|
|
||||||
float cmax = max(r,max(g,b));
|
|
||||||
float cmin = min(r,min(g,b));
|
|
||||||
float delta = cmax - cmin;
|
|
||||||
|
|
||||||
float h = 0.f; //hue
|
|
||||||
|
|
||||||
if (delta > 0.f){
|
|
||||||
if (cmax == r){
|
|
||||||
h = (g-b)/delta;
|
|
||||||
h = mod(h,6.f);
|
|
||||||
} else if (cmax == g){
|
|
||||||
h = ((b - r) / delta) + 2.f;
|
|
||||||
} else {
|
|
||||||
h = ((r-g)/delta) + 4.f;
|
|
||||||
}
|
|
||||||
h = h * 60.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
float s = 0.f; //saturation
|
|
||||||
if (cmax > 0.f){
|
|
||||||
s = delta / cmax;
|
|
||||||
}
|
|
||||||
|
|
||||||
return vec3(h,s,cmax); // Keep original alpha value
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 hsv2rgb(vec3 hsv) { //Converts HSV values to RGB
|
|
||||||
float h = hsv.r;
|
|
||||||
float s = hsv.g;
|
|
||||||
float v = hsv.b;
|
|
||||||
float c = v * s;
|
|
||||||
//X = C × (1 - |(H / 60°) mod 2 - 1|)
|
|
||||||
float x = h / 60.f;
|
|
||||||
x = mod(x,2.f);
|
|
||||||
x = abs(x - 1.f);
|
|
||||||
x = c * (1.f - x);
|
|
||||||
|
|
||||||
float m = v - c;
|
|
||||||
|
|
||||||
vec3 rgb = vec3(0.f,0.f,0.f);
|
|
||||||
|
|
||||||
if (h < 60.f) {
|
|
||||||
rgb = vec3(c,x,0.f);
|
|
||||||
} else if (h < 120.f){
|
|
||||||
rgb = vec3(x,c,0.f);
|
|
||||||
} else if (h < 180.f){
|
|
||||||
rgb = vec3(0.f,c,x);
|
|
||||||
} else if (h < 240.f){
|
|
||||||
rgb = vec3(0.f,x,c);
|
|
||||||
} else if (h < 300.f){
|
|
||||||
rgb = vec3(x,0.f,c);
|
|
||||||
} else if (h < 360.f){
|
|
||||||
rgb = vec3(c,0.f,x);
|
|
||||||
}
|
|
||||||
rgb[0] = rgb[0] + m;
|
|
||||||
rgb[1] = rgb[1] + m;
|
|
||||||
rgb[2] = rgb[2] + m;
|
|
||||||
|
|
||||||
return rgb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
ivec2 uv;
|
vec2 center_position = -1.0 + 2.0 * UV / (1.0 / TEXTURE_PIXEL_SIZE);
|
||||||
vec3 color;
|
float center_distance = length(center_position);
|
||||||
|
|
||||||
|
float ripple = sin(center_distance * -frequency * PI + ripple_rate * TIME) * amplitude / (center_distance + 1.0);
|
||||||
|
|
||||||
|
vec2 uv = FRAGCOORD.xy / (1.0 / SCREEN_PIXEL_SIZE).xy + (center_position/center_distance) * ripple * wave_amplitude;
|
||||||
|
vec2 background_wave = wave(uv, TIME);
|
||||||
|
vec4 background_texture = texture(SCREEN_TEXTURE,background_wave) * sqrt(amplitude);
|
||||||
|
|
||||||
|
float alpha_scalar = (1.0 - min(center_distance, 1.0)) * background_texture.x * 2.5;
|
||||||
|
|
||||||
|
background_texture.a *= 1.0 * alpha_scalar * (ripple + background_texture.x * background_texture.y);
|
||||||
|
background_texture.a = max(background_texture.a - (background_texture.y * 0.45), 0.0);
|
||||||
|
|
||||||
|
COLOR = vec4(background_texture.xyz, background_texture.a);
|
||||||
|
|
||||||
if(scale_resolution){
|
|
||||||
uv = ivec2(FRAGCOORD.xy / float(target_resolution_scale));
|
|
||||||
color = texelFetch(TEXTURE, uv * target_resolution_scale, 0).rgb;
|
|
||||||
} else {
|
|
||||||
uv = ivec2(FRAGCOORD.xy);
|
|
||||||
color = texelFetch(TEXTURE, uv, 0).rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(enable_recolor){
|
|
||||||
vec3 hsv = rgb2hsv(color);
|
|
||||||
float color_pos = (hsv.x / 360.0);
|
|
||||||
vec3 new_color = texture(to_gradient, vec2((color_pos), 0.5)).rgb;
|
|
||||||
vec3 new_hsv = rgb2hsv(new_color);
|
|
||||||
hsv.x = new_hsv.x;
|
|
||||||
vec3 final_rgb = hsv2rgb(hsv);
|
|
||||||
|
|
||||||
color.rgb = final_rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Convert from [0.0, 1.0] range to [0, 255] range
|
|
||||||
ivec3 c = ivec3(round(color * 255.0));
|
|
||||||
|
|
||||||
// Apply the dithering pattern
|
|
||||||
if (dithering) {
|
|
||||||
c += ivec3(dithering_pattern(uv));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 final_color;
|
|
||||||
if(change_color_depth){
|
|
||||||
// Truncate from 8 bits to color_depth bits
|
|
||||||
c >>= (8 - target_color_depth);
|
|
||||||
final_color = vec3(c) / float(1 << target_color_depth);
|
|
||||||
} else {
|
|
||||||
final_color = vec3(c) / float(1 << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert back to [0.0, 1.0] range
|
|
||||||
COLOR.rgb = final_color;
|
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,26 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://cagfc5ridmteu"]
|
[gd_scene load_steps=6 format=3 uid="uid://cagfc5ridmteu"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://d1f8blk5ucqvq" path="res://src/app/App.cs" id="1_rt73h"]
|
[ext_resource type="Script" uid="uid://d1f8blk5ucqvq" path="res://src/app/App.cs" id="1_rt73h"]
|
||||||
[ext_resource type="PackedScene" uid="uid://rfvnddfqufho" path="res://src/menu/MainMenu.tscn" id="2_1uiag"]
|
[ext_resource type="PackedScene" uid="uid://rfvnddfqufho" path="res://src/menu/MainMenu.tscn" id="2_1uiag"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://drkl3btdy6uxj" path="res://src/options/OptionsMenu.tscn" id="2_v0mgf"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cpjlj7kxdhv16" path="res://src/menu/LoadingScreen.tscn" id="3_3st5l"]
|
[ext_resource type="PackedScene" uid="uid://cpjlj7kxdhv16" path="res://src/menu/LoadingScreen.tscn" id="3_3st5l"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cm6fo70yb2hip" path="res://src/ui/gallery/GalleryMenu.tscn" id="5_iuu71"]
|
||||||
|
|
||||||
[node name="App" type="Node"]
|
[node name="App" type="Node"]
|
||||||
process_mode = 3
|
process_mode = 3
|
||||||
script = ExtResource("1_rt73h")
|
script = ExtResource("1_rt73h")
|
||||||
|
|
||||||
[node name="LoadingScreen" parent="." instance=ExtResource("3_3st5l")]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
|
|
||||||
[node name="MainMenu" parent="." instance=ExtResource("2_1uiag")]
|
[node name="MainMenu" parent="." instance=ExtResource("2_1uiag")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="LoadingScreen" parent="." instance=ExtResource("3_3st5l")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
[node name="OptionsMenu" parent="." instance=ExtResource("2_v0mgf")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
[node name="GalleryMenu" parent="." instance=ExtResource("5_iuu71")]
|
||||||
|
unique_name_in_owner = true
|
||||||
visible = false
|
visible = false
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://ddii3pi8x75xc"
|
|
||||||
path="res://.godot/imported/amb_beach.wav-046e4f838e50e43a1aba1a754b92aad6.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://src/audio/AMB/amb_beach.wav"
|
|
||||||
dest_files=["res://.godot/imported/amb_beach.wav-046e4f838e50e43a1aba1a754b92aad6.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=3
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://ym4ur8a2qxhp"
|
|
||||||
path="res://.godot/imported/amb_perlin.wav-ba6da0d5591f392e4aca7d2f85c4dfc2.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://src/audio/AMB/amb_perlin.wav"
|
|
||||||
dest_files=["res://.godot/imported/amb_perlin.wav-ba6da0d5591f392e4aca7d2f85c4dfc2.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=3
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://b7wxddjx3qw5o"
|
|
||||||
path="res://.godot/imported/amb_white_noise.wav-d316dd05afe429f6bcdda594285ad718.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://src/audio/AMB/amb_white_noise.wav"
|
|
||||||
dest_files=["res://.godot/imported/amb_white_noise.wav-d316dd05afe429f6bcdda594285ad718.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=3
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="wav"
|
|
||||||
type="AudioStreamWAV"
|
|
||||||
uid="uid://bmiitw4fcs68e"
|
|
||||||
path="res://.godot/imported/amb_wind_loop_altar.wav-e766e3db29faa01ad6dbaa8cb18d7de6.sample"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://src/audio/AMB/amb_wind_loop_altar.wav"
|
|
||||||
dest_files=["res://.godot/imported/amb_wind_loop_altar.wav-e766e3db29faa01ad6dbaa8cb18d7de6.sample"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
force/8_bit=false
|
|
||||||
force/mono=false
|
|
||||||
force/max_rate=false
|
|
||||||
force/max_rate_hz=44100
|
|
||||||
edit/trim=false
|
|
||||||
edit/normalize=false
|
|
||||||
edit/loop_mode=3
|
|
||||||
edit/loop_begin=0
|
|
||||||
edit/loop_end=-1
|
|
||||||
compress/mode=2
|
|
||||||
@@ -1,42 +1,21 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
public partial class AudioManager : Node
|
public partial class AudioManager : Node
|
||||||
{
|
{
|
||||||
private static string sfxPath = $"res://src/audio/sfx/";
|
private static AudioStreamPlayer _audioPlayer;
|
||||||
private AudioStreamPlayer _audioPlayer;
|
private static AudioManager _instance;
|
||||||
private IDictionary<SoundEffect, AudioStream> _sfxDictionary;
|
|
||||||
|
public static AudioManager Instance => _instance;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
if (_instance != null)
|
||||||
|
QueueFree();
|
||||||
|
_instance = this;
|
||||||
_audioPlayer = new AudioStreamPlayer();
|
_audioPlayer = new AudioStreamPlayer();
|
||||||
AddChild(_audioPlayer);
|
AddChild(_audioPlayer);
|
||||||
_sfxDictionary = new Dictionary<SoundEffect, AudioStream>();
|
_audioPlayer.Bus = "SFX";
|
||||||
var soundEffects = Enum.GetValues(typeof(SoundEffect));
|
|
||||||
foreach (var effect in soundEffects)
|
|
||||||
_sfxDictionary.Add((SoundEffect)effect, GD.Load<AudioStream>(sfxPath + effect + ".ogg"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Play(SoundEffect soundEffect)
|
|
||||||
{
|
|
||||||
_sfxDictionary.TryGetValue(soundEffect, out var stream);
|
|
||||||
_audioPlayer.Stream = stream;
|
|
||||||
_audioPlayer.Play();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public enum SoundEffect
|
|
||||||
{
|
|
||||||
Cancel,
|
|
||||||
Equip,
|
|
||||||
Heal,
|
|
||||||
MenuBack,
|
|
||||||
MoveThroughOptions,
|
|
||||||
PlayerAttack,
|
|
||||||
PlayerHitWall,
|
|
||||||
Select,
|
|
||||||
Sort,
|
|
||||||
Unequip
|
|
||||||
}
|
|
||||||
|
|||||||
150
Zennysoft.Game.Ma/src/audio/SFXDatabase.tscn
Normal file
150
Zennysoft.Game.Ma/src/audio/SFXDatabase.tscn
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
[gd_scene load_steps=25 format=3 uid="uid://brgi35xj3b4ud"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://cw100tox0ufsy" path="res://src/audio/SfxDatabase.cs" id="1_ojkqd"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://cye8wlqbx66h4" path="res://src/audio/sfx/player_heal.ogg" id="2_158j8"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://1nuk6xpkwujl" path="res://src/audio/sfx/player_gain_VT.ogg" id="3_kac56"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://bfrp34y2m8b1l" path="res://src/audio/sfx/item_number_increase.ogg" id="4_fa8i8"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://xjdv23q5cqhm" path="res://src/audio/sfx/UI_PAUSE.ogg" id="5_p5cio"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://clhdcrs4dxt6h" path="res://src/audio/sfx/UI_MOVE.ogg" id="6_r16t0"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://c817txm4tmup7" path="res://src/audio/sfx/PLAYER_EQUIP.ogg" id="7_sew62"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://qxi7qto7hhgk" path="res://src/audio/sfx/PLAYER_UNEQUIP.ogg" id="8_rf1la"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://doeefxilh0luj" path="res://src/audio/sfx/ITEM_SORT.ogg" id="9_l6w22"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://4mk4hlse81if" path="res://src/audio/sfx/player_losehealth.ogg" id="10_kac56"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://dwp3ep3jddvrr" path="res://src/audio/sfx/UI_SELECT.ogg" id="10_nerso"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://oslvh60ec5gc" path="res://src/audio/sfx/UI_CANCEL_BACK.ogg" id="11_rloay"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://bo2u1ceci6k1i" path="res://src/audio/sfx/PLAYER_quicker_slash.ogg" id="13_fa8i8"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://na0lxb1lib11" path="res://src/audio/sfx/player_crit.ogg" id="14_p5cio"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://bsc83jkt7uisg" path="res://src/audio/sfx/PLAYER_GET_ITEM.ogg" id="15_r16t0"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://ckf3md1ujxhvm" path="res://src/audio/sfx/player_levelup.ogg" id="16_sew62"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://coeynqnn61c43" path="res://src/audio/sfx/ITEM_TRANSFER.ogg" id="18_l6w22"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://bfrmm07vthpwt" path="res://src/audio/sfx/item_divine_recall.ogg" id="19_nerso"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://bu8akh5uh3ioo" path="res://src/audio/sfx/item_devic_balance_element1.ogg" id="20_rloay"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://bjkn6s2xjxuji" path="res://src/audio/sfx/item_gospel_dimension.ogg" id="21_6hsck"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://c3ur4bgvmsidi" path="res://src/audio/sfx/item_gospel_escape.ogg" id="22_3wq6u"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://bc2pe0l5nr5ro" path="res://src/audio/sfx/ITEM_kyuu_hit.ogg" id="23_aaerj"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://ck0nc757t0jq5" path="res://src/audio/sfx/ITEM_PERSPECTIVE.ogg" id="23_jdwj3"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://dblijlgm8njjv" path="res://src/audio/sfx/item_sine_morphization.ogg" id="24_jdwj3"]
|
||||||
|
|
||||||
|
[node name="SfxDatabase" type="Node"]
|
||||||
|
script = ExtResource("1_ojkqd")
|
||||||
|
|
||||||
|
[node name="UI" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="OpenInventorySound" type="AudioStreamPlayer" parent="UI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("5_p5cio")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="MoveSound" type="AudioStreamPlayer" parent="UI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("6_r16t0")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="SelectSound" type="AudioStreamPlayer" parent="UI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("10_nerso")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="CancelSound" type="AudioStreamPlayer" parent="UI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("11_rloay")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="Player" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="HealHPSound" type="AudioStreamPlayer" parent="Player"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("2_158j8")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="TakeDamageSound" type="AudioStreamPlayer" parent="Player"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("10_kac56")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="HealVTSound" type="AudioStreamPlayer" parent="Player"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("3_kac56")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="WeaponSwingSound" type="AudioStreamPlayer" parent="Player"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("13_fa8i8")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="CritSound" type="AudioStreamPlayer" parent="Player"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("14_p5cio")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="PickupItemSound" type="AudioStreamPlayer" parent="Player"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("15_r16t0")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="LevelUpSound" type="AudioStreamPlayer" parent="Player"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("16_sew62")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="EquipSound" type="AudioStreamPlayer" parent="Player"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("7_sew62")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="UnequipSound" type="AudioStreamPlayer" parent="Player"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("8_rf1la")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="Item" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="TransferItemSound" type="AudioStreamPlayer" parent="Item"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("18_l6w22")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="IncreaseStatSound" type="AudioStreamPlayer" parent="Item"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("4_fa8i8")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="SortSound" type="AudioStreamPlayer" parent="Item"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("9_l6w22")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="RecallEnemiesSound" type="AudioStreamPlayer" parent="Item"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("19_nerso")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="KillHalfEnemiesSound" type="AudioStreamPlayer" parent="Item"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("20_rloay")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="TeleportToRandomRoomSound" type="AudioStreamPlayer" parent="Item"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("21_6hsck")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="TeleportToExitSound" type="AudioStreamPlayer" parent="Item"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("22_3wq6u")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="AbsorbHPFromAllEnemiesSound" type="AudioStreamPlayer" parent="Item"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("23_aaerj")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="SwapHPAndVTSound" type="AudioStreamPlayer" parent="Item"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("23_jdwj3")
|
||||||
|
bus = &"SFX"
|
||||||
|
|
||||||
|
[node name="TurnAllEnemiesIntoHealingItemsSound" type="AudioStreamPlayer" parent="Item"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
stream = ExtResource("24_jdwj3")
|
||||||
|
bus = &"SFX"
|
||||||
108
Zennysoft.Game.Ma/src/audio/SfxDatabase.cs
Normal file
108
Zennysoft.Game.Ma/src/audio/SfxDatabase.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
using Chickensoft.AutoInject;
|
||||||
|
using Chickensoft.Introspection;
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
[Meta(typeof(IAutoNode)), Id("sfx_database")]
|
||||||
|
public partial class SfxDatabase : Node
|
||||||
|
{
|
||||||
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
|
|
||||||
|
private static SfxDatabase _instance;
|
||||||
|
|
||||||
|
public static SfxDatabase Instance => _instance;
|
||||||
|
|
||||||
|
public void OnReady()
|
||||||
|
{
|
||||||
|
if (_instance != null)
|
||||||
|
QueueFree();
|
||||||
|
_instance = this;
|
||||||
|
|
||||||
|
_sfxMap = new Dictionary<SoundEffect, AudioStreamPlayer>
|
||||||
|
{
|
||||||
|
{SoundEffect.HealHP, HealHPSound },
|
||||||
|
{SoundEffect.TakeDamage, TakeDamageSound },
|
||||||
|
{SoundEffect.HealVT, HealVTSound },
|
||||||
|
{SoundEffect.IncreaseStat, IncreaseStatSound },
|
||||||
|
{SoundEffect.WeaponSwing, WeaponSwingSound },
|
||||||
|
{SoundEffect.Crit, CritSound },
|
||||||
|
{SoundEffect.PickupItem, PickupItemSound },
|
||||||
|
{SoundEffect.OpenInventory, OpenInventorySound },
|
||||||
|
{SoundEffect.MoveUI, MoveSound },
|
||||||
|
{SoundEffect.Equip, EquipSound },
|
||||||
|
{SoundEffect.Unequip, UnequipSound },
|
||||||
|
{SoundEffect.SortInventory, SortSound },
|
||||||
|
{SoundEffect.SelectUI, SelectSound },
|
||||||
|
{SoundEffect.CancelUI, CancelSound },
|
||||||
|
{SoundEffect.LevelUp, LevelUpSound },
|
||||||
|
{SoundEffect.Transfer, TransferItemSound },
|
||||||
|
{SoundEffect.RecallEnemies, RecallEnemiesSound},
|
||||||
|
{SoundEffect.KillHalfEnemies, KillHalfEnemiesSound},
|
||||||
|
{SoundEffect.TeleportToRandomRoom, TeleportToRandomRoomSound},
|
||||||
|
{SoundEffect.TeleportToExit, TeleportToExitSound},
|
||||||
|
{SoundEffect.AbsorbHPFromAllEnemies, AbsorbHPFromAllEnemiesSound},
|
||||||
|
{SoundEffect.TurnAllEnemiesIntoHealingItems, TurnAllEnemiesIntoHealingItemsSound},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Node] private AudioStreamPlayer HealHPSound { get; set; } = default!;
|
||||||
|
[Node] private AudioStreamPlayer TakeDamageSound { get; set; } = default!;
|
||||||
|
[Node] private AudioStreamPlayer HealVTSound { get; set; } = default!;
|
||||||
|
[Node] private AudioStreamPlayer IncreaseStatSound { get; set; } = default!;
|
||||||
|
[Node] private AudioStreamPlayer WeaponSwingSound { get; set; } = default!;
|
||||||
|
[Node] private AudioStreamPlayer CritSound { get; set; } = default!;
|
||||||
|
[Node] private AudioStreamPlayer PickupItemSound { get; set; } = default!;
|
||||||
|
[Node] private AudioStreamPlayer OpenInventorySound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer MoveSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer EquipSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer UnequipSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer SortSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer SelectSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer CancelSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer LevelUpSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer TransferItemSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer RecallEnemiesSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer KillHalfEnemiesSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer TeleportToRandomRoomSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer TeleportToExitSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer AbsorbHPFromAllEnemiesSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer SwapHPAndVTSound { get; set; }
|
||||||
|
[Node] private AudioStreamPlayer TurnAllEnemiesIntoHealingItemsSound { get; set; }
|
||||||
|
|
||||||
|
private Dictionary<SoundEffect, AudioStreamPlayer> _sfxMap;
|
||||||
|
|
||||||
|
public void Play(SoundEffect soundEffect)
|
||||||
|
{
|
||||||
|
_sfxMap.TryGetValue(soundEffect, out var audio);
|
||||||
|
if (audio != null)
|
||||||
|
audio.Play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SoundEffect
|
||||||
|
{
|
||||||
|
HealHP,
|
||||||
|
TakeDamage,
|
||||||
|
HealVT,
|
||||||
|
IncreaseStat,
|
||||||
|
WeaponSwing,
|
||||||
|
Crit,
|
||||||
|
PickupItem,
|
||||||
|
OpenInventory,
|
||||||
|
MoveUI,
|
||||||
|
Equip,
|
||||||
|
Unequip,
|
||||||
|
SortInventory,
|
||||||
|
SelectUI,
|
||||||
|
CancelUI,
|
||||||
|
LevelUp,
|
||||||
|
Transfer,
|
||||||
|
RecallEnemies,
|
||||||
|
KillHalfEnemies,
|
||||||
|
TeleportToRandomRoom,
|
||||||
|
TeleportToExit,
|
||||||
|
AbsorbHPFromAllEnemies,
|
||||||
|
SwapHPAndVT,
|
||||||
|
TurnAllEnemiesIntoHealingItems,
|
||||||
|
}
|
||||||
|
|
||||||
1
Zennysoft.Game.Ma/src/audio/SfxDatabase.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/audio/SfxDatabase.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cw100tox0ufsy
|
||||||
Binary file not shown.
@@ -1,19 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="oggvorbisstr"
|
|
||||||
type="AudioStreamOggVorbis"
|
|
||||||
uid="uid://dci08kmwsu6k1"
|
|
||||||
path="res://.godot/imported/Cancel.ogg-90240069a266fcef76dd638dfd79efd5.oggvorbisstr"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://src/audio/sfx/Cancel.ogg"
|
|
||||||
dest_files=["res://.godot/imported/Cancel.ogg-90240069a266fcef76dd638dfd79efd5.oggvorbisstr"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
loop=false
|
|
||||||
loop_offset=0
|
|
||||||
bpm=0
|
|
||||||
beat_count=0
|
|
||||||
bar_beats=4
|
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AGNI_AGGRO.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AGNI_AGGRO.ogg
Normal file
Binary file not shown.
19
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AGNI_AGGRO.ogg.import
Normal file
19
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AGNI_AGGRO.ogg.import
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://b30jgvhwd6vfj"
|
||||||
|
path="res://.godot/imported/ENEMY_AGNI_AGGRO.ogg-9878bfe043b251a0b2cc6c6291d549c4.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_AGNI_AGGRO.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_AGNI_AGGRO.ogg-9878bfe043b251a0b2cc6c6291d549c4.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AGNI_AMBIENT_LOOP.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AGNI_AMBIENT_LOOP.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://dh6drqqrcp8dp"
|
||||||
|
path="res://.godot/imported/ENEMY_AGNI_AMBIENT_LOOP.ogg-c85d2b023556dd456dfa07e48b74e769.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_AGNI_AMBIENT_LOOP.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_AGNI_AMBIENT_LOOP.ogg-c85d2b023556dd456dfa07e48b74e769.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=true
|
||||||
|
loop_offset=0.0
|
||||||
|
bpm=0.0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AGNI_ATTACK_1.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AGNI_ATTACK_1.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://cc7g8awtomf45"
|
||||||
|
path="res://.godot/imported/ENEMY_AGNI_ATTACK_1.ogg-dc64f90a85640c723c65c932bfbc9007.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_AGNI_ATTACK_1.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_AGNI_ATTACK_1.ogg-dc64f90a85640c723c65c932bfbc9007.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AGNI_ATTACK_2_SWING.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AGNI_ATTACK_2_SWING.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://c36ewcgnjtr7g"
|
||||||
|
path="res://.godot/imported/ENEMY_AGNI_ATTACK_2_SWING.ogg-4abaf9b1cfa9986027d561d523e840f9.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_AGNI_ATTACK_2_SWING.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_AGNI_ATTACK_2_SWING.ogg-4abaf9b1cfa9986027d561d523e840f9.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_APSARA_AGGRO.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_APSARA_AGGRO.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://bemrovoemoq5u"
|
||||||
|
path="res://.godot/imported/ENEMY_APSARA_AGGRO.ogg-c77159934ba46ad7019339715aa58d6f.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_APSARA_AGGRO.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_APSARA_AGGRO.ogg-c77159934ba46ad7019339715aa58d6f.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_APSARA_STRIKE.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_APSARA_STRIKE.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://b4bseex34nu6c"
|
||||||
|
path="res://.godot/imported/ENEMY_APSARA_STRIKE.ogg-2af6e982927e25cfdc545efb8b7f8e9d.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_APSARA_STRIKE.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_APSARA_STRIKE.ogg-2af6e982927e25cfdc545efb8b7f8e9d.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AQUEOS_LOOP.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AQUEOS_LOOP.ogg
Normal file
Binary file not shown.
19
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AQUEOS_LOOP.ogg.import
Normal file
19
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_AQUEOS_LOOP.ogg.import
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://ddcyb2ni2aisr"
|
||||||
|
path="res://.godot/imported/ENEMY_AQUEOS_LOOP.ogg-8237cb508a4b08073b02775819a85e91.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_AQUEOS_LOOP.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_AQUEOS_LOOP.ogg-8237cb508a4b08073b02775819a85e91.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=true
|
||||||
|
loop_offset=0.0
|
||||||
|
bpm=0.0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_CHARIOT_DEATH.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_CHARIOT_DEATH.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://daye7334d7rfe"
|
||||||
|
path="res://.godot/imported/ENEMY_CHARIOT_DEATH.ogg-f33e3a380a502c415659f697891048f5.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_CHARIOT_DEATH.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_CHARIOT_DEATH.ogg-f33e3a380a502c415659f697891048f5.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_DEMONWALL_SMASH.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_DEMONWALL_SMASH.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://cm565avpubaxy"
|
||||||
|
path="res://.godot/imported/ENEMY_DEMONWALL_SMASH.ogg-086ea8d6196afbc09cfd6bbdd831be56.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_DEMONWALL_SMASH.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_DEMONWALL_SMASH.ogg-086ea8d6196afbc09cfd6bbdd831be56.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_DEMONWALL_THUNDER.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_DEMONWALL_THUNDER.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://coux7hls1vils"
|
||||||
|
path="res://.godot/imported/ENEMY_DEMONWALL_THUNDER.ogg-156e207e3fd9a3e11ff46ccb6d65b7cc.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_DEMONWALL_THUNDER.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_DEMONWALL_THUNDER.ogg-156e207e3fd9a3e11ff46ccb6d65b7cc.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_DEMON_WALLMOVE.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_DEMON_WALLMOVE.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://bjo0q2tyf7vff"
|
||||||
|
path="res://.godot/imported/ENEMY_DEMON_WALLMOVE.ogg-54685006d006c356b1b0e6b616b84214.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_DEMON_WALLMOVE.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_DEMON_WALLMOVE.ogg-54685006d006c356b1b0e6b616b84214.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_DEMON_WALL_ORB.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_DEMON_WALL_ORB.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://c50a5gp3821u4"
|
||||||
|
path="res://.godot/imported/ENEMY_DEMON_WALL_ORB.ogg-c12bf36029735aefcd97431b41d93a20.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_DEMON_WALL_ORB.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_DEMON_WALL_ORB.ogg-c12bf36029735aefcd97431b41d93a20.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_EDEN_FIRE.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_EDEN_FIRE.ogg
Normal file
Binary file not shown.
19
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_EDEN_FIRE.ogg.import
Normal file
19
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_EDEN_FIRE.ogg.import
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://bgvt4kqyvl5gp"
|
||||||
|
path="res://.godot/imported/ENEMY_EDEN_FIRE.ogg-143fd061355f804d5aa4351f6977f048.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_EDEN_FIRE.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_EDEN_FIRE.ogg-143fd061355f804d5aa4351f6977f048.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://c0jveij17p14k"
|
||||||
|
path="res://.godot/imported/ENEMY_EDEN_PILLAR_PROJECTILETRAVEL.ogg-b4f9aee4950e337c782450e73d0a7e64.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_EDEN_PILLAR_PROJECTILETRAVEL.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_EDEN_PILLAR_PROJECTILETRAVEL.ogg-b4f9aee4950e337c782450e73d0a7e64.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_FILTH_ATTACK.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_FILTH_ATTACK.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://dl818xjlcm7vu"
|
||||||
|
path="res://.godot/imported/ENEMY_FILTH_ATTACK.ogg-304b551825cca3c0b3f0de6f9408245d.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_FILTH_ATTACK.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_FILTH_ATTACK.ogg-304b551825cca3c0b3f0de6f9408245d.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_HorseFace_ATK1.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_HorseFace_ATK1.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://d3poou6ultswg"
|
||||||
|
path="res://.godot/imported/ENEMY_HorseFace_ATK1.ogg-f5f32acf24912cb880cfe4eea4ab60d1.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_HorseFace_ATK1.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_HorseFace_ATK1.ogg-f5f32acf24912cb880cfe4eea4ab60d1.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_MICHAEL_ATTACK1.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_MICHAEL_ATTACK1.ogg
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://w6l4yoo1kcmq"
|
||||||
|
path="res://.godot/imported/ENEMY_MICHAEL_ATTACK1.ogg-96c253d5e131cf2c0e510f51dc69e821.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://src/audio/sfx/ENEMY_MICHAEL_ATTACK1.ogg"
|
||||||
|
dest_files=["res://.godot/imported/ENEMY_MICHAEL_ATTACK1.ogg-96c253d5e131cf2c0e510f51dc69e821.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_PILLAR_FIRE.ogg
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/ENEMY_PILLAR_FIRE.ogg
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user